자바스크립트는 프로토타입 기반의 객체지향 프로그래밍 언어이다.
C++나 자바 같은 클래스 기반 객체지향 프로그래밍 언어는 클래스가 있고, 클래스를 통해 상속을 사용한다. 하지만 자바스크립트는 클래스가 없고 객체를 프로토타입 기반으로 복제를 통해 생성한다. (자바스크립트의 class 는 ES6에서 추가된 문법)
프로토타입은 상속하고자 하는 속성과 메소드를 담아두는 공간(유전자). 모든 객체는 프로토타입으로부터 프로퍼티와 메소드를 상속받는다.
클래스는 붕어빵 틀. 클래스 기반에서 객체는 붕어빵 틀인 클래스로 붕어빵을 찍어내지만, 프로토타입 기반에서 객체는 유전자인 프로토타입을 복제해서 사용한다.
function Parent() {
this.health = 'good';
this.skin = 'dry';
}
const child = new Parent ()
Parent.prototype.hair = 'thick' // prototype에 추가 가능
child.hair
// thick
→ Parent의 prototype에 hair라는 데이터를 추가하면, child에서도 Parent의 데이터를 끌어올 수 있다.
객체의 프로퍼티에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티가 없으면 부모 프로토타입의 프로퍼티를 순차적으로 검색한다.
✔ proto : 부모에게 유전받은 프로토타입을 참조하는 속성
생성자 함수를 통해 쉽게 객체를 생성할 수 있지만, 객체의 메서드를 등록할 때마다 새로운 함수가 생성된다.
function Member(name) {
this.name = name;
this.sayHello = function() {
console.log(`Good morning, ${this.name}!`);
} // 객체의 메서드 등록 할 때마다 새로운 함수 생성
}
const mem1 = new Member('민영');
const mem2= new Member('지훈');
여기서 문제는 객체의 메서드를 등록할 때마다 sayHello이라는 새로운 함수를 생성한다. 동일한 생성자 함수에 의해 생성된 모든 인스턴스가 동일한 메서드를 중복 소유하는 것은 메모리를 낭비하는 것이다.
이 문제를 해결하기 위해 프로토타입을 사용한다. Member 생성자 함수가 생성한 모든 인스턴스가 sayHello 메서드를 공유해서 사용할 수 있도록 프로토타입에 추가한다.
function Member(name) {
this.name = name;
}
Member.prototype.sayHello = function() {
console.log(`Good morning, ${this.name}!`);
}
const mem1 = new Member('민영');
const mem2= new Member('지훈');
프로토타입은 Member 생성자 함수의 prototype 프로퍼티에 바인딩되어 있다. Member 생성자 함수가 생성한 모든 인스턴스는 Member.prototype으로부터 하나의 sayHello메서드를 공유한다.
sayHello 메서드는 단 하나만 생성되어 프로토타입인 Memeber.prototype의 메서드로 할당되어 있다. 따라서 Member 생성자 함수가 생성하는 모든 인스턴스는 sayHello메서드를 상속받아 사용할 수 있다.
부모 역할을 할 생성자 함수
function Parent() {
this.health = 'good';
this.skin = 'dry';
}
Parent.prototype.hair = 'thick'
자식 역할을 할 생성자 함수
function Child() {
Parent.call(this);
} // call 함수는 Child함수의 this가 Parent생성자 함수의 this를 바라보게 한다.
Child.prototype = Object.create(Parent.prototype);
// 인자를 Child.prototype에 연결한다.
const junior = new Child()
Object.create는 프로토타입을 지정해서 새로운 객체를 생성한다. Object.create의 첫 번째 매개변수는 프로토타입을 지정할 객체(부모)를 전달한다. 두 번째 매개변수는 생성할 객체의 프로퍼티를 전달한다. Parent의 프로토타입을 Child의 프로토타입이 참조하게 하라는 것이다.