MDN을 보면 모든 객체들이 메소드와 속성들을 상속 받기위한 템플릿으로 프로토타입 객체를 가진다는 의미라 한다. (뭔 소리인지 하나도 모르겠다.) 이어지는 말을 보면 이해가 쉬운데
프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속 받을 수도 있고 그 상위 프로토타입 객체도 마찬가지다!
이를 프로토타입 체인 이라 부르며 다른 객체에 정의된 메소드와 속성을 한 객체에서 사용할 수 있도록 한다.
이제 머리속에 그림이 조금 그려진다. 아래 내용을 보면 그림이 조금 더 확실해 지는데
상속되는 속성과 메소드들은 각 객체가 아니라 객체의 생성자의
prototype이라는 속성에 정의되어 있다.
JS는 객체 인스턴스와 프로토타입 간에 연결이 구성되며
이 연결을 따라 프로토타입 체인을 타고 올라가며 속성과 메소드를 탐색합니다.
이런 특성 덕분에 다른 객체에 정의된 메소드와 속성을 한 객체에서 사용할 수 있다! 예를 들어보자!
이런 생성자 함수를 정의하고 인스턴스를 만들어 'portable1'을 치면 브라우저는 아래처럼 해당 객체의 맴버 이름을 자동 완성 팝업으로 보여준다!
portable1의 프로토타입 객체인 Portable()에 정의된 맴버들을 볼 수 있고 Portable()의 프로토타입 객체인 Object에 정의된 다른 맴버도 볼 수 있다.
이는 프로토 타입 체인이 동작 하는 증거이다!
그럼 Object에 정의되어 있는 메소드를 portable1에서 호출하면 어떻게 될까?
어머어머 이게 무슨일이람!
위에 처럼 실행되는 이유는
- 브라우저가 우선 portable1 객체가 valueOf() 메소드를 가지고 있는지 체크한다. 없다면
- portable1의 프로토타입 객체(Portable() 생성자의 프로토타입)에 valueOf() 메소드가 있는지 체크한다. 없다면
- Portable() 생성자의 프로토타입 객체의 프로토타입 객체(Object() 생성자의 프로토타입)가 valueOf() 메소드를 가지고 있는지 체크한다. 여기에 있으니 호출하며 끝난다!
여기서 더 알아봐야 하는건 Object.prototype. 속성이다. prototype 속성도 하나의 객체이고 프로토타입 체인을 통해 상속하고자 하는 속성과 메소드를 담아두는 버킷으로 주로 사용되는 객체이다.
만약 잘 모르는데 구글링을 하다 이 글을 읽는다면 무슨 말인지 찾아보길 바란다!
3시간 전 내 얘기
배열 또한 원리가 동일하다. 배열은 Array 클래스의 인스턴스이고, 프로토타입에는 다양한 베서드가 존재한다.
Array -- .prototype -- -> Array.prototype -- new Array();instantiation -> arr -- .__ proto__ -> Array.prototype -- .constructor -> Array
이처럼 동일하다는걸 알 수 있다! ( __proto__
는 느린 작업이기 때문에 쓰지 않기로 하자)