2013-06-30 7 views
7

obj.constructor.prototypeを使用してオブジェクトのプロトタイプにアクセスできる場合は、obj.constructor.prototype.constructor.prototypeを使用してプロトタイプチェーンをトラバースすることができないため、Object.getPrototypeOfを使用する必要がありますか?constructor.prototypeを使用したプロトタイプチェーンのトラバース

function MyConstructor() 
{ 
    this.prop = 1; 
} 

var o = new MyConstructor(); 

console.log(o.constructor.prototype) // MyConstructor 

console.log(o.constructor.prototype.constructor.prototype) // MyConstructor? 

それは(クロームコンソールで)function() { [native code] }あるMyConstructorのプロトタイプを返すべきではないでしょうか。

答えて

7

すべてのコンストラクタは、グローバルFunctionオブジェクトのインスタンスである:

function Foo(){ this.x = 1 }; // Dummy constructor function 

console.log(Foo instanceof Function) // => true; Foo is an instance of global Function constructor 

すべてのプロトタイプは、グローバルObjectオブジェクトのインスタンスである:コンストラクタFooが定義されている場合は

console.log(Foo.prototype instanceof Object); // => true 

、それが自動的にFoo.prototypeを持っています上記のように、それ自体が "空の"オブジェクトと考えることができるオブジェクトは、グローバルObjectオブジェクトから継承します。言い換えれば、Foo.prototypeのプロトタイプはObject.prototypeです:

function Foo(){ this.x = 1 }; // Dummy constructor function 

console.log(Foo.prototype); // Foo (object); already exists 

console.log(Object.getPrototypeOf(Foo.prototype) === Object.prototype); // => true 

Foo.prototypeが空白のオブジェクトであるので、1はそのコンストラクタがグローバルObjectコンストラクタ関数であることを期待する:

function Foo(){ this.x = 1 }; // Dummy constructor function 

console.log(Foo.prototype.constructor) // => function Foo() { this.x = 1; } ?? 

console.log(Foo.prototype.constructor === Object.prototype.constructor); // => false 

しかし、この「空白」オブジェクトには明示的な自己参照constructorプロパティがあり、これはfunction Foo(){ this.x = 1 }を指し、期待しているデフォルトのコンストラクタプロパティを上書きまたはマスクします。

function Foo(){ this.x = 1 }; // Dummy constructor function 

delete Foo.prototype.constructor; // Delete explicit constructor property 

console.log(Foo.prototype.constructor) // => function Object() { [native code] } 

console.log(Foo.prototype.constructor === Object.prototype.constructor); // => true 

したがって、obj.constructor.prototypeを再帰的に使用してプロトタイプチェーンをトラバースすることはできず、Object.getPrototypeOf()メソッドに依存する必要があります。

ここは素晴らしいvisual referenceです。

2

私はあなたが一般的にできないオブジェクト

のプロトタイプにアクセスするためにobj.constructor.prototype使用することができます。このアプローチの仕組みを考えてみましょう。

var proto = MyConstructor.prototype; 
// has an (nonenumberable) property "constructor" 
proto.hasOwnProperty("constructor"); // `true` 
// that points [back] to 
proto.constructor; // `function MyConstructor() {…}` 

ご覧のとおり、これは循環的なプロパティ構造です。あなたは

var o = new MyConstructor(); 
// and access 
o.constructor; // `function MyConstructor() {…}` 
// then it yields the value that is inherited from `proto` 
// as `o` doesn't have that property itself: 
o.hasOwnProperty("constructor"); // `false` 

を行うが、それが唯一の彼らのプロトタイプオブジェクトから constructorプロパティを継承し、 oのようなオブジェクトのために働くとき、それは何かがプロトタイプオブジェクトを指すとの有益な価値を有しています。考えてください

var o = {}; 
o.constructor = {prototype: o}; 

おっと。 o.constructor.prototypeにアクセスすると、ここにoという結果が得られます。これは他の無意味な値であった可能性があります。構造は実際にはMyConstructor.prototypeで上記と同じです。proto.constructor.prototype.constructor.prototype[.constructor.prototype…]にアクセスすると、proto以外は取得できません。

は、なぜ私はプロトタイプチェーンを横断するobj.constructor.prototype.constructor.prototypeを使用してObject.getPrototypeOfを使用する必要はありませんか?

あなたが MyConstructor.prototypeような円形の構造の中に閉じ込めているので

は)constructorプロパティ自体とはObject.prototypeから継承されないことがあります。本当に次のオブジェクトを真のプロトタイプチェーンにするには、Object.getPrototypeOfを使用する必要があります。

var o = new MyConstructor(); 
console.log(o.constructor.prototype) // MyConstructor 

それは実際にMyConstructor.prototypeされている必要があります。 Chromeコンソールでは、名前のないオブジェクトに便利なタイトルを表示することが混乱することがあります。必ずしも正しいとは限りません。

プロトタイプを取得した場合、Object.prototypeが得られます。MyConstructor関数のプロトタイプを取得した場合は、Function.prototypeになります。後者をMyConstructor.constructor.prototypeでやり直すことができます...