본문 바로가기

Software/JavaScript & JQuery

[JavaScript] - Prototype 과 Constructor !!!

http://itux.tistory.com/28 님의 글에서 정보를 제공받았습니다.

굉장이 혼란스러운 개념이다...
처음 접했을때 이게 뭐지? 

아직도 감이 안온다.
그래도 한번 정리해 보자!

개념을 설명하기에 앞서.. javascript에서 사용하는 용어가 정확히 무엇을 정의하는지부터 살펴보자.
용어의 정의 ECMA-262 표준을 이용하였다.

primitive value : type이 Boolean, Number, String ( Undefined, Null ) 인 값들. Undefined, Null은 일반적인 자료형이 아닌 다소 특이한 유형이므로 가로를 적용하였다.

object : An object is a collection of properties and has a single prototype object. The prototype may be the null value
속성의 집합이면서 prototype이라는 객체를 가지고 있는 것을 object라고 한다. prototype객체는 null 일 수 있다.

constructor : Function object that creates and initialises objects
객체를 생성하고 초기화하는 function 객체를 constructor라고 한다.
constructor의 prototype 속성의 값은 prototype 객체이다.

prototype : object that provides shared properties for other objects. 
다른 객체에게 공유되는 속성을 제공하는 객체 


코드를 통해 중요한 정보 확인해보자.
   -----------------------------------------------------
function foo() {
    //do something!!!!
}
 
var f1 = new foo();
 
foo.prototype.x = "hello";
 
alert(f1.constructor);  //function foo(){}
alert(f1.prototype);    //undefined
alert(foo.x);       //undefined
alert(f1.x);        //hello
 
 if (f1.constructor === foo) {
    alert("f1.constructor === foo");
 }
----------------------------------------------

처음 함수선언부 function foo(){}가 실행되면 foo라는 Function 객체가 생성된다.

var f1 = new foo(); 를 수행하면,
new라는 keyword에 의해 f1변수에 foo의 객체가 할당되어 생성된다.

이 때 생성된 f1 객체의 __proto__는 foo function객체의 prototype 속성이 가리키는
객체와 동일하다.
(__proto__ 와 prototype의 개념은 다르나 용도가 같아 보임)

그 다음 문장은 foo function 객체는 prototype이라는 속성이 존재하고,
그 prototype 객체의 x라는 속성에 "hello"라는 값을 할당한 것이다.


이제 alert문을 통해 적확하게 어떤게 어떤것을 가리키는지, 어떤식으로 사용되는지
다시한번 짚어보자.

alert(f1.constructor); 는 f1 객체의 constructor속성을 찍으라는 의미이다.
f1객체 자체에는 constructor 속성이 없으므로...(왜 없을까? : 그 이유는 위에서 설명 했다

싶이 constructor라는 속성은 prototype이 갖는 속성이다.

그리고 prototype이라는 속성은 function객체 생성시 자동적으로 할당되어 지는 속성이다.

따라서 f1객체는 prototype이라는 속성이 존재 하지 않기 때문에 당연히 constructor 속성도
없다.)

javascript에서는 f1객체의 __proto__가 가리키는 곳에서 constructor속성을 찾게 된다.

위의 이미지에서도 확인 할 수 있겠지만, __proto__는 Foo function 객체의 prototype을

의미하므로, 결론적으로는 Foo.prototype.constructor 와 동일한 의미를 지니게 되어,

function foo(){}라는 데이터가 출력된다.


단, 여기서 주의할 것은 __proto__는 javascript 코드상에서는 직접 참조할수없는 속성이다.

즉, f1.__proto__.constructor와 같은 방식으로 하면 오류가 발생한다.

여기까지만 이해해도 어느정도 prototype이라는 개념에 대해 어느정도 이해가 될것이다.


두번째 alert문장을 보자. 결과는 undefined이다. 왜 이렇게 출력되는지 이해되는가?
참고로 undefined는 해당 변수에 아무런 값이 할당되지 않았을 경우 출력되는 값이다.


alert(f1.prototype);을 그럼 한번 살펴보자.
f1객체의 prototype이라는 속성값을 출력하라고 하는데
f1 객체 자체에는 prototype속성이 없다.(__proto__ 이것 뿐이다.)

따라서 javascript에서는 f1.__proto__.prototype속성을 뒤진다.
이곳에도 없으면 f1.__proto__.__proto__.prototype 속성을 뒤지게 되고,
이곳에도 없으면 재귀적으로 계속 뒤지게 된다.

위의 그림에서 알 수 있듯이, 결국 이 연결고리(prototype chain이라고 부름)에는
prototype 속성이 없으므로 "undefined"가 출력되는 것이다.

세번째 alert(foo.x)도 두번째 alert 문장과 비슷한 이유로 "undefined"가 출력된다.
foo.x라는 속성은 존재하지 않기 때문에,
javascript에서는 foo.__proto__.x(foo.prototype.x가 아님에 주의 할것)라는 속성을 찾게 된다.

마지막으로 alert(f1.x)를 살펴보자. f1.x라는 속성이 없기 때문에,
f1.__proto__.x라는 값을 찾게 된다.
여기에 앞에서 정의된 "hello"가 있기 때문에 이번에는 "hello"를 출력하게 되는 것이다.

java나 c++에 익숙한 사람들이라면... 아마 이 개념이 엄청 낯설 것이다.
그래도 javascript를 제대로 이해하려면 prototype이라는 것의 의미를 정확하게 짚고 넘어가야 할
필요가 있으니 꼭, 다시 되짚어보자.

반응형

'Software > JavaScript & JQuery' 카테고리의 다른 글

[JavaScript] - ICE Breaking(2)  (0) 2016.08.30
[JavaScript] - ICE Breaking(1)  (0) 2016.08.17
[jQuery] - jQuery Mobile  (0) 2012.01.18
[DOM] - Div 와 Span  (0) 2012.01.11
[JavaScript] - JavaScript 와 DOM과의 관계  (0) 2012.01.05