지난 글에서 썼던 프로토타입 체인을 조금 더 자세히 알아보자!
상속을 JavaScript에서 구현할 때는 프로토타입 체인을 사용한다!
상속한다 = 객체와 객체를 연결 해 멤버 함수나 멤버 변수를 공유한다
일단 염두에 둘 것은, 모든 객체의 최상위 타입은 ⭐️Object⭐️라는 것이다.
체인을 타고 올라 올라가다보면 결국은 Object를 맞닥뜨리게 된다.
JavaScript는 프로토타입 기반 언어이며, DOM도 프로토타입으로 상속을 구현
document.creatElement('div')
를 이용하면 새로운 div 엘리먼트를 만들수 있다.
이때 이 div 엘리먼트는 HTMLDivElement라는 클래스의 인스턴스이다.
아래 실습 문제를 풀어보면 해당 엘리먼트의 프로토타입 체인을 확인 할 수 있다.
let div = document.createElement('div');
div.__proto__
div.__proto__.__proto__
div.__proto__.__proto__.__proto__
div.__proto__.__proto__.__proto__.__proto__
div.__proto__.__proto__.__proto__.__proto__.__proto__
div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__
div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__
콘솔창으로 확인해보자!
div가 addEventListener 메서드를 사용할 수 있는 이유는 EventTarget
을 상속하고 있기 때문
보통 클래스의 인스턴스는 new 키워드
로 생성하지만, DOM에서는 new 키워드가 아닌 createElement
를 사용
먼저 Person이라는 class를 만들어주자.
class Person {
constructor(first, last, age, gender, interests) {
this.name = {
first,
last
};
this.age = age;
this.gender = gender;
this.interests = interests;
}
greeting() {
console.log(`Hi! I'm ${this.name.first}`);
};
farewell() {
console.log(`${this.name.first} has left the building. Bye for now!`);
};
}
📌 하위 클래스 생성 --> extends
키워드로 상속받을 클래스를 명시
extends를 사용해서 Person의 멤버를 Teacher에게 상속한다.
class Teacher extends Person {
constructor(first, last, age, gender, interests, subject, grade) {
this.name = {
first,
last
};
this.age = age;
this.gender = gender;
this.interests = interests;
// subject and grade are specific to Teacher
this.subject = subject;
this.grade = grade;
}
}
📌 상위 클래스 생성자 호출 --> super()
연산자의 매개변수를 통해 멤버 상속
❗️ 파생 클래스에서 super() 함수가 먼저 호출되어야 this
키워드를 사용할 수 있다. 그렇지 않을 경우 참조오류가 발생!
❗️ 생성자 함수 내의 super 키워드는 한번만 사용 가능
class Teacher extends Person {
constructor(first, last, age, gender, interests, subject, grade) {
super(first, last, age, gender, interests);
// subject and grade are specific to Teacher
this.subject = subject;
this.grade = grade;
}
}
📌 Teacher의 인스턴스를 생성하면 Teacher와 Person 양쪽의 메서드를 사용할 수 있다
let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5);
snape.greeting(); // Hi! I'm Severus.
snape.farewell(); // Severus has left the building. Bye for now.
snape.age // 58
snape.subject; // Dark arts
📌 생성한 클래스의 인스턴스의 속성 값을 변경하거나 최종 값을 예측할 수 없는 경우
--> 이런 상황에 getter / setter
가 필요!
class Teacher extends Person {
constructor(first, last, age, gender, interests, subject, grade) {
super(first, last, age, gender, interests);
// subject and grade are specific to Teacher
this._subject = subject;
this.grade = grade;
}
get subject() {
return this._subject;
}
set subject(newSubject) {
this._subject = newSubject;
}
}
subject 속성에 대해 getter와 setter가 생겼다.
멤버 변수에는 _를 붙여 getter/setter와 구분
(이렇게 하지 않으면 get/set을 호출할때마다 에러가 발생한다)
snape 객체의 _subject
속성 값을 보려면 snape._subject
를 실행
_subject
에 새 값을 할당하려면 snape._subject="new value"
를 실행
[참고]