자바스크립트는 프로토타입 기반 언어이며, 객체 지향 프로그래밍의 특성 중 상속을 구현할 때 프로토타입 체인을 이용한다.
ES2015 전까지 자바스크립트는 클래스를 사용하지 않았다. 대신, 프로토타입 체인을 써왔고 지금도 여전히 쓰고있다고 할 수 있다. ES6의 클래스는 내부를 열어보면 사실 프로토타입 체인이 모든 일을 하고 있는데 이것을 숨기고 있는 문법 설탕의 일종이라는 걸 알 수 있다.
(문법설탕(syntactic sugar): 프로그래밍 언어 내에서 쉽게 읽고 표현하기 위해 설계된 구문)
따라서 javascript 객체 지향 체계를 사용하면서 효율적인 코드를 작성하기 위해서는 프로토타입 체인에 대해 아는 것이 매우 중요하다.
클래스로 인스턴스를 생성하면, 클래스안에 내장된 속성과 메소드가 인스턴스에게 상속된다.
class Human {
constructor(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
farewell() {
console.log{`${this.name} has left the building. Bye for now!`};
}
}
let zoe = new Human('Zoe', 100, 'female')
zoe.name; // 'Zoe' (클래스 객체의 속성 이용)
zoe.age; // 100
zoe.farewell(); // 'Zoe has left the building. Bye for now!' (클래스 객체의 메소드 이용)
위에서 Human 클래스의 프로토타입이 인스턴스인 zoe에게 상속되므로,
zoe 객체에서 클래스의 속성과 메소드를 모두 이용할 수 있게된다.
prototype은 클래스에서 생성자 함수에 의해 만들어 진다.
인스턴스에서는 .prototype으로 무언가를 조회할 수 없다.
.prototype을 이용한 조회는 class에서만 가능하다.
인스턴스에서는 .__proto__ 링크를 이용해 prototype을 조회할 수 있다.
.prototype은 객체 안에 들어 있는 prototype을 찾아가는 것이고,
.__proto__는 주소값으로 프로토타입을 찾아가 힐끗 안을 들여다보는 것이다.
.prototype은 내 집으로 비밀번호 치고 들어가서 집 안에 있는 prototype을 보는 것이고,
.__proto__는 prototype씨가 사는 주소를 찾아가서 prototype씨를 확인하는 것이다.
.__proto__``````.__proto__ ~
위 프로토타입 체인에 올라타면 상속받은 모든 속성을 확인할 수 있다.
정리하자면, 자바스크립트에서의 상속은 prototype 덕분에 가능하며, 인스턴스는 prototype chain을 통해 최상위 클래스의 프로토타입부터 그 하위 클래스들로부터 쭉 상속받은 모든 속성을 이용할 수 있게 된다.
javascript에서는
1. super와
2. extends 키워드
를 이용하여 상속을 구현한다.
class Human {
constructor(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
farewell() {
console.log{`${this.name} has left the building. Bye for now!`};
}
}
예를 들어, Human이라는 클래스가 있고, professor라는 클래스를 생성하고자 할때, professor는 사람이기에 Human의 특성을 가지고 있고(예를 들어 이름,성별,나이가 있음) 거기에 추가적으로 다른 특성들(가르치는 과목 등)을 가질 것이다.
Professor 클래스로 만든 인스턴스들에서 Human과 Professor의 속성과 메소드를 모두 사용할 있도록 하려면,
Professor 클래스 선언시 extends Human을 추가하고, constructor 함수안에 super([매개변수])를 이용하여 부모 클래스의 속성들을 가져오면 된다.
class Human {
constructor(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
farewell() {
console.log{`${this.name} has left the building. Bye for now!`};
}
}
// Human의 하위 클래스 Professor 생성
class Professor extends Human {
constructor(name, age, gender, subject) {
super(name, age, gender);
this.subject = subject;
}
}
// Professor로부터 인스턴스 생성
let severus = new Professor('Severus', 58, 'male', 'Dark')
severus.name; // 'Severus' (Human 클래스의 속성)
severus.subject; // 'Dark' (Professor 클래스의 속성)
severus.farewell(); // 'Severus has left the building. Bye for now!' (Professor 클래스의 메소드)
브라우저에서 DOM을 이용하면, document.createElement('div')로 새로운 div 엘리먼트를 생성할 수 있다.
생성된 div 엘리먼트는 HTMLDivElement라는 클래스의 인스턴스이다.
인스턴스의 .__proto__를 이용하면 부모 클래스의 프로토타입, 또는 부모의 부모 클래스의 프로토타입을 확인할 수 있다.
참고자료:
DEV / Codesmith Staffing / Explaining JavaScript’s Prototype Chain Like You're Five/ https://dev.to/codesmith_staff/explain-javascripts-prototype-chain-like-im-five-51p