ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 프로토타입 (Prototype) 1부
    Javascript 2016. 6. 13. 23:05


    이번엔 Closure 와 함께 Javascript 의 또 다른 중요 특성인  Prototype  에 대하여 알아보자. 

    명세에 따르면 자바스크립트 객체는  Prototype  이라는 내부 속성이 있고 이는 다른 객체를 참조하는 단순

    레퍼런스로 사용한다. 


     var myObject = {
      a: 2
    }
    
    myObject.a;  //2
    


    위 코드에서 myobject.a 가 호출 될 때 GET 이 호출된다. GET 은 기본적으로 그 객체 자체에 해당 속성이 

    존재하는지 찾아보고 존재하면 그 속성을 사용한다.

    하지만 myobject에 a란 속성이 없으면 다음 관심사는 이 객체의  prototype  링크를 찾아가며 수색을 한다.



     
    var anotherProject = {
         a : 2
    };
    
    var myObject = Object.create ( anotherObject );
    myObject.a; //2
    


    위 코드의 수색과정을 알아보자. 


    Object.create 는 특정객체의  Prototype  링크를 가진 객체를 생성한다.

    순서를 생각해보자.

    먼저 myObject 객체가 생성되고 myObject의 prototype 역시 생성되었다. 

    거기에 anotherObject 의  Prototype  링크를 붙였다. 

    이제 myObject.a 를 호출하면 먼저 myObject 의 Prototype 을 수색하고 여기서 찾지 못하였기에 링크된 

    anotherObject 의 prototype 를 수색한다.  만약 여기서 값을 찾지 못했다면 prototype 체인을 따라서 계속

    수색하며 마지막으로 object.prototype 즉 모든 prototype의 최상위 객체 를 수색하게 된다.

    수색은 일치하는 값을 찾던지, prototype 체인이 끝날때 까지 수색하며 원하는 값을 찾지 못하면 undefined 를 

    반환하게 된다. 


    이번엔 shadowing 에 대하여 알아보자. 

    다음 코드를 보자.

    myObject.foo = "bar";
    
    


    위 코드는 myObject 객체의 foo 라는 속성을 "bar" 로 바꾸는 코드이다. 

    이 코드를 실행할 때 순서는 먼저 foo 가 myObject 에 있는 속성인지 연결 되어 있는 모든 prototype 을 순회하기 

    시작하고, 해당 속성을 찾으면 변경하고 , 만약 발견되지 않으면 그 때 foo 라는 속성을 추가하고 주어진 값을 

    할당한다. 


    하지만 여기서 만약 prototype 순회 중 myObject 에도 foo 가 있고 , myObject에 연결된 상위 prototype 에도 

    foo 가 존재한다면 어떻게 될까? 


    이때는 myObject 의 foo만 바뀌고, 상위 prototype 의 속성은 가려진다. 이를 shadowing 이라고 한다.

    prototype 을 순회 할 때 하위 객체부터 검색을 하기 때문에 이 같은 상황이 벌어진다. 

    다음 코드를 보면 나도 모르게 shadowing 이 발생하는 상황을 볼 수 있다. 


    var anotherObject = {
       a : 2
    };
    
    var myObject = Object.create( anotherObject );
    
    anotherObject.a;    //2
    myObject.a;    //2
    
    anotherObject.hasOwnProperty( "a" );  //true
    myObject.hasOwnProperty( "a" );   // false
    
    myObject.a++;     // shadowing 발생 !!!
    anotherObject.a;  //2
    
    myObject.a;    //3
    myObject.hasOwnProperty( "a" );  // true
    
    
    


    겉으로 보기엔 myObject.a++ 이 anotherObject.a 속성을 찾아 1만큼 값을 증가시킬 것 같지만, ++ 연산자는

    결국 myObject.a = myObject.a + 1 을 의미한다. 따라서 Prototype을 경유하여 GET 을 먼저 찾고  ,

    anotherObject.a 에서 현재 값 2를 얻은 뒤 1만큼 증가시키고, 그 결과 값 3을 다시 PUT 으로 myObject.a 에 

    새로운 shadowing 속성 a 를 생성한 뒤에 할당한다. 


    많이 볼 수 없는 상황이지만 이런식으로 위임을 이용해서 속성을 수정할 땐 조심해야 한다.

    anotherObject.a 를 1만큼 증가시킬려면 anotherObject.a++; 만이 정답이 된다. 


    prototype 에 대하여 간략하게 알아보았는데 , 아직 알아야 할 것이 무궁무진하다. 

    2부에서는 생성자 , 상속 , 클래스와 위임지향의 디자인 패턴 등에 대하여 알아보자. 


    (끝)


    댓글