본문 바로가기

JavaScript

[JavaScript] 프로토타입 체인

자바스크립트는 프로토타입 기반 객체 지향 언어이다. 자바스크립트의 모든 객체는 자신의 부모 역할을 하는 객체와 연결이 되어 있는데, 이러한 부모 객체를 프로토타입 객체(이하 프로토타입)라고 부른다. 

 

const student = {
  name: 'Lee',
  score: 90
};

// student에는 hasOwnProperty 메소드가 없지만 아래 구문은 동작한다.
console.log(student.hasOwnProperty('name')); // true

console.dir(student);

/** 
_proto__:
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()
*/

 

위 주석에 보이는 __proto__가 student 객체의 프로토타입이다.

 

자바스크립트의 모든 객체는 [[prototype]]이라는 객체(혹은 null)를 가진다. 이를 이용하여 상속을 구현하고 get 액세스를 사용하여 상속되며 자식의 프로퍼티 객체처럼 사용할 수 있다.

 

 

 

그렇다면 프로토타입 체인은 무엇일까?

 

 

자바스크립트는 특정 객체의 프로퍼티 혹은 메서드에 접근할 때, 그 특정 객체에 해당하는 프로퍼티나 메서드가 없다면, [[prototype]]이 가리키는 객체를 따라가며 자신의 부모 역할을 프로토타입 객체의 해당하는 프로퍼티나 메서드를 찾는데 이를 프로토타입 체인이라고 한다.

 

 

function Person(name) {
	this.name = name;
};

Person.prototype.sayHello = function () {
	console.log(`Hi! My name is ${this.name}`);
};

const me = new Person('Jang');

console.log(me.hasOwnProperty('name')); // true

Object.getPrototypeOf(me) === Person.prototype; // true

 

Person 생성자 함수에 의해서 me라는 객체가 생성되었는데 이아이는 Object.prototype에 있는 메서드인 hasOwnProperty를 호출할 수 있다. 이처럼 부모 역할을 하는 프로토타입 객체를 찾아 해당 프로퍼티 혹은 메서드를 불러올 수 있는 것이다.

 

다른 예시를 살펴보자.

 

 

function Person(name, gender) {
  this.name = name;
  this.gender = gender;
  this.sayHello = function(){
    console.log('Hi! my name is ' + this.name);
  };
}

const foo = new Person('Lee', 'male');

console.dir(Person);
console.dir(foo);

console.log(foo.__proto__ === Person.prototype);                // ① true
console.log(Person.prototype.__proto__ === Object.prototype);   // ② true
console.log(Person.prototype.constructor === Person);           // ③ true
console.log(Person.__proto__ === Function.prototype);           // ④ true
console.log(Function.prototype.__proto__ === Object.prototype); // ⑤ true

 

 

https://poiemaweb.com/js-prototype

 

여기서 Object.prototype은 프로토타입 체인의 최상단에 위치한다. 제일 위 조상을 뜻하며 이를 프로토타입 체인의 종점이라고 부른다.

 

 

생성자 함수를 이용했을 경우

 

 

함수를 정의하는 방법에는 함수표현식, 함수선언식, Function() 생성자 함수가 있다. 함수 선언식, 함수 표현식 모두 함수 리터럴 방식을 이용하기 때문에 결론적으로 Function() 생성자 함수를 이용하여 함수 객체를 선언한다. 따라서 함수 객체는 무슨 방식을 사용하던 그 prototype 객체는 Function.prototype 이다.