TIL 78 | 프로토타입

모던자바스크립트 Deep Dive "19장 프로토타입"을 요약해보자. 프로토타입이란 무엇인가?

객체지향 프로그래밍이란❓

자바스크립트는 명령형, 함수형, 프로토타입 기반의 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어이다.

프로토타입 기반의 객체지향 프로그래밍 이 무엇일까?

  • 프로토타입 : 프로토타입 객체의 줄임말. 프로토타입은 어떤 객체의 상위(부모) 객체의 역할을 하는 객체. 다른 객체에 공유 프로퍼티(메서드 포함)를 제공한다. 프로토타입을 상속받은 하위(자식) 객체는 상위 객체의 프로퍼티를 자신의 프로퍼티처럼 자유롭게 사용할 수 있다. 즉, 객체간 상속을 구현하기 위해 사용된다.

    • 객체 : 속성을 통해 여러 개의 값을 하나의 단위로 구성한 복합적인 자료구조를 객체라고 한다.
      • 객체의 구성 : 객체는 상태 데이터(property)와 동작을 하나의 논리적인 단위로 묶은(method) 복합적인 자료구조
      • 객체의 특성 : 각 객체는 고유의 기능을 갖는 독립적인 부품. 자신의 고유한 기능을 수행하면서 다른 객체와 관계성을 가질 수 있다(메세지를 주고받기, 데이터 처리, 상속)
  • 객체지향 프로그래밍 : 프로그램을 여러 개의 독립적인 단위, 즉 객체의 집합으로 표현하는 프로그래밍 패러다임이다.

    • 상속 : 객체지향 프로그래밍의 핵심 개념. 어떤 객체의 프로퍼티 또는 메서드를 다른 객체가 상속받아 그대로 사용하는 것이 상속. JS는 프로토타입을 기반으로 상속을 구현하여, 코드의 불필요한 중복을 제거한다.

      • 상속에 의한 메서드 공유

      • 상속에 의한 메서드 공유 코드

  function Circle(radius) {
    this.radius = radius;
  }

Circle.prototype.getDiameter = function () {
  return Math.PI * this.radius ** 2;
};

const circle1 = new Circle(1);
const circle2 = new Circle(2);

console.log(circle1.getDiameter === circle2.getDiameter); // true;

console.log(circle1.getDiameter()); // 3.141592653589793
console.log(circle2.getDiameter()); // 12.566370614359172

프로토타입 객체에 대하여❗

  • 모든 객체는 [[Prototype]]이라는 내부 슬롯을 가진다. 모든 객체는 하나의 프로토타입을 갖는다.
  • [[Prototype]]에 저장되는 프로토타입은 객체 생성 방식에 의해 결정된다. 즉, 객체가 생성될 때 객체 생성 방식에 따라 프로토타입이 결정되고 [[Prototype]]에 저장된다.
    • 객체 리터럴에 의해 생성된 객체의 프로토타입 : Object.prototype
    • 생성자 함수에 의해 생성된 객체의 프로토타입 : 생성자 함수의 prototype 프로퍼티에 바인딩되어 있는 객체
  • 모든 프로토타입은 생성자 함수와 연결되어있다.

    [[Prototype]] 내부 슬롯에는 직접 접근할 수 없지만, 위 그림처럼 __prototype__접근자 프로퍼티를 통해 자신의 프로토타입에 간접적으로 접근할 수 있다. 그리고 프로토타입은 자신의 constructor 프로퍼티를 통해 생성자 함수에 접근할 수 있고, 생성자 함수는 자신의 prototype 프로퍼티를 통해 프로토타입에 접근할 수 있다.

__proto__접근자 프로퍼티

  • 모든 객체는 __proto__ 접근자 프로퍼티를 통해 자신의 프로토타입, 즉 [[Prototype]] 내부 슬롯에 간접적으로 접근할 수 있다
  • student 객체를 생성한 뒤, 콘솔에서 출력해보자
    • 아래의 그림에서 __prototype__ 아래의 항목들이 student 객체의 프로토타입인 Object.prototype이다.
    • __prototype__ 접근자 프로퍼티를 통해 student 객체의 [[Prototype]] 내부 슬롯이 가리키는 객체인 Object.prototype에 접근한 결과를 콘솔에 출력한 것.
  • 모든 객체는 __prototype__ 접근자 프로퍼티를 통해서 프로토타입을 가리키는 [[Prototype]] 내부 슬롯에 접근할 수 있다

  • 접근자 프로퍼티 : 자체적으로 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 사용하는 접근자 함수(getter/setter)로 구성된 프로퍼티
  • __prototype__ 접근자 프로퍼티는 객체가 직접 소유하는 프로퍼티가 아니라 Object.prototype의 프로퍼티다. 모든 객체는 상속을 통해 Object.prototype.__proto__접근자 프로퍼티를 사용할 수 있다

Object.prototype
모든 객체는 프로토타입의 계층 구조인 프로토타입 체인에 묶여있다. JS 엔진은 객체의 프로퍼티(메서드 포함)에 접근하려고 할 때, 해당 객체에 접근하려는 프로퍼티가 없다면 __prototype__ 접근자 프로퍼티가 가리키는 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색한다. 프로토타입 체인의 종점, 즉 프로토타입 체인의 최상위 객체는 Object.prototype이며, 이 객체의 프로퍼티와 메서드는 모든 객체에 상속된다.

함수 객체의 prototype 프로퍼티

함수 객체가 소유하는 prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킨다

// 함수 객체는 prototype 프로퍼티를 소유한다
(function () {}).hasOwnProperty('prototype'); // true

// 일반 객체는 prototype 프로퍼티를 소유하지 않는다
({}).hasOwnProperty('prototype'); // false

좋은 웹페이지 즐겨찾기