자바스크립트에는 다른 언어들(Java, Python, Ruby)에는 있는
Class 개념 대신 Prototype이 존재한다.
아래의 코드를 한번 보자.
function Person() {
this.eyes = 2;
this.nose = 1;
}
var kim = new Person();
var park = new Person();
console.log(kim.eyes); // => 2
console.log(kim.nose); // => 1
console.log(park.eyes); // => 2
console.log(park.nose); // => 1
위 코드는 한가지 단점이 있다.
kim, park 외의 다른 객체(new Person();)이 늘어날 수록 eyes, nose 도 늘어나
메모리를 많이 쓴다는 것.
이런 단점을 아래처럼 Prototype으로 해결할 수 있다.
function Person() {}
Person.prototype.eyes = 2;
Person.prototype.nose = 1;
// person 안에 있던 eyes, nose를 밖으로 꺼내 Prototype 형식으로 작성했다.
var kim = new Person();
var park = new Person():
console.log(kim.eyes); // => 2
console.log(kim.nose); // => 1
console.log(park.eyes); // => 2
console.log(park.nose); // => 1
Person.prototype 이라는 빈 객체에 eyes와 nose를 저장시킨다
Person으로부터 파생된 kim, park는 Person.prototype에서 eyes, nose를 꺼내 쓴다.
따로 Person.prototype에 eyes, nose를 저장시켰기 때문에 kim,park 외의 새로운 객체가 늘어나도 더 이상 메모리가 늘어나지 않는다.
자바스크립트에서 Prototype은 기본적으로 Object와 Link로 구성되어있다. 그중 먼저 Object를 알아보자.
코드를 작성하다 보면 객체를 생성하는 일은 자주 있을 것이다. 그런데 그 객체들이 전부 '함수'로부터 생성되었다는 것을 알고 있는가?
function Person() {} // => 함수
var personObject = new Person(); // => 함수로 객체를 생성
함수가 정의되고
그 함수로 객체를 생성한다.
만약 그렇다면 함수를 정의하지 않고 객체를 생성하면?
var obj = {}
위 코드의 어딜 봐도 함수가 없지만 사실 위 코드는 다음과 같다.
var obj = new Object();
(new Object()는 {}이다. )
빈 객체를 생성해도 자바스크립트에서 기본적으로 제공하는 Object 라는 함수에서
객체를 생성해 제공하는 것이다.
그런데 이 때, 정의된 함수가 객체를 생성할 때 동시에 2가지 일을 더한다.
생성자(constructor)자격이 생기면 new 키워드를 통해 객체를 만들어낼 수 있다.
생성자 자격이 있는 함수만이 new 키워드를 사용할 수 있다.
(객체는 불가능하다)
함수가 정의되면, Prototype Object도 같이 생성된다.
(abc.prototype이라는 객체가 생성되었다)
위의 예시를 보면 abc라는 함수를 만들자,
abc.prototype이라는 객체가 같이 생성된 모습을 보인다.
constructor라는 키 값에 함수 abc라는 밸류값이 들어있고,
__proto__라는 키 값에 Object라는 밸류값이 들어있다.
여기서 abc.prototype은 객체이기 때문에 속성을 마음대로 추가할 수 있다.
abc.prototype이라는 객체에 eyes라는 속성을 추가했고 밸류로 2를 넣은 모습이다.
그리고 abc()는 생성자 함수이기 때문에 new 키워드를 사용할 수 있다.
그렇게 kim이라는 새로운 객체는 eyes라는 속성을 abc.prototype에서 가져와 사용할 수 있다.
그런데 어떻게 kim은 eyes라는 속성도 없으면서 2라는 값을 가져와 사용할 수 있을까?
그건 Prototype Link 덕분이라고 할 수 있다.
kim을 콘솔창에서 찍어보면 빈 객체가 나올 것이라고 생각하는가? 자바스크립트의 모든 객체가 가지고 있는 딱 하나의 속성이 있다. _proto_.
생성자 함수만 가지고 있던 prototype 속성과 달리 _proto_ 속성은 어느 객체나 가지고 있다.
(kim.prototype은 나오지 않지만 _proto_는 출력된다.)
kim이 eyes와 nose 속성을 가질 수 있었던 이유는 _proto_가 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리키기 때문이다. 여기서는 abc.prototype을 가리킬 것이다.
(역시 abc 함수의 prototype을 가리키고 있었다)
kim객체가 eyes를 직접 가지고 있지 않기에 eyes 속성을 찾을 때 까지 상위 프로토타입, 그것의 상위 프로토타입... 계속 탐색해 나간다. 최상위인 Object의 Prototype Object까지 도달했는데도 못찾았을 경우 undefined를 리턴한다. 이렇게 _proto_속성을 통해 상위 프로토타입과 연결되어있는 형태를 프로토타입 체인(Chain)이라고 한다.
이런 프로토타입 체인 구조 때문에 모든 객체는 Object의 자식이면서,
Object Prototype Object에 있는 모든 속성을 사용할 수 있다.
es5 부터는 JS 에서도 클래스를 사용할 수 있답니당 !
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Classes