Prototype Chain이란?
JavaScript는 흔히 프로토타입 기반 언어(prototype-based language)라 불립니다.— 모든 객체들이 메소드와 속성들을 상속 받기 위한 템플릿으로써 프로토타입 객체(prototype object)를 가진다는 의미입니다.
프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속 받을 수도 있고 그 상위 프로토타입 객체도 마찬가지입니다. 이를 프로토타입 체인(prototype chain)이라 부르며 다른 객체에 정의된 메소드와 속성을 한 객체에서 사용할 수 있도록 하는 근간입니다.
Keyword 1. proto, constructor, prototype 이 각각 어떤 관계인가?
JavaScript에서는 객체 인스턴스와 프로토타입 간에 연결(많은 브라우저들이 생성자의 prototype 속성에서 파생된 proto 속성으로 객체 인스턴스에 구현하고 있습니다.)이 구성되며 이 연결을 따라 프로토타입 체인을 타고 올라가며 속성과 메소드를 탐색합니다.
constructor
생성자 함수 Person이 생길때 Person의 프로토타입도 동시에 생긴다.
이때 둘을 연결시켜줘야 서로 참조가 가능한데 이때 생성자함수내에는 prototype이라는 속성안에 프로토타입객체를 넣어둔다.
반대로 프로토타입객체 내부에는 constructor라는 속성안에 생성자 함수를 넣어 상호참조한다.
prototype
자바나 C++과같은 클래스 기반 객체지향 프로그래밍 언어와 다르게 자바스크립트는 프로토타입 기반 객체지향 프로그래밍 언어이다. 클래스가 없다보니 기본적인 상속기능도 없다. 그래서 프로토타입 기반으로 상속을 흉내내도록 구현해서 사용한다.
최근의 ES6에서는 class문법이 추가되었지만 프로토타입 기반의 클래스 구현이라 볼 수 있다.
Person 생성자 함수에서 나온 객체들이 공통된 속성을 공유하는 부모객체. 이걸 Prototype객체. 줄여서 프로토타입 이라고 한다.
자바스크립트에서 객체를 만드는 방법중 하나로 함수에 new를 붙여 만드는방법이 있다.
(자바스크립트에서는 함수가 객체라고한다.)
일반함수와 생성자 함수를 구분하기 위해 함수명 첫글자를 대/소문자로 표기한다.
__proto__
생성자함수 Person이 instance들을 만들어내면 새로 만들어진 instance들은 생성자함수과 같은 구조를 가지게 된다. 그런데 생성자함수의 prototype속성 대신 __proto__ 라는 속성이 생기게 된다. 의미로는 '나의 생성자의 프로토타입'이라고 보면 된다.
Keyword 2. ES6 class 키워드 및 super 키워드 이용 방법.
ES6 사용 예시
class SmartPhone {
constructor(name, color, weight) {
this.name = name;
this.color = color;
this.weight = weight;
}
calling() {
console.log(this.name + "통화중");
}
}
class Iphone extends SmartPhone {
constructor(name, color, weight, price) {
//만약 추가로 매개변수를 받고 싶다면 (price) constructor에 추가, this.price =price 추가.
super(name, color, weight);
this.corporation = "Apple";
this.price = price;
}
text() {
console.log(this.name + "문자중");
}
}
let iphone7 = new Iphone("iphone7", "white", "0.5", "30000");
iphone7.text();
//"iphone7문자중" 이라고 출력된다.
iphone7.calling();
// "iphone7통화중" 이라고 출력된다. --------> SmartPhone class 에서 상속받아서 메소드 사용되어짐.
ES5 Prototype 사용 예시
let SmartPhone = function (name, color, weight) {
this.name = name;
this.color = color;
this.weight = weight;
};
SmartPhone.prototype.calling = function () {
console.log("통화중");
};
let Iphone = function (name, color, weight) {
//상속받는 쪽에서 this 설정을 해줘야한다. 안해주면 this가 undefined가 나와서 데이터를 못 가져온다.
SmartPhone.call(this, name, color, weight); //.apply(this, arguments)도 사용 가능.
};
//SmartPhone class의 상속을 받기를 원한다면 아래처럼 Object.create를 해주고,
//constructor도 제대로 Iphone을 가리킬 수 있게 할당해주어야 한다.
//할당은 안해주면 constructor가 SmartPhone을 가리키게 된다.
Iphone.prototype = Object.create(SmartPhone.prototype); // extends
Iphone.prototype.constructor = Iphone;
Iphone.prototype.text = function () {
console.log("문자 보내는 중");
};
let iphoneX = new Iphone("iphoneX", "black", "0.3kg");
iphoneX.calling();
//"통화중" 이라고 출력된다.
console.log(iphoneX.name);
//"iphoneX" 라고 출력된다.
*참고 사이트 : https://www.nextree.co.kr/p7323/