자바스크립트는 프로토타입 기반 언어라고 불린다.
프로토타입은 원형 객체를 말한다.
앞서 객체 지향 프로그래밍에 대해서 배우면서 클래스 등을 배웠지만,
프로토타입에 대해 검색하면서 자바스크립트에는 클래스라는 개념이 없었고 대신 프로토타입이 존재했다는 걸 알게 되었다. (ES6에서 class 문법이 추가되었으나 자바스크립트가 클래스 기반으로 바뀐 것은 아님)
class Human {
constructor(name, age) {
this.name = name;
this.age = age;
}
sleep() {
console.log(`${this.name}은 잠에 들었습니다`);
}
}
let kimcoding = new Human('김코딩', 30);
Human.prototype.constructor === Human; //true: Human 클래스의 프로토타입 객체의 생성자는 Human 함수
Human.prototype === kimcoding.__proto__; //true: Human의 프로토타입 객체는 Human 클래스의 인스턴스 kimcoding의 __proto__과 같다.
Human.prototype.sleep === kimcoding.sleep; //true: Humam클래스의 sleep 매서드는 프로토타입 객체에 있으며, Human 클래스의 인스턴스 kimcoding에서 sleep 매서드를 실행할 수 있다.
자바스크립트에서 상속을 구현할 때 프로토타입 체인을 이용한다.
부모 클래스의 프로토타입, 부모의 부모 클래스 프로토타입을 탐색할 수 있는 proto가 부모 객체의 프로퍼티나 메소드를 검색하는 것을 프로토타입 체인이라고 한다.
자바스크립트 객체는 속성을 저장하는 동적인 "가방"과 (자기만의 속성이라고 부른다) 프로토타입 객체에 대한 링크를 가진다. 객체의 어떤 속성에 접근하려할 때 그 객체 자체 속성 뿐만 아니라 객체의 프로토타입, 그 프로토타입의 프로토타입 등 프로토타입 체인의 종단에 이를 때까지 그 속성을 탐색한다. (출처 : MDN)
//부모 클래스
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!`);
};
}
//자식 클래스
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;
//과목과 성적 속성은 Teacher만의 특징임
this.subject = subject;
this.grade = grade;
}
}
class Teacher extends Person {
constructor(first, last, age, gender, interests, subject, grade) {
super(first, last, age, gender, interests);
//부모 클래스의 생성자 호출
//이 아래는 Teacher만의 속성들
this.subject = subject;
this.grade = grade;
}
}
//자식 클래스에서 인스턴스를 생성하면 부모 클래스 매소드 접근이 가능해진다.
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
자식 클래스에서는 따로 부모 클래스 매서드를 입력하지 않아도 인스턴스 객체를 만들었을 때 사용 가능하다.
위의 예에서 snape 인스턴스에서 greeting()이라는 매서드를 사용가능한 이유는 Teacher 클래스가 Person 클래스의 자식 클래스이기 때문이다. 그러므로 부모 클래스의 매서드인 greeting()을 자식 클래스에서 사용 가능하다.
let div = document.createElement('div');
div.__proto__ //HTMLDivElement
div.__proto__.__proto__ // HTMlElement
div.__proto__.__proto__.__proto__ // Element
div.__proto__.__proto__.__proto__.__proto__ // Node
div.__proto__.__proto__.__proto__.__proto__.__proto__ // EventTarget
div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__ //Object
div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__ //null
let div = document.createElement('div')
document.body.append(div);
div.textContent = "데마시아!!!!"
div.addEventListener("click",() => console.log("럭스 짱"));
위의 예시에서 div가 addEventListener 매서드를 사용할 수 있는 이유는 EventTarget을 상속하고 있기 때문이다.
최상위 클래스 Object => EventTarget => Node => Element => HTMLElement => HTMLDivElement 순으로 상속한다.
function multiply (a, b=1){
return a * b
} // b에 할당된 1가 디폴트 파라미터
console.log(multiply(5, 2));//10
console.log(multiply(5));//5