JS

prototype

gurwhddl 2022. 10. 1. 16:16

일단 간단하게 prototype을 유전자라고 생각하면됨

 

function A() {this.xx = xx}

이렇게 constructor를 만들고

let x = new A 이렇게 하게되면 new A라는 오브젝트를 x에 상속시키게 되는거임 

왼쪽이 자식, 오른쪽이 부모

A.prototype이라는걸 찍어보면 어떤 함수같은게 나오는데 이게 바로 유전자인거 - 자식에게 상속가능

이 유전자에 새로운걸 추가해서 상속도 가능함

A.prototype.aa = 1 이라는 값을 추가하게되면 자식인 x에게도 그 값이 상속이 됨 ( 하지만 x를 찍어보면 나오지는 않고 x.aa로 찍어보면 1 이 나옴 ) 비밀공간이 주어진다고 생각하면됨

 

자바스크립트는 오브젝트에서 값을 출력할 때 이런 순서로 물어봅니다.

(1) 학생1에 직접 gender라는 값이 있는가?

(2) 그럼 부모 유전자에 gender라는 값이 있는가?

(3) 그럼 부모의 부모 유전자에 gender라는 값이 있는가?

(4) 그럼 부모의 부모의 부모의 유전자에 .. 그게 있는가? 

 

이런 특성 탓에 x.aa를 했을 때 실제 값에는 담겨있지 않지만 부모 유전자(prototype)에 aa = 1이라고 추가했기 때문에 그 값을 받아오는거임

var arr = [1,2,3];
var arr = new Array(1,2,3);

▲ 위 코드 두줄은 같은 완전 똑같은 의미입니다.

위는 인간이 array 만드는 방식, 밑은 컴퓨터가 array 만드는 방식입니다. 

사람은 귀찮아서 [] 그냥 대괄호쳐서 만드는데 내부적으로는 저렇게 new 키워드를 항상 이용해서 array/object를 만들어줍니다.  

 

그러면 당연히 Array에 있는 prototype을 상속받게됨. Array.prototype 찍어보면 여러 내장함수들이 나오는데 이때문에 []로 만든 모든 값들은 .map . push 이런 내장함수들 사용쌉가능.

 

mdn에서 항상 검색하면 array.prototype.sort ㅇㅈㄹ로 나왔던 이유가 바로 이거

object는 비슷하게 new Object로 만들어짐

 

세부특징

1) prototype은 함수에만 몰래 생성됨

  var x = new 함수() 

x.prototype // error 

만약에 변수에서 내 윗 부모의 prototype이 뭔지 궁금하면

x.__proto__를 찍어보면됨(언더바 2개임) - 유전자 검사같은느낌. 유전자가 뭔지 알아볼 수 있음

그러면 아까 이후에 .prototype.aa = 1 찍은거랑 A constructor 함수가 나올거임

사용법(근데 잘안씀)
var 부모 = {firstName : 'lee'}

var 자식 = {} 

두개는 다른 object니까 부모의 prototype을 자식에게 주면됨 

자식.__proto__ = 부모라고 하면 부모가 가지고 있는 모든 속성이 자식에게 상속이됨 

찍어보면 자식은 {}지만 자식.firstName이 가능

근데 이것보다 편한 문법이 있어서 잘안씀

 

탐색해보시면 모든 object 자료형의 조상은 Object() 라는 기계이며 (일명 Object.prototype)

모든 array 자료형의 조상도 Object()입니다. (중간에 Array()라는 부모도 있고요)

모든 함수 자료형의 조상도 Object() 입니다.

(그래서 자바스크립트는 모든게 다 Object라고 말하는 것입니다.)

 

** 여기서 prototype나  __proto__로 추가할 때 만약에 값이 존재하는거에서 추가를 한 상황일경우에는 기존에 있던 값이 출력됨

function 부모() {this.name = 'kim'}
undefined
var 자식 = new 부모
undefined
자식 
부모 {name: 'kim'}
부모.prototype.name = 'park'
'park'
자식.name 
'kim'  

 

 

이걸 쉽게하는법

Object.create(추가하고 싶은 prototype) 해주면됨

상속기능을 구현하는 ES5 방법

 

let 부모 = {firstName : 'lee' , 집: '서울'}

let 자식 = Object.create(부모); - prototype을 부모로 하라는 뜻

아까랑 똑같이 자식 찍어보면 {}로 나오지만 자식.firstName 은 'lee'로 나온다.

물려받은 값을 바꾸고싶으면 자식.집 = '대전' 이런식으로 바꿔주면 되는데

만약에 여기서 또 let 손자 = Object.create(자식) 이런식으로 만들게되면

손자.집을 했을 때 일단 손자의 object에는 그 값이 없기때문에 그 부모, 즉 자식의 object에 가게 된다.

아까 방금 자식.집 = 대전 이라고 설정해놨기 때문에 이 값은 이제 자식의 obj 안에 들어있기 때문에 손자.집은 서울이 아닌 대전으로 출력됨

object의 가장 최상위 부모는 new Object()