[Part3] Ch5. Prototype
5.1 [[Prototype]]
- 객체는
[[Prototype]]이라는 내부 프로퍼티로 다른 객체를 참조하는 링크를 가진다. - 객체를 생성할 때 이 링크가 설정되며, 해당 객체에서 프로퍼티를 찾을 수 없을 때 이 링크를 따라 탐색된다.
var anotherObject = {
a: 2
};
var myObject = Object.create(anotherObject);
console.log(myObject.a); // 2
for...in & in 연산자
for (var k in myObject) {
console.log(`${k} 를 발견`);
}
"a" in myObject; // true
5.1.1 Object.prototype
[[Prototype]]체인의 최상단은Object.prototype이다.- 모든 객체는
Object.prototype을 상속한다.
5.1.2 프로퍼티 세팅과 가려짐 (Shadowing)
myObject.foo = "bar";
foo가 현재 객체에 없으면[[Prototype]]을 탐색- 상위에서
foo가 있고:- writable: 가려짐 발생
- non-writable: strict 모드에서는 에러
- setter: setter 호출 (가려짐 아님)
var anotherObject = {
a: 2
};
var myObject = Object.create(anotherObject);
myObject.a++; // 암시적 가려짐
console.log(anotherObject.a); // 2
console.log(myObject.a); // 3
myObject는a를 갖지 않았지만,a++수행 시 새로a를 생성하며 가림Object.defineProperty()로 직접 정의 가능
→ 가려짐은 명시적 위임이 필요한 경우 문제를 야기할 수 있으며, 작동 위임(6장)으로 대체할 수 있다.
5.2 클래스
자바스크립트에서 클래스는 존재하지 않지만, 이를 흉내내는 방식이 있다.
5.2.1 클래스 함수
function Foo() {}
Foo.prototype; // {}
var a = new Foo();
Object.getPrototypeOf(a) === Foo.prototype; // true
new를 통해Foo.prototype과a의[[Prototype]]이 연결된다.
→ 클래스는 복사 기반이 아니라 링크 기반 상속
차등 상속
- 객체 간 차이를 기반으로 새로운 객체를 구성하는 방식
- 중복보다 필요한 차이만 기술
5.2.2 생성자
function Foo() {
// ...
}
var a = new Foo();
a.constructor === Foo; // true
new는 함수 실행에 객체 생성 로직을 추가한 연산자NothingSpecial()같은 일반 함수도new로 호출 시 객체 생성
function NothingSpecial() {
console.log('');
}
var a = new NothingSpecial(); // a: {}
→ 생성자라는 표현은 문법적으로 부정확할 수 있다
5.2.3 체계 예시
function Foo(name) {
this.name = name;
}
Foo.prototype.myName = function () {
return this.name;
};
var a = new Foo("a");
var b = new Foo("b");
console.log(a.myName()); // 'a'
console.log(b.myName()); // 'b'
a,b는 각각Foo로부터 생성된 인스턴스myName메서드는Foo.prototype에 존재
→ 클래스지향의 꼼수이며 진정한 객체 연결(OLOO)은 이후 장에서 다룬다