ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JavaScript] 프로토타입 체이닝 1 : constructor, prototype, __proto__
    카테고리 없음 2020. 2. 14. 16:50

    * constructor, prototype

     

    자바스크립트의 모든 객체는 자신의 부모 객체와 연결되어 있다. 이 때, 부모 역할을 하는 객체를 프로토타입 혹은 프로토타입 객체라고 부른다. 객체의 부모, 즉 객체의 프로토타입은 객체가 생성될 때 결정된다.

     

    객체는 생성자함수에 의해 만들어진다. 어떤 함수가 생성되면 프로토타입 객체가 함께 생성된다. 생성된 함수의 prototype 프로퍼티는 함께 생성된 프로토타입 객체를 가리키며, 생성된 객체의 constructor 프로퍼티는 생성자 함수를 가리킨다. 이를 그림으로 보면 아래와 같다. 

     

     

    프로토타입 객체에는 기본적으로 constructor 프로퍼티가 들어있다. 프로토타입도 객체이므로, 아래외 같이 프로퍼티를 추가해서 사용하는 것이 가능하다.

    // Constructor function
    function Car(brand) {
    	this.brand = brand;
    };
    
    // Prototype Object : Car.prototype  
    
    // adding an property into Prototype Object
    Car.prototype.drive = function(){ console.log('I'm driving')};

     

     

    * __proto__, 프로토타입 체이닝

    모든 객체에는 자신의 프로토타입(부모)을 가리키는 프로퍼티인 __proto__를 가지고 있다.

    (* 크롬에서는 __proto__로 구현되어 있으나, ECMAScript 명세서에서는 이를 [[Prototype]] 이라 명시했다)

     

    객체가 부모 객체와 연결되어서 좋은 점은 무엇일까? 부모가 가지고 있는 메소드를 자유자재로 사용할 수 있다는 점이다. 마치 나에게 자동차가 없어도, 부모님의 자동차를 빌려 사용할 수 있는 것과 같다. 아래 코드를 보자.

     

     

     

    obj라는 객체가 있고, 그 안에는 hey: 33라는 프로퍼티가 한 개 있다. 프로퍼티의 밸류는 숫자 33이다. 그런데, 콘솔을 통해 obj.hey.toString() 을 찍어보면 toString() 메소드를 실행한 결과로 문자 33이 나온다. 

     

    obj 라는 객체에는 toString() 메소드가 정의되지 않았다. 그런데 어떻게 이를 사용할 수 있는 것일까?

     

     

    콘솔을 통해 보면 obj 안에는 __proto__ 프로퍼티가 있다. 앞서 언급했듯, __proto__ 프로퍼티는 자신의 부모 객체(프로토타입)를 가리키고 있다.  이 링크를 통해서 obj객체는 자신의 부모인 Object.prototype 객체로부터 toString() 메소드를 검색 후 사용한다. 

    이 때문에, 자신이 toString() 메소드를 가지고 있지 않아도, 프로토타입과 연결된 __proto__ 프로퍼티를 이용해 해당 메소드를 사용하는 것이다. 이렇게 __proto__ 프로퍼티를 통해 프로토타입 객체에 접근해 프로토타입의 프로퍼티를 검색해 사용하는 것을 프로토타입 체이닝이라고 한다. 

     

    생성자함수와 그 인스턴스의 관계는 마치 부모와 자식의 관계와 비슷하다. 하지만 엄밀히 말하자면 생성자함수는 인스턴스를 통해 만들어져 있지만, 인스턴스가 생성자함수와 직접 이어져있는 것은 아니다. 인스턴스와 이어져있는 것은 생성자함수의 프로토타입 프로퍼티가 가리키는 프로토타입 객체다.

     

    그림으로 보면 아래와 같다. 위 경우에서 생성자함수는 Object() 가 되고, 프로토타입은 Object.prototype 객체가 된다. 새로 생성된 인스턴스는 __proto__를 통해 프로토타입 객체(생성자함수.prototype)와 이어져 있다고 볼 수 있다. 

     

     

    *  reference : <인사이드 자바스크립트>

     

     

    댓글