7

を使用obj.constructor.prototypeしてオブジェクトのプロトタイプにアクセスできるのに、なぜ を使用obj.constructor.prototype.constructor.prototypeしてプロトタイプ チェーンをトラバースできず、 を使用しなければならないのObject.getPrototypeOfでしょうか?

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] }(Chrome コンソールにある) MyConstructor のプロトタイプを返すべきではありませんか?

4

2 に答える 2

8

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

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

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

すべてのプロトタイプはグローバルObjectオブジェクトのインスタンスです。

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

コンストラクターFooが定義されると、自動的に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であると予想されます。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()

これは素晴らしいビジュアルリファレンスです。

于 2013-06-30T21:10:25.013 に答える
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`

しかし、それはプロトタイプオブジェクトからプロパティoを継承しconstructor、プロトタイプオブジェクトを指す何かを持つ有用な値を持つようなオブジェクトに対してのみ機能します。のことを考える

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 コンソールは、名前のないオブジェクトの有用なタイトルを表示する際に混乱することがあり、常に正しいとは限りません。

プロトタイプを取得すると、yield が生成され、関数自体Object.prototypeのプロトタイプを取得すると、が生成されます。後者をもう一度実行できることに注意してください…</p> MyConstructorFunction.prototypeMyConstructor.constructor.prototype

于 2013-06-30T22:44:43.220 に答える