-
프로토타입 (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부에서는 생성자 , 상속 , 클래스와 위임지향의 디자인 패턴 등에 대하여 알아보자.
(끝)
'Javascript' 카테고리의 다른 글
ES6 2부 - Arrow function, 객체 리터럴 , 2진수, 8진수 (0) 2016.08.18 ES6 1부 - let , const , 배열과 객체 (1) 2016.08.17 Angular.js 의 작동원리 (1) 2016.06.27 javascript 에서 for loop 를 사용할 때 (0) 2016.06.26 클로저 (closure) (3) 2016.05.30