본문 바로가기

Web/Javascript

__proto__ 와 prototype에 대해..

오브젝트의 특징으로서

모든 오브젝트는 __proto__ 프로퍼티를 가진다.
그리고
모든 함수오브젝트는 prototype 프로퍼티를 가진다.

또 new 에 의해서 작성된 오브젝트의
__proto__ 프로퍼티에는 그 함수의 prototype이 설정되어
__proto__ 는 constructor프로퍼티를 가진다.
이 constructor 프로퍼티는 new 한 함수 오브젝트를 가리키고 있다..

이게 뭔 소리여 -_- 전에 했던 말과 다르다..
분명한것은 익스플로어에서는 없어졌다는 것이다...

하지만 계속 봐보자.
아래와 같은함수 Parent.Child가 있다.

function Parent() { }

function Child() { }
Child.prototype = new Parent();

단순한 계승관계이다.
그리고 Child 클래스로부터 오브젝트를 작성한다.

var myobj = new Child();

이렇게 해서 4개의 오브젝트가 있다.
  • Parent 함수 오브젝트
  • Parent를 new한 오브젝트
  • Child 함수 오브젝트
  • Child를 new 한 오브젝트
오브젝트를 ()로 감싸고
함수 오브젝트를 [ ]로 감싸서
위의 코드의 관계를 써본다.

(?).constructor = [Parent]
[Parent].prototype = (?)
(Parent).__proto__ = [Parent].prototype = (?)

[Child].prototype = (Parent)
(Child).__proto__ = [Child].prototype = (Parent)
(Child).__proto__.constructor = [Child]
(Child).constructor = 'undefined'

이런 관계가 성립된다.
(?) 은 아직 정의되지 않은 예를 든 표현이다.
함수오브젝트에는 new 연산자로 오브젝트가 만들어지지 않았으니 임의의 오브젝트를 명시한것이다.

사용자 삽입 이미지

prototype 체인이란,
프로퍼티의 참조시에 연관된 것을 말한다.
위의 경우 (Child)의 프로퍼티hoge는

1. this.hoge
2. (Child).__proto__.hoge = (Parent)hoge = [Child].prototype.hoge
3. (Child).__ptoto__.__proto__.hoge = (Parent).__proto__.hoge = (?).hoge
의 순서에 의해 찾아가게 된다. (= 는 수학에서의 같다라는 표시이다.)
(?)는 다중계승하고 있는 경우, 똑같이 __proto__로 연결되어서 간다.
계승이 끝난 시점에서 (?)는 null 이 된다.
프로퍼티의 팜조시, (?)가 null의 경우 그 프로퍼티는 undefined 값이 된다.

아.. 복잡 -_-..
다시 코드를 보자

var Parent = function() { }
var Child = function() {}
Child.prototype = new Parent();

alert(new Child().__proto__ === Child.prototype);         // true

역시 생각대로 값이 나온다.

다음에는 prototype 에 null 값을 넣어보았다.

Child.prototype = null;

alert(Child.prototype === null);    // true
alert(new Child().__proto__ === null);     // false
alert(new Child().__proto__ === Child.prototype);     //false

엥?
왜 저렇게 되었을까?

__proto__ 에는 null이 들어가 체인이 연결되지 않는 것이라고 생각했지만
2번째와 3번째의 결과로부터 null 은 아닌것 같다.
아무래도 생성자에서 prototype으로부터 __proto__에 값을 설정할때
prototype이 오브젝트가 아니면 Object.prototype을 설정하는것 같다.

그래서 다시 코드를 쳐보자.

alert(new Child().__proto__ === Object.prototype);    //true


오~ 역시 그렇게 되는군..

결론은 오브젝트를 상속받는다는 것이지.