자바스크립트의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결되어 있다. 이러한 부모 객체를 프로토타입 객체 또는 프로토타입이라고 한다.
프로토타입은 객체의 원형이라는 뜻으로, 객체는 부모가 가지는 유전자 즉, 프로토타입 객체로부터 프로퍼티 또는 메소드를 상속 받는다.
다시 말해, 객체는 다른 객체로부터 직접 상속을 받는데, 이때 상속되는 객체가 프로토타입이다.
const carPrototype = {
color: function () {
console.log('black color');
},
};
function Car() {}
Car.prototype = carPrototype;
const miniCar = new Car();
miniCar.color(); // 출력: black color
코드 설명
carPrototype
은 프로토타입의 객체로,Car
생성자 함수의 prototype에 할당되어 있다.
miniCar
라는 인스턴스는Car
생성자 함수로 생성되었는데, 이로 인해miniCar
는carPrototype
에 있는color
메소드를 상속받아 사용할 수 있다.
함수 객체에서는 prototype이라는 특수한 프로퍼티가 존재한다. ( 객체 !== 프로퍼티 )
이 프로퍼티에는 해당 함수로 생성된 인스턴스들이 공통적으로 가지는 속성이나 메소드가 포함되어 있다.
function Car(make, model) {
this.make = make;
this.model = model;
}
Car.prototype.drive = function () {
console.log('Driving a', this.make, this.model);
};
const myCar = new Car('Hyundai', 'Grandeur');
myCar.drive(); // 출력: Driving a Hyundai Grandeur
코드 설명
Car
생성자 함수의 prototype 프로퍼티에drive
메소드를 추가했다.
- 이 메소드는
Car
생성자 함수로 생성된 모든 인스턴스에서 공통으로 사용할 수 있다.
상속이 .prototype 프로퍼티를 통해서 가능하다면, 인스턴스는 자신의 프로토타입을 .__proto__를 통해서 가능하다.
.prototype 프로퍼티는 내가 원형일 때 존재하며, 함수 객체만 가지고 있다. 주로 생성자 함수에서 사용하고, 해당 생성자로부터 생성된 모든 인스턴스가 공유하는 프로퍼티와 메소드를 정의한다.
.__proto__는 나의 원형을 가리키고, 모든 객체가 가지고 있다. 프로토타입 체인에서 현재 객체의 부모를 가리키는 링크 역할을 하며, 객체 간의 상속 구조를 형성하는 중요한 역할을 한다.
function Car(color) {
this.color = color;
}
const myCar = new Car('black');
console.dir(Car); // prototype 프로퍼티가 있다.
console.dir(myCar); // prototype 프로퍼티가 없다.
코드 설명
Car
는 생성자 함수이며, 객체를 생성하고 초기화한다.myCar
는Car
생성자 함수를 통해 생성된 인스턴스다.
- 콘솔을 통해
Car
함수 객체를 살펴보면, prototype 프로퍼티가 존재한다. 왜냐? 생성자 함수가 가지는 특수한 프로퍼티로 해당 함수로 생성된 인스턴스들이 공유하는 프로토타입을 지정하기 때문이다.console.log(Car.prototype === myCar.__proto__);
- 하지만 콘솔을 통해
myCar
인스턴스를 살펴보면, prototype 프로퍼티가 존재하지 않는다. 인스턴스 자체에 prototype 프로퍼티가 직접 존재하지 않는 대신, 인스턴스는 __proto__를 통해 프로토타입에 접근할 수 있다.console.log(Car.__proto__ === Function.prototype);
인스턴스 객체에서 어떤 프로퍼티에 접근하려고 할 때, 해당 객체에 그 프로퍼티가 없으면 프로토타입 체인을 따라 상위 프로토타입으로 올라가서 찾는다.
이를 통해 상속 구조를 형성하며 부모 객체의 속성이 자식 객체에게 상속된다.
const bigCarPrototype = {
start: function () {
console.log('BigCar starting');
},
};
const miniCarPrototype = Object.create(bigCarPrototype);
miniCarPrototype.drive = function () {
console.log('MiniCar driving');
};
const myCars = Object.create(miniCarPrototype);
myCars.drive(); // 출력: MiniCar driving
myCars.start(); // 출력: BigCar starting
코드 설명
bigCarPrototype
은 부모 객체이고,miniCarPrototype
은 자식 객체이며,Object.create
를 사용해 프로토타입 체인을 만들었다.
- 자, 이제
myCars
인스턴스는miniCarPrototype
을 프로토타입으로 가지며,drive
메소드를 직접 상속받고,start
메소드는bigCarPrototype
을 통해 간접적으로 상속받아 사용할 수 있다.