[JS] prototype

CheolHyeon Park·2022년 12월 2일
0

JavaScript

목록 보기
18/23

자바스크립트는 흔히 프로토타입 기반 언어라 불린다. 모든 객체들이 메소드와 프로퍼티를 상속 받기 위해서 프로토타입 객체를 가진다는 의미다. prototype객체도 prototype을 갖고 상위의 프로토타입 객체도 마찬가지다. 이를 프로토타입 체인이라고 한다. 이에 대해 알아보고자 한다.

프로토타입 구조

생성자 함수를 new 키워드를 통해 생성하면 인스턴스가 생성된다. 인스턴스는 [[prototype]] 내부 속성을 갖는데 이는 생성자 함수의 prototype 프로퍼티를 참조하고 있다. (복사 아니고 참조다)

프로토타입은 위와 같은 형식으로 생성자를 생성한다. 이 과정이 Java에서는 class로 인스턴스를 생성하는 것과 같은 기능을 하는 것이다.

💡 __proto__
__proto__ 는 legacy로 남아있다. 대신에 Object.getPrototypeOf(obj)를 통해 접근해야 한다.

코드

function Person(first, last, age, gender, interests) {

    // 속성과 메소드 정의
    this.first = first;
    this.last = last;
  //...
}
Person.prototype.getName = function() {
    return this.first;
}
var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);

console.dir(person1)
console.dir(Person)
console.log(Object.getPrototypeOf(person1) === Person.prototype);  // true
console.log(person1.getName()) // Bob

  • Person 생성자 함수의 prototype 프로퍼티와 인스턴스 person1[[prototype]] 같은 객체를 가르키고 있다. 아래 이미지는 위 코드의 콘솔이다. 빨간색으로 표시된 부분이 같은 객체이다.
  • Person.prototype.getName 의 정의가 person1 인스턴스의 [[Prototype]] 에 존재하여 인스턴스가 직접 접근 가능하다.

이처럼 생성자의 prototype 은 상속시킬 프로퍼티나 메소드를 보관하는 장소가 된다.

Constructor

위 이미지를 보면 prototype에 constructor 를 가지고 있다. 이는 생성자 함수 자기 자신을 가르키고 있다. 직접 constructor 를 이용해 접근도 가능하다. 이 프로퍼티는 자신의 원형을 알기 위한 속성이다.

person1.constructor
person2.constructor

또한, 다음과 같이 constructor 프로퍼티를 통해 새로운 인스턴스를 생성하는 것도 가능하다.

var person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);
console.log(person3.first, person3.last);

객체의 생성자를 확인하기 위해 constructor.name을 사용하지 말자 constructor.name은 변경 가능하기 때문이다. instanceof 를 사용하자

프로토타입 체인

프로토타입 체인은 상속을 구현할 수 있는 방식이다. 이에 더해, 내적 동질성을 구현하기 위한 장치로도 사용된다.

위 코드에서 Person의 [[Prototype]]안에 또 다시 [[Prototype]] 가 있다. 해당 객체는 [[Prototype]]에 존재하는 프로퍼티나 메소드에 접근 가능하다. 아래 코드를 보면,

person1.valueof();  // OK

해당 코드는 정상적으로 작동하고 출력 된다. 그 과정은 이렇다.

  1. 자신의 메소드에 valueof메소드가 있는지 확인한다.
  2. 없으면 [[Prototype]]를 따라 올라가 valueof 가 있는지 확인한다.
  3. 없으면 [[Prototype]] 안에 [[Prototype]]을 타고 올라가 valueof 가 있는지 확인한다.
  4. Object의 prototype에 존재하는 valueof 메소드를 실행한다.
person1.valueof = function() {
	console.log('hi');
}
person1.valueof();  // hi

만약 위 코드처럼 person1에 직접 valueof메소드를 구현한다면 우선적으로 hi가 출력 된다.

정리하자면 프로토타입 체인은 자신의 메소드가 있다면 먼저 사용하게 되고(내적 동질성), 없다면 prototype을 타고 올라가서 찾기 때문에 상속을 가능하게 한다.

profile
나무아래에 앉아, 코딩하는 개발자가 되고 싶은 박철현 블로그입니다.

0개의 댓글