JavaScript

프로토타입에 관해

J개발자 2022. 3. 14. 01:34

JS(자바스크립트) 이해하기 어려운 부분들을 복습삼아 글을 쓴다.

 

상속관점에서 유일한 생성자는 객체뿐이다.

은닉속성을 가지는데 바로 프토로타입!  프로토타입을 계속 찾아나서고 이를 프로토타입 체인이라한다.

이러한 점이 JS의 약점이라하지만 상송모델은 고전적?이다 할 수 있으며 더 강력한 방법이라할 수 있다.

프로토타입적 모델에서 고전적인 방식 구현은 꽤나 사소한 일이지만 그 반대는 훨씬 어려운일이기 때문.

 

프로토타입 체인을 이용한상속!

모든 함수는 prototype이라는 특수한 속성을 갖는다.

let f = function(){
  this.a = 1
 }
 let o = new f();
 
 f.prototype.a = 2;
 f.prototype.b = 3;

f라는 함수 o라는 객체가 있다. 객체 o는 속성 a를 가지고 있다.

함수 f에 프로토타입 속성 값을 추가하였다.(b)

o.prototype 의 속성은 a와 b.

o.prototype.prototype = object.prototype 

o.prototype.prototype.prototype = null (종단이다)

o.a = 1 (속성값) 단 프로토타입이 속성을 가지지만 이값은 쓰이지 않는다.(2값) "prototype shadowing"

o.b 는 속성을 가지지 않는다. o.prototype은 b라는 속성을 가지고있다.

그럼 o.c는 속성을 가지지도 않고 o.prototype에도 가지고 있지 않다. o.prototype.prototype.prototype = null 이다.

그렇기에 undefined를 반환한다.

 

JS에서 메소드라는 건 없다 객체의 속성으로 함수를 지정할 수 있고 속성값을 사용하듯 쓸 수 있다.

마치 자기가 가지고있는 것마냥 사용한다. 

 

상속함수 실행될때 this라는 변수는 상속된 오브젝트를 가르킨다.

var o = {
 a:2,
 b: function(b){
     return this.a+1;
     }
 };
 
 var p = object.create(o);
 p.a = 12;

o.b = this는 함수o의 a+1 를 리턴. 즉 this = 함수o를 가르킨다.

p는 프로토타입을 o로 가지는 오브젝트.

p.a = 12는 p에 새로운 a라는 속성을 만든다. 

p.b = 의 this는 이제 o가아닌 p를 가르킨다. o함수의 b를 상속받아 개인 속성이라 할 수 있다.

 

프로토타입을 사용하는 방법

function doSomething(){};
var doSomething = function(){};

두 실행문을 파헤쳐보면 (객체 console.log(doSomethis.prototype) 해보면) 아래와 같다.

{
    constructor: ƒ doSomething(),
    __proto__: {
        constructor: ƒ Object(),
        hasOwnProperty: ƒ hasOwnProperty(),
        isPrototypeOf: ƒ isPrototypeOf(),
        propertyIsEnumerable: ƒ propertyIsEnumerable(),
        toLocaleString: ƒ toLocaleString(),
        toString: ƒ toString(),
        valueOf: ƒ valueOf()
    }
}

함수의 객체가 생성되면 constructor와 __proto__가 자동 만들어진다.

function doSomething(){}
doSomething.prototype.foo = "bar";
console.log( doSomething.prototype );

      |
      V
{
    foo: "bar",
    constructor: ƒ doSomething(),
    __proto__: {
        constructor: ƒ Object(),
        hasOwnProperty: ƒ hasOwnProperty(),
        isPrototypeOf: ƒ isPrototypeOf(),
        propertyIsEnumerable: ƒ propertyIsEnumerable(),
        toLocaleString: ƒ toLocaleString(),
        toString: ƒ toString(),
        valueOf: ƒ valueOf()
    }
}

위코드결과는 프로토타입에 속성을 추가한것.

아래는 객체에 추가하는 것.

함수로 정의된건 new 통해 함수의 객체(인스턴스)를 만들 수 있다. 이를 통해 속성들을 이 객체에 추가한다.

function doSomething(){}
var doSomeInstancing = new doSomething();
doSomeInstancing.prop = "aaa";   //객체에 속성 추가
console.log( doSomeInstancing );

          |
          V
{
    prop: "aaa",
    __proto__: {
        foo: "bar",
        constructor: ƒ doSomething(),      // -------doSomething.prototype();---------
        __proto__: {
            constructor: ƒ Object(),
            hasOwnProperty: ƒ hasOwnProperty(),
            isPrototypeOf: ƒ isPrototypeOf(),
            propertyIsEnumerable: ƒ propertyIsEnumerable(),
            toLocaleString: ƒ toLocaleString(),
            toString: ƒ toString(),
            valueOf: ƒ valueOf()
        }
    }
}

함수 doSomethig의 prototype이 객체  doSomeInstancing에 연결되고 이 doSomeInstancing(doSomethig의 object)가 

가지는 기본 속성(constructor , __proto__)은 함수 doSomethig을 연결한다.

doSomeInstancing.prop:      aaa
doSomeInstancing.foo:       bar
doSomething.prop:           undefined
doSomething.foo:            undefined
doSomething.prototype.prop: undefined
doSomething.prototype.foo:  bar

 

function f(){      //함수 속성 a,b 갖는다
   this.a =[];
   this.b =[];
   }
f.prototype = {          //함수 f의 프로토타입에 속성a에 값을 추가
    adda: function(v){ 
             this.a.push(v); 
             }
    }
};
var g = new f();    //함수 f의 오브젝트 생성 똑같이 a,b속성을 가지는 객체가 된다.
                            즉  ,  g.prototype = f.prototype

상속과 프로토타입 - JavaScript | MDN (mozilla.org)  

http://dannyzhang.run/2017/04/06/Advanced-JavaScript-Objects-and-Functions/

자세한 공부를 위한 링크!