読者です 読者をやめる 読者になる 読者になる

Object.creat()とプロトタイプチェーン

JavaScriptの言語仕様(ES5)

Object.creat()を使うと、[[Prototype]]を指定した上で、オブジェクトを生成できる。
リテラルで生成したオブジェクトの[[Prototype]]Object.prototypeになるが、Object.creat()を使えば、任意のオブジェクトを[[Prototype]]に設定できる。

Object.creat()の第一引数にプロトタイプオブジェクトを渡し、第二引数にプロパティディスクリプタを渡すことで、オブジェクトを生成できる。
第二引数は省略可能。

var person1 = {
    sayName: function(){ console.log(this.name); }
};
// person1のプロトタイプオブジェクトはObject.prototype
console.log(person1.__proto__ === Object.prototype);   // true

var person2 = Object.create(person1, {
    name:{
        value: 'Tom',
        writable: true,
        enumerable: true,
        configurable: true
    }
});

// person2のプロトタイプオブジェクトはperson1
console.log(person2.__proto__ === person1); // true
person2.sayName();  // Tom

プロトタイプチェーン

プロパティを読み込もうとした際、まず、オブジェクト自身がそのプロパティを持っていないか確認する。
持っていなかった場合、そのオブジェクトの[[Prototype]]が参照しているプロトタイプオブジェクトの中から、同名のプロパティがないかを検索する。
それでも見つからなかった場合、プロトタイプオブジェクトの[[Prototype]]の中を検索する。

以降、プロパティが見つかるか、[[Prototype]]nullを返すまで、このサイクルを繰り返す。
このサイクルを、プロトタイプチェーンと呼ぶ。
通常、Object.prototypenullなので、そこがプロトタイプチェーンの終端となることが多い。

var person1 = {
    sayHello: function(){ console.log('Hello'); }
};

var person2 = Object.create(person1);

person2.sayHello(); // Hello
console.log(person2.hasOwnProperty('sayHello'));   // false
console.log(person2.__proto__ === person1); // true
console.log(person1.hasOwnProperty('sayHello'));   // true
// person2のプロトタイプであるperson1がsayHelloを持っているため、実行される

console.log(person2.toString());    // [object Object]
console.log(person2.hasOwnProperty('toString'));   // false
console.log(person1.hasOwnProperty('toString'));   // false
console.log(person1.__proto__ === Object.prototype);   // true
console.log(Object.prototype.hasOwnProperty('toString')); // true
// person2のプロトタイプ(person1)のプロトタイプであるObject.prototypeがtoStringを持っているため、実行される

console.log(person2.__proto__ === person1); // true
console.log(person2.__proto__.__proto__ === Object.prototype); // true
console.log(person2.__proto__.__proto__.__proto__ === null);  // true
// Object.prototypeの[[Prototype]]はnull