자바스크립트는 프로토타입 기반 언어이다.
ES6 이전에는 클래스를 사용하기 위해서는 prototype 말고는 방법이 없었지만, ES6부터는 class를 사용하여 클래스를 구현할 수 있다.
- prototype
function Dog(name) {
this.name = name;
}
Dog.prototype.say = function(){
console.log(this.name + ": Bark!!!");
}
var dog = new Dog('Pug');
dog.say(); // Pug: Bark!!!
- class
class Dog {
constructor(name) {
this.name = name;
}
say() {
console.log(this.name + ": Bark!!!");
}
}
const dog = new Dog('Pug');
dog.say(); // Pug: Bark!!!
자바스크립트도 객체지향언어이다. 그런데 자바스크립트에는 클래스라는 개념이 없다. 대신 프로토타입(Prototype)이라는 것이 존재한다.
프로토타입 기반 언어는 객체 원형인 **프로토타입 객체(prototype object)**을 이용하여 새로운 객체를 만들어낸다. 프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속 받을 수도 있고 그 상위 프로토타입 객체도 마찬가지이다. 이를 **프로토타입 체인(prototype chain)**이라 한다. 프로토타입 체인을 통해서 다른 객체에 정의된 메소드와 속성을 한 객체에서 사용할 수 있게 된다.
밑의 예제에서 car 프로토타입이 vehicle 프로토타입을 상속받았다.
car 객체 자체에는 drive()라는 메서드가 없지만, 얘와 연결된 vehicle이라는 객체에 있으므로 사용할 수 있다.
const vehicle = {
drive: function() {
console.log("the car is driving");
}
};
const car = {
make: "honda",
}
Object.setPrototypeOf(car, vehicle); // rprototype chain으로
car.drive(); // vehicle의 메서드를 사용 가능
함수가 정의되면 다른 곳에 함수와 이름이 똑같은 다른 프로토타입 객체가 생성된다. 함수도 객체이므로 그 안에 멤버가 있다.
Javascript가 파싱 단계에 들어가면 함수의 prototype 멤버는 이 같은 이름의 프로토타입 객체를 참조한다. 이 프로토타입 객체의 constructor 멤버는 함수를 참조한다.
function Person(){}
이 프로토타입 객체는 우리가 new 연산자와 함수 Person을 통해 생성된 모든 객체들의 원형이 된다. 생성된 모든 객체가 이 프로토타입 객체를 참조한다.
각각 만들어진 모든 객체 안에는 proto라는 속성이 있어서, 이 속성이 이 객체의 원형이 되는 프로토타입 객체를 참조한다.