prototype chain은 세가지 단계로 나눌 수 있다.
- 생성자 함수(class의 constructor)
- 원형(부모) 객체(instance객체의 prototype)
- 복사(자식) 객체(instance)
function myfamily(1starg, 2ndarg, 3rdarg){
this.age = 1starg;
this.name = 2ndarg;
this.role = 3rdarg;
}
let mom = new myfamily(47,'ajs','mother');
console.log(mom);//myfamily{age: 47, name: 'ajs', role: 'mother'}
이전 프로토타입의 기본에 대해 기록해두었던 코드이다. 클래스 방식으로 다시 표현하자면,
class myfamily{
constructor(1starg, 2ndarg, 3rdarg){
this.age = 1starg;
this.name = 2ndarg;
this.role = 3rdarg;
}
}
let mom = new myfamily(47,'ajs','mother');
console.log(mom);//myfamily{age: 47, name: 'ajs', role: 'mother'}
이렇게 바꾸어 표현할 수 있다.
먼저
- 생성자 함수(class의 constructor)
- 원형(부모) 객체(prototype)
이 두 친구 관계에 대해 말하자면,
위 코드에서 constructor
함수를 통해 prototype객체가 만들어진다고 가정했을 때, 굳이 코드로 구현 해보자면 이런 형태이다.
//prototype 객체
{
age : 1starg,
name : 2ndarg,
role : 3rdarg
}
constructor
함수를 통해 만들어진 prototype객체는 value값이 정의 된다면 언제든 만들어질 수 있는 준비된 객체 정도로 생각하면 될 것 같다.
이러한 형태라면 메서드를 통해 속성이나 메서드를 넣을 수 있는데,
myfamily.prototype.family = 'tess';//프로토 타입 객체 안에 family:'tess' 의 형태로 들어가는 속성
myfamily
로 생성된 prototype
객체에 family
라는 key
값을 가지고 'tess'
라는 value
값을 가진 속성을 추가한다.
myfamily.prototype.hello = el => `안녕 ${el}`; //프로토타입 객체 안에 hello(el):`안녕 ${el}`의 형태로 들어가는 메서드
myfamily
로 생성된 prototype
객체에 hello
라는 함수명을 가지고el
을 인자로 받아 '안녕 ${el}'
이라는 값을 return하는 메서드를 추가한다.
라고 풀어 쓸 수 있다.
prototype 객체는 생성자 함수의 선언으로 만들어지고, instance 객체가 선언되어 인자를 받기 전까지는 그저 껍데기같은 역할이라고 생각이 든다.
prototype이 껍데기 상태를 탈출하기 위한 열쇠!
- 원형(부모) 객체(instance객체의 prototype)
- 복사(자식) 객체(instance)
이 두 친구의 관계에 대해 이야기 해보려 한다.
가장 쉽게 부모를 쏙 빼닮은 부모와 자식정도로 생각하면 된다.
instance 객체는 prototype 객체의 속성과 메서드를 복사하듯 그대로 가져온다. 이후에 또 다른 속성이나 메서드를 추가할 수 있다. 마치 자식이 부모와 생김새는 닮아도 똑같은 삶을 살지는 않는 것 처럼 말이다.
그래서 표현식 또한
let mom = new family(47,'ajs','mother');
이렇게 기존 객체의 속성을 바꾸지 않게 new
라는 메서드를 사용한다.
instance객체의 친족 확인(?) 방법은 .__proto__
라는 메서드를 이용한다. 브라우저 콘솔창에서 보면 엄마(?)의 엄마의 ...의 엄마까지 알 수 있는데, 결국 최종 보스 엄마는 Object
가 된다. 모든 객체의 원형은 Object
이기 때문이다.
그리고 Object
부터 가장 가까운 prototype 객체의 속성과 메서드를 instance 객체에서 활용이 가능하다.
중간에 한번 슥 훑고 지나간 class라는 개념과 class를 확장시키는 super라는 개념에 대해 알아보자.
class
instance객체를 생성하기 위한 템플릿이다. 속성, 메서드를 추가할 수 있으며 class에 추상화된 속성과 메서드는 instance 객체에 복사되어 사용할 수 있다.
class myfamily{ //myfamily라는 class 생성
constructor(age, name, role){ //constructor를 통해 속성 생성
this.age = age;
this.name = name;
this.role = role;
}
this.introduce = function(){
return `안녕하세요 ${this.family}의 가족 ${this.name}입니다.`
}//소개하는 메서드 생성
}
let mom = new myfamily(47,'ajs','mother');//instance객체 생성(속성과 메서드 복사)
console.log(mom);//myfamily{age: 47, name: 'ajs', role: 'mother'}
mom.introduce();//`안녕하세요 tess의 가족 ajs입니다.`
super
새로운 선언식에 부모 오브젝트의 함수를 호출할 때 사용되는 키워드이다.
class myfamily{
constructor(age, name, role){
this.age = age;
this.name = name;
this.role = role;
}
}
class yourfamily extends myfamily{ //extends는 해당 class를 다른 class의 자식으로 만들때 사용
constructor(age, name, role){
super(age, name, role);//super에서 먼저 참조 되어야 오류가 발생하지 않음.
this.role = 'your ' + role;
}
}
let yourmom = new yourfamily(53,'ksb','sister');
console.log(yourmom);////myfamily{age: 53, name: 'ksb', role: 'your sister'}
super
는 자식 class의 constructor
안에서 this
가 실행되기 전에 실행되어야 하는 키워드이다. 실행시키지 않은 상태에서 인자를 불러올 경우 오류를 발생시킬 수 있다.