Js - Prototype

자바스크립트는 프로토타입 기반 언어(prototype-based language)라고 한다. 여기서 말하는 프로토타입이란 무엇일까?

자바스크립트에서는 배열의 속성 값을 쉽게 가공할 수 있는 함수, map()을 제공한다. 이 map을 알아보기 위해 MDN 문서를 검색해보면 문서의 제목이 아래와 같은걸 알 수 있다.

MDN - map

프로토타입에 대한 MDN 문서를 살펴보자.

JavaScript는 흔히 프로토타입 기반 언어(prototype-based language) 라 불립니다. — 모든 객체들이 메소드와 속성들을 상속 받기 위한 템플릿으로써 프로토타입 객체(prototype object) 를 가진다는 의미입니다. 프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속 받을 수도 있고 그 상위 프로토타입 객체도 마찬가지입니다. 이를 프로토타입 체인(prototype chain) 이라 부르며 다른 객체에 정의된 메소드와 속성을 한 객체에서 사용할 수 있도록 하는 근간입니다.

https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Object_prototypes

프로토타입은 자바스크립트에서 객체들의 메소드와 속성을 상속할 수 있는 템플릿이라고 한다.

이제 코드를 통해 알아보도록 하자.

1
2
3
4
5
6
7
8
9
10
11
const Korea = { name: 'Korea', population: '50 M' };

function countryTemplate(nation) {
this.name = nation.name;
this.population = nation.population;
}
countryTemplate.prototype.introduction = function() {
return '제 국가는 '+this.name+'이고, 인구는 '+this.population+'입니다.';
}
const country = new countryTemplate(Korea);
console.log(country.introduction());

자바스크립트에서 위와 같은 코드를 작성해서 node로 실행해보았다.

result

country 라는 객체를 생성하기 위해 countryTemplate이라는 함수를 템플릿으로 사용했다. 이후에 처음 countryTemplate를 선언할땐 존재하지 않았던 introduction()이라는 함수를 prototype를 통해 추가할 수 있었다.

위의 코드에서 확인할 수 있는 상속 구조는 다음과 같다.

prototype

상속을 받을때 상위 객체의 프로토타입 체이닝을 거쳐 받음으로써 하위 객체들이 프로토타입의 속성과 메소드를 상속받을 수 있었다. 위의 코드에서 실제로 프로토타입을 변경한 구간은 countryTemplate과 country간의 상속관계에서의 프로토타입 체이닝이었다.

이번엔 아닌 자바스크립트에서 제공하는 내장 객체중 하나인 배열(Array)의 프로토타입을 제어해보겠다.

1
2
3
4
5
6
7
8
9
10
11
const arr = [0,1,2,3,4];
const arr2 = 'Hello'.split('');

Array.prototype.print = function() {
for(let i=0; i<this.length; i++) {
console.log(this[i]);
}
}

arr.print();
arr2.print();

프로토타입을 이용하면 속성을 추가하거나 이처럼 함수를 추가해서 마치 내장 객체마저 커스터마이징 할 수 있는 효과를 누릴 수 있다.

그러나 직접 속성을 추가하는 행위는 권하지 않는다. 프로토타이핑은 상속 관계의 상위 객체의 속성을 제어하는 일인데 반복적으로 사용할 속성이 아니라면, 굳이 프로토타입에 정의하기보다는 인스턴스에서 추가하는것이 목적에 더 부합할 수 있다.