용어에 있어서 MDN에 따르면
ECMAScript 표준은 someObject.[[Prototype]]을 객체 someObject의 프로토타입을 지시하도록 명시하였다. ECMAScript 2015부터 [[Prototype]]에 조상 Object.getPrototypeOf()과 Object.setPrototypeOf()을 이용하여 접근하기 때문이다. 이것은 자바스크립트의 표준은 아니나 많은 브라우저에 구현되어 사실상의 표준이 된 속성
__proto__
과 동일하다.
라고 되어있고 이는 표준에서는 [[Prototype]]이라 쓰지만 브라우저상에서는 __proto__
로 사용한다는 것 같은데 일단 크롬에서는 __proto__
로 확인이 가능하기에 이렇게 사용하겠습니다.
웹 스터디를 진행하면서 이번에 과제에서 프로토타입이라는것을 사용하게 되었다. 자바스크립트로 이것저것 해보았지만 처음들은 단어다. 어쩜이렇게 파도파도 모르는것만 나오는지 신기하다. 하지만 문제는 해결해야했기에 이번에도 MDN과 javascript.info의 힘을 빌려 prototype이란 어떤것인지 알아봤다.
__proto__
자바스크립트에서 모든 함수에는 prototype
이라는 특수한 속성이 있다. 함수를 선언하면, 그 함수의 prototype이 생기는것이다. 그리고 어떤 변수에 이 함수를 new 키워드로 호출하게 되면 그 변수의 __proto__
는 해당 함수의 prototype을 가리키게 된다.
function A(){}
이렇게 함수를 선언하면 그 함수가 선언될 때는 사실 prototype이 함께 생기는것이다. 그리고 이 A를 사용해 a라는 변수에 new A()로 할당하게 되면. a에는 __proto__
라는 숨겨진 속성이 있는데,
let a = new A(); a.__proto__;
그리고
a.__proto__
를 살펴보면
-> constructor : f A()
->__proto__
: Object
라고 나온다.
a의 __proto__
는 A의 prototype을 참조하여 new를 호출할 때 만들어진다. a가 아니라 다른 변수라도 new A()를 통해 생성했다면 __proto__
는 A의 prototype을 가리키게 되는것이다.
b = new A();
c = new A();
A.prototype.type = 'abc';
a.type; // 'abc'
b.type; // 'abc'
c.type; // 'abc'
A의 prototype을 자세히 보면,
a의 __proto__
는 A의 prototype을 가리키고, 이 A의 prototype에 있는 __proto__
는 Object를 가리키고 있다.
A뿐만 아니라 모든 객체의 prototype을 타고 올라가면 그 끝에는 Object.prototype이 있다.
이렇게 계속 연결되어있는 프로토타입을 프로토타입 체인 이라고 하는데 이것을 이용해 상속 비슷하게 사용 할 수 있다.
우리가 만약 a에 없는 어떤 속성을 사용하려고 한다면, 먼저 a내부에서 찾아보고는 없다면 a의 __proto__
를 찾아간다. 실제 a에 없더라도 상속받은 프로토타입에 있다면 사용할 수 있는것이다. 그리고 만약 거기에도 없다면 계속해서 __proto__
를 타고 올라간다. 결국 Object.prototype까지 가서도 찾지 못한다면 없다고 판단하고 undefined가 될 것이다.
이 때문에 우리가 따로 만들지 않았어도 객체에서 toString, valueOf등 Object의 기능을 사용 할 수 있다.
이해한대로 적어보긴 했으나 너무 개요만 있는것 같아 나중에 좀더 공부해서 추가로 작성해야겠다. 프로토타입체인의 사용과 Class 키워드와 일반 함수로 생성한 차이점 등 궁금한게 남아있다. 할게 많은데 좀처럼 줄어들지않는다. 열심히 해야겠다.
그리고 MDN과 jsinfo 말고도 이 블로그에도 잘 정리가 되어있었습니다.
https://velog.io/@adam2/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Prototype-%EC%99%84%EB%B2%BD-%EC%A0%95%EB%A6%AC