본문 바로가기

JavaScript

Detail of prototype in Javascript

반응형

자바스크립트는 객체지향언어이고 상속은 객체지향 프로그래밍의 핵심 개념입니다.
자바스크립트는 프로토타입을 기반으로 상속을 구현하여 불필요한 중복을 제거할 수 있습니다.
즉 class기반 언어의 상속을 흉내 낼 수 있는 것입니다. 

(ES6에서 class 문법이 추가되었습니다만 자바스크립트가 클래스 기반 언어로 바뀐 것은 아닙니다.)

function Person(name, age){
	this.name = name;
    this.age = age;
    this.speak = function(){
		return `Hi, ${name} I'm ${age} years old`
	};
}

const person1 = new Person('justin', 12);
const person2 = new Person('dave', 14);

위의 생성자 함수에는 같은 메서드가 두개의 객체에 중복되어 있다는 문제가 있고 이를 해결할 수 있는 것이 prototype입니다. 

개선해봅시다. 

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

Person.prototype.speak = function(){
	return `Hi, ${this.name} I'm ${this.age} years old`
};

const person1 = new Person('justin', 12);
const person2 = new Person('dave', 14);

(리터럴로 객체를 정의한 경우 Object.setPrototypeof()를 통해 프로토타입을 지정할 수 있습니다.
https://bedeveloper.tistory.com/90 이곳에서 확인 가능하십니다.) 

같은 결과를 도출 해낼 수 있지만 개선된 모습입니다. 

 

어떻게 같은 결과를 도출할 수 있을까요? person1과 person2에는 speak라는 메서드가 정의되어있지 않았습니다만
생성자 함수가 정의될 때 함께 생겨나는 Person.prototype 객체로부터 상속을 받기 때문입니다.
(함수가 정의될 때 함수는 constructor 즉 객체를 생성할 수 있는 자격을 취득하며
동시에 prototype 객체(또는 [[Prototype]] 내부 슬롯)또한 생성된다.)
 

 

어떻게 Person.prototype 객체에서 상속을 받을 수 있는 걸까요? person1, person2에 즉 모든 객체에는 __proto__ 프로퍼티가 있고 이 프로퍼티를 통해서 생성된 객체의 청사진을 정의한 생성자함수의 프로토타입 객체에 간접적으로 접근이 가능한 것입니다. 

위 사진을 보면 알겠지만 __proto__ 접근자 프로퍼티를 통해 간접적으로 프로토타입 객체에 접근할 수 있으며 constructor는 생성자 함수 자체를 가리키고 있는 것을 알 수 있고 프로토타입 객체도 객체이기에 프로토타입 객체를 가지고 있는 것을 알 수 있습니다. 

위 사진을 보면 알 수 있듯이 Person 생성자 함수의 프로토타입 객체도 객체이기에 __proto__ 속성으로 Person.prototype 객체의 생성자 함수 Object의 프로토타입 객체로 접근하는 것을 알 수 있습니다. 자바스크립트는 해당 인스턴스에서 프로퍼티, 메서드에 접근할때 해당 객체에서 찾아지지 않는다면 __proto__ 접근자 프로퍼티로 상위 프로토타입 객체로 접근하여 찾아내고 최상단인 Object.prototype 객체에 까지 올라가게 됩니다. 이것이 프로토타입 체인이고 최상단까지 갔음에도 찾지 못 할 경우 undefined를 반환합니다. 

 

출처 : https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67

위 사진은 프로토타입 체인을 이해하기에 좋은 사진이라서 다른 블로그에서 가져왔습니다.

반응형