Prototype은 원래의 형태 또는 전형적인 예, 기초 또는 표준을 의미합니다.
자바스크립트의 객체는 [[Prototype]]
이라는 숨김 프로퍼티를 갖습니다. 이 숨김 프로퍼티 값은 null
이거나 다른 객체에 대한 참조가되는데, 다른 객체를 참조하는 경우 참조 대상을 '프로토타입(prototype)'이라 부릅니다.
object
에서 프로퍼티를 읽으려고 할 때, 해당 프로퍼티가 없으면 자바스크립트는 자동으로 프로토타입에서 프로퍼티를 찾습니다. 이런 동작 방식을 프로토타입 상속이라고 부릅니다.
[[Prototype]]
프로퍼티는 내부 프로퍼티이면서 숨김 프로퍼티이지만, __proto__
를 사용하여 값을 설정할 수 있습니다.
아래는 fruit
이 strawberry
의 프로토타입이 되도록 설정해준 예시입니다.
let fruit = {
seed: true
};
let strawberry= {
leaves: true
};
strawberry.__proto__=fruit;
alert
함수가 strawberry.seed
를 읽으려 하지만, strawberry
에는 seed
라는 프로퍼티가 없습니다. 이 때 자바스크립트는 [[Prototype]]
이 참조하고 있는 객체인 fruit
에서 seed
를 찾습니다. 따라서 strawberry
에서는 fruit
에서 구현된 seed
를 사용할 수 있습니다.
alert(strawberry.seed); //true
alert(strawberry.leaves); //true
이렇게 프로토타입에서 상속받은 프로퍼티를 '상속 프로퍼티(inherited property)'라고 합니다. 이제 "strawberry
의 프로토타입은 fruit
이다. " 또는 "strawberry
는 fruit
의 상속을 받는다"라고 말할 수 있습니다.
상속 프로퍼티를 사용해 fruit
에서 정의된 메소드도 strawberry
에서 호출할 수 있습니다.
let fruit = {
seed; true,
ripen() {
alert("과일이 익다");
}
};
let strawberry = {
leaves: true,
__proto__: fruit
};
strawberry.ripen(); //과일이 익다!
동일한 프로퍼티가 반복되어 메모리에 할당되는 문제를 해결하기 위해 프로토타입을 사용할 수 있습니다. 아래에서 donaldDuck
과 daisyDuck
은 species
와 friend
를 공통적으로 가지고 있고, 메모리에는 species
와 friend
가 두 개씩, 총 4개가 할당됩니다.
function Character() {
this.species = 'duck';
this.friend = 'mickey';
}
let donaldDuck = new Character();
let daisyDuck = new Character();
console.log(donaldDuck.species); // duck
console.log(donaldDuck.friend); // mickey
console.log(daisyDuck.species); // duck
console.log(daisyDuck.friend); // mickey
즉, 객체가 늘어날 수록 메모리에 할당되는 변수의 수도 늘어나게 됩니다. 이와 같은 문제를 프로토타입으로 해결할 수 있습니다. Character.prototype
이라는 객체에 species
와 friend
를 넣고, Character
함수로부터 생성된 객체 donaldDuck
과 daisyDuck
은 이를 공유해서 사용할 수 있습니다.
function Character() {
Character.prototype.species = 'duck';
Character.prototype.friend = 'mickey';
}
let donaldDuck = new Character();
let daisyDuck = new Character();
console.log(donaldDuck.friend); // mickey
Prototype은 Prototype Object와 Prototype Link로 나눌 수 있습니다.
객체는 언제나 함수로 생성됩니다.
var obj = {}
위 코드는 함수와 상관 없는 코드로 보이지만, 사실은 다음 코드와 같습니다.
var obj = new Object();
위 코드에서 Object
는 자바스크립트가 기본적으로 제공하는 함수입니다. Object
와 마찬가지로 Function
, Array
도 모두 함수로 정의되어 있습니다.
함수가 정의될 때는 해당 함수에 Constructor 자격이 부여되고, Prototype Object가 생성되어 이와 연결됩니다.
해당 함수에 Constructor(생성자) 자격 부여
Constructor 자격이 부여되면 new
를 통해 객체를 만들 수 있습니다. 따라서 함수만 new
키워드를 사용할 수 있습니다.
해당 함수의 Prototype Object 생성 및 연결
함수를 정의하면 함수 뿐 아니라 Prototype Object도 같이 생성됩니다.
생성된 함수는 Prototype이라는 속성을 통해 Prototype Object에 접근할 수 있습니다. Protoype Object는 일반적인 객체와 같으며 기본적인 속성으로 constructor
와 __proto__
를 가지고 있습니다
Prototype Object는 객체이므로 속성을 추가 또는 삭제할 수 있습니다.![]
__proto__
는 Prototype Link라고 불리며, 모든 객체에 존재합니다.
donaldDuck
에는 friend
라는 속성이 없지만, __proto__
라는 속성 때문에 donaldDuck.friend
를 실행하여 mickey
라는 값을 참조할 수 있습니다. __proto__
는 객체가 생성될 때 부모였던 함수의 Prototype Object를 가리키기 때문입니다.