javascript에서 상속의 개념을 갖게 해주는 prototype.
정확한 동작 방식보다는 개념에 초점을 맞추어 생각해본 글입니다...
prototype은 일종의 유전자 같은 개념이다.
- (부모입장)
prototype
: 유전자, 자손에게 넘겨주고픈 메소드,변수를 정의함.- (자식입장)
__proto__
(property) : 내가 받은 유전자 접근하기. 부모에게 유전받은prototype
을 참조할 수 있다.
ECMA-262에서 prototype은 ‘object that provides shared properties for other objects’로, 다른 객체에 공유 프로퍼티(메서드 포함)를 제공하는 객체이다.
재해석 :
prototype
는 일종의 유전자와 같이 자신을 조상으로 하는 다른 객체에게 공유(유전자면, 전달이라는 의미가 좀 더 쉽겠지만, 실제 공유와 더 가깝다)하는 property 혹은 method 객체이다.
생물학적 유전자와는 당연 차이가있다...
❓ 객체의 유전자인 프로토타입도 객체라는 것이죠?
❗ 네(니오), 넘겨주고싶은 유전자가 없다면?
null
이고, 있으면 객체의 형태로 존재한다.
prototype
은null
혹은 객체
좀 더 자세한 내용은... Prototype과 proto 이해하기(2)에서...
__proto__
란?모든 객체는
__proto__
를 통해 자신이 물려받은[[Prototype]]
값에 접근할 수 있다.
재해석 :__proto__
라는 프로퍼티로 유전자 접근이 가능하다.
하지만
[[Prototype]]
내부 슬롯에는 직접 접근이 불가하다. 이는 프로토타입 체인의 단방향을 지키기 위해서다. 만약 직접 접근가능하다면, 서로가 서로의 프로토타입이 되면서 프로토타입 체인이 무한으로 돈다. 따라서__proto__
프로퍼티로만 접근할 수 있다.
자식이 자신이 받은 유전자를 확인할 수 있는 property 이다. 애초 자식 오브젝트를 만들 때, 명시적으로 선언하지 않지만 자바스크립트 엔진이 내부적으로 알아서 할당해준다.
따라서 자식객체.__proto__
를 내가 정의해주지 않았어도, 이미 정의가 되어있다. (내가 태어나면, 자동적으로 부모님의 유전자가 내 안에 있는것처럼 객체 혹은 null
로 정의되어있음)
예를 들어, const str_instance = new String("abc");
을 하면, str_instance
는 String
이라는 부모로부터 낳아진 자식이다. 따라서 __proto__
에 String.prototype
이 이미 자동적으로 잘 정의되어진다.
const str_instance = new String("abc");
String.prototype === str_instance.__proto__ //true
결국, String
오브젝트가 자식에게 넘겨주고싶던 유전자 String.prototype
와 str_instance
가 받은 유전자 str_instance.__proto__
는 같다.
재번역하면, 자식은 부모로부터 자기가 물려받은 유전자를 활용할 수 있나요? yes! 부모뿐만 아니라 부모의 부모, 부모의 부부부부부모 유전자까지 활용가능하다.
프로토타입 체인(prototype chain) 구조로 활용 가능한데, chaining rule(연쇄법칙)을 상상하면 개념은 쉽다.
.__proto__
로 접근.__proto__.__proto__
로 접근즉, 객체는 chain rule(연쇄법칙) 구조로 property나 method를 활용한다.
undefined
, 메소드이면 TypeError
를 반환한다.const str_instance = new String("abc");
//자식에게 존재
console.log(str_instance[0]) //a
//자식에게 없고 부모에게 존재
console.log(str_instance.indexOf("c")) //2
//자식에게 없고, 부모,조부모에게 있지만 더 측근인 부모 method활용하고 조부모 prototype 접근 안함
console.log(str_instance.valueOf()) //'abc'
//자식에게 없고, 부모에게 없고 조부모 prototype에 존재
console.log(str_instance.hasOwnproperty())//false
//자식,부모,조부모,,...., 모두 없음
console.log(str_instance.count());//error, 함수없음
//자식,부모,조부모,,...., 모두 없음
console.log(str_instance.long);//undefined
재해석 : 유전자가 변경되면, 이 유전자를 갖는 자손들은 어떻게 되나요?
const str_instance_before = new String("abc");
console.log(str_instance_before.sayHi()); //error,자식 그리고 모든 조상에 정의되지 않음.
String.prototype.sayHi = function(){
return "hi!"}
console.log(str_instance_before.sayHi()); //"hi!"
const str_instance_after = new String("cde");
console.log(str_instance_after.sayHi()); //"hi!"
이 유전자를 갖는 자식뿐만 아니라 모든 자손의 유전자__proto__
가 변경됨
내용상 오류가 있으면 알려주시면 감사합니다.