코어자바스크립트 chapter6의 내용 '프로토 타입'의 개념에 대해 알아보자.
프로토타입 = 자바스크립트
자바스크립트는 프로토타입기반 언어라고 불릴만큼 '프로토타입'은 js에서 핵심개념이다. 클래스기반언어에서는 '상속'을 사용하지만, 프로토타입기반언어에서는 어떤 객체를 원형(prototype)
으로 삼고 이를 복제함으로써 상속과 비슷한 효과를 얻는다.
var instance = new Constructor();
위의 코드를 이해하고, 그림을 보며 문장을 만들 수 있다면 프로토타입의 이해는 끝난 것이다. ^^
=> new
키워드(연산자)로 constructor
를 호출하면, instance
가 만들어지는데, 이 instance의 생략 가능한 프로퍼티인__proto__
는 Constructor의 prototype
을 참조한다.
위 문장을 이해하기 위해서 위에서 언급한 각각의 단어들에 대해서 알아보도록 해보자.
인스턴스
라는 용어는 "객체(object)"와 유사하다.
의미상으로 "객체"는 좀더 일반적인 의미인 반면에 "인스턴스"라고 표현하면 "현재 생성된 바로 그 객체"라는 인스턴트한 뉘앙스로 좀 더 짙게 표현할 수 있다.
또는 어떤 클래스의 속성을 지니는 실존하는 개체를 일컬어 말한다.
let cho = {
name:'hye-mi',
first:10,
second:20,
sum:function(){
return this.first+this.second;
}
}
let choi = {
name:'ha-neol',
first:10,
second:15,
sum:function(){
return this.first+this.second;
}
}
let kim = {
name:'bo-hyen',
first:30,
second:10,
sum:function(){
return this.first+this.second;
}
}
console.log("cho.sum()", cho.sum());
console.log("choi.sum()", choi.sum());
console.log("kim.sum()", kim.sum());
=> 객체가 동작하는 방법을 바꾼다면(ex.객체에 third라는 속성을 추가해야 하는 경우) 해당하는 속성들을 일일히 다 바꿔줘야 하는 문제점이 발생한다.
function Person(name, first, second, third){
this.name = name;
this.first = first;
this.second = second;
this.third = third;
this.sum = function(){
return this.first + this.second + this.third;
}
}
let cho = new Person('hye-mi',10, 20, 30);
console.log(cho);
// Person {
name: 'hye-mi',
first: 10,
second: 20,
third: 30,
sum: [Function]
}
new연산자를 붙여주어 새로운 인스턴스가 만들어졌다는 것을 알려준다. new를 붙이면, Person함수는 더이상 기존의 일반적인 함수가 아니라, 객체를 생성하는 생성자함수가 된다. (new가 있다면 = 생생자 함수)
위의 코드에서 cho라는 객체를 생성할 때, Person이라는 함수를 생성자로서 동작시켰다. new 키워드로 인스턴스 만들 때 마다 sum함수를 정의해주어 메모리 낭비를 하게된다.
함수를 분리해서 prototype을 사용하게되면, Person이라는 생성자함수가 실행될때마다 나오는 것이 아니라 한번만 실행하게 된다.
function Person(name, first, second, third){
this.name=name;
this.first=first;
this.second=second;
this.third=third;
}
Person.prototype.sum = function(){
return 'prototype : '+ (this.first+this.second+this.third);
}
let cho = new Person('hye-mi', 10, 20, 30);
let choi = new Person('choi', 10, 10, 50);
console.log("cho.sum()", cho.sum());
console.log("choi.sum()", choi.sum());
프로토를 통해 인스턴스와 객체 간의 상속관계를 자유롭게 설정할 수 있다.
let superObj = {superVal:'super'}
let subObj = {subVal:'sub'}
subObj.__proto__ = superObj;
console.log('subObj.subVal:', subObj.subVal);
//subObj의 'superVal'값을 바꾸는 경우
subObj.superVal = 'sub';
console.log('superObj.superVal:',);
⇒ superObj의 객체의 값을 바꿨을 뿐, __proto__가 가르키는 객체를 바꾼 것이 아니다. 즉, proto를 바꾸는 것이 아니다.