티스토리 뷰
프로토타입이 무엇인지를 설명하기에 앞서 자바스크립트에서는 같은 프로퍼티를 가진 객체를 여러개 생성하고 싶을 때 어떻게 하는지 알아보자.
인스턴스 객체를 생성하기 위한 4가지 방법을 알아보았다. 그 중에서도 인스턴스 객체를 생성할 때마다 인스턴스에 메서드가 할당되어 인스턴스 메서드 개수만큼 메모리를 차지 했다. 성능이 저하되고 메모리의 효율이 떨어진다.
이러한 단점을 보완하고자 함수에 메서드를 정의 하지 않고, 함수 밖에서 공통으로 사용할 메서드를 정의했다. 인스턴스 객체를 생성할때마다 메서드가 실행되지 않기 때문에 메모리 절약이 된다.
아래의 코드를 보며 프로토타입을 이해해보자.
// 생성자 함수 정의
function Person(name, first, second) {
this.name = name;
this.first = first;
this.second = second;
}
// Person의 prototype에 메서드 sum 정의
Person.prototype.sum = function() {};
// new 키워드를 통해 생성자 함수는 인스턴스 객체 반환
var kim = new Person('kim',10,20);
생성자 함수(constructor)는 인스턴스 객체를 만들기도 하지만, 인스턴스 객체의 초기 상태를 세팅한다(프로퍼티 정의)
여기서 중요한 점은 자바스크립트에서 함수도 객체라는 점이다. 그래서 함수 Person에 대한 새로운 객체가 생기고 동시에 함수 Person의 프로토타입 객체가 생긴다.
함수 Person은 prototype 프로퍼티를 가지고 있으며, 해당 속성은 Person의 프로토타입을 가리킨다.
Person의 프로토타입은 constructor 속성을 가지고 있으며, 함수 Person을 가리킨다.
즉, 상호 참조를 하고 있다.
3)은 함수 Person과 new 키워드를 이용하여 생성한 인스턴스 객체 kim를 그림으로 그려봤다.
만약에 kim.name;을 실행한다면? 자바스크립트는 kim 객체에서 name이라는 프로퍼티가 있는지 찾는다. 객체 kimd에 name 프로퍼티가 있다면 객체 kim의 name 프로퍼티에 저장된 값을 출력한다.
만약에 객체 kim에 name 프로퍼티가 없다면, 객체 kim의 __proto__ 프로퍼티가 가리키는 객체인 Person.prototype찾아가서 name프로퍼티가 있는지 찾아 본다. Person.prototype에 name 프로퍼티가 있다면 해당 프로퍼티를 출력한다.
만약 Person.prototype에도 name 프로퍼티가 없다면, person.prototype의 __proto__ 프로퍼티가 가리키는 객체로 찾아간다. 최상위 Object의 prototype에 가서도 해당 프로퍼티를 찾지 못하면 undefined를 리턴한다.
이러한 __proto__ 프로퍼티를 통해 상위 프로토타입과 연결되어 있는 것을 프로토타입 체인이라고 한다.
객체 kim이 메서드 sum을 사용한다면 위와 같은 방식으로 __proto__ 프로퍼티를 통해 상위 프로토타입에 접근하게 된다.
Prototype
자바스크립트는 prototype을 기반으로 상속을 구현한다. 생성자 함수(객체 만들어 내는 틀이라고 생각하자)와 new 키워드를 이용하여 인스턴스 객체를 만들어 낸다. 생성자 함수가 정의될 때, 생성자 함수의 프로토타입 객체도 동시에 생성된다. 프로토타입과 인스턴스 객체는 __proto__ 프로퍼티를 가지고 있기 때문에 해당 프로퍼티를 통해 상위 프로토타입에 접근할 수 있다. 그리고 상위 프로토타입의 프로퍼티 및 메서드에 접근할 수 있다. 이러한 특징을 통해 중복된 코드 줄일 수 있고, 재사용성을 높일 수 있다.