Javascript/core

prototype, __proto__에 관하여

student513 2020. 12. 20. 21:06

정재남 강사님 강의 중 캡쳐

프로토타입 개념에 관한 도식이다. 

Constructor 생성자함수로 instance를 생성한 경우

Constructor의 프로퍼티인 prototype가 instance의 __proto__라는 프로퍼티에 전달이 된다.

 

그럼 prototype은 무엇일까?

console.dir로 Array 생성자를 출력해보았다.

많은 메소드들 중 prototype이 보인다.

배열에서 사용할 수 있는 메소드들이 보인다.

Array 생성자로 생성한 인스턴스인 배열은 __proto__에 prototype의 메소드들을 포함하게 되는 것이다!

arr라는 배열을 생성하여 콘솔에 출력해보니 Array의 prototype과 똑같은 __proto__라는 객체가 출력이 되는 것을 알 수 있다.

arr라는 instance는 Array 생성자로부터 메소드를 상속받게 된 것이다.

 

Array: prototype ==> arr: __proto__

 

이를 이용하면 우리가 흔히 알고 있는 상속의 개념을 이용하여 코드의 중복을 막을 수 있게 된다.

아래의 코드를 확인해보자.

function Person(n, a){
    this.name = n;
    this.age = a;
}

var gomu = new Person('고무곰', 30);
var iu = new Person('아이유', 25);

gomu.setOlder = function() {
    this.age += 1;
}
gomu.getAge = function() {
    return this.age;
}
iu.setOlder = function() {
    this.age += 1;
}
iu.getAge = function() {
    return this.age;
}

gomu, iu라는 인스턴스에 둘 다 setOlder, getAge라는 메소드가 존재한다. 

각 메소드는 동일한 생성자에서 동일한 기능을 하기에 하나로 관리하고 싶다.

이럴 때 gomu와 iu의 공통조상인 Person에 setOlder, getAge를 추가하면

Person으로부터 생성된 모든 instance에 메소드를 상속해줄 수 있다.

function Person(n, a){
    this.name = n;
    this.age = a;
}

Person.prototype.setOlder = function() {
    this.age += 1;
}
Person.prototype.getAge = function() {
    return this.age;
}

var gomu = new Person('고무곰', 30);
var iu = new Person('아이유', 25);

Person의 prototype에 메소드를 추가해주면

gomu, iu의 __proto__에도 추가된 메소드가 똑같이 상속된다.

 

그런데 메소드를 참조할 경우 다음과 같이 작성해야한다.

gomu.getAge() // O
gomu.__proto__.getAge() // X

보통 메소드를 참조할 때도 __proto__는 적지 않는다.

__proto__까지 적을 경우,  this는 gomu.__proto__까지 바인딩하게 되므로 NaN값이 나온다.

__proto__은 생략할 수 있다.

 

그러나 만약 Person.prototype.age=100이 선언되어있었다면, 

gomu.__proto__.getAge는 100의 값을 갖게 된다.

 

메소드 호출시 this의 바인딩의 범위가 어디까지인지를 생각하면 이해할 수 있을 것이다.

 

 

출처: Javascript 핵심 개념 알아보기 - JS Flow, 정재남 강사님, 코어자바스크립트