5

私はこの機能を持っています:

function Foo(){}

この写真によると:

ここに画像の説明を入力

>> Foo.prototype   ->    Foo {}

ここに画像の説明を入力

だから私が書くと:

Foo.prototype.constructor

今 -オブジェクトを作成 したコンストラクター関数を参照します。Foo{}function Foo(){}

ここに画像の説明を入力

大丈夫。

では、問題はどこにあるのでしょうか?

Foo.prototypeオブジェクトインスタンスです -->Foo {}

そして、のコンストラクター関数はFoo{}誰ですか?

それはfunction Foo(){}

ここで黄色で見ることができます:

ここに画像の説明を入力

わかった

しかし、私はここで次のように言われました:

ここに画像の説明を入力

したがって、 では なくのFoo.prototype.__proto__を参照する必要があります。prototypefunction Foo(){}Object.prototype

私がそれを翻訳すると:

    __proto__               is the                   ctor's                        prototype
    _________________________________________________________________________________________
  Foo.prototype.__proto__     is the               function Foo(){}               Foo.prototype

しかし、これは間違っています

そして、私はおそらく間違っています:

ここに画像の説明を入力

何が欠けていますか?

4

1 に答える 1

4

注:まず、__proto__非標準Object.getPrototypeOfです。短くするために を使用します。私は怠け者なのでprototype、この回答ではかなりの回数使用しました

私があなたを正しく読んでいるなら、あなたはあなたの最初の仮定に投げ出されています:

Foo.prototype -> Foo{}

(コンストラクターである)のプロトタイプFooは、定義上、 のインスタンスですFoo。ただし、コンストラクターは関数であり、コンストラクターは特定のインスタンスのオブジェクトを返すため、プロトタイプはObjectどちらの方法でも拡張されます。
私はプロトタイプの慣性を従来の OOP と比較するのは好きではありませんが、次のように考えてください。

プロトタイプは一種のFoo可変クラス定義であり (メソッドとプロパティを随時追加できます)、コンストラクターはこのプロトタイプを拡張するオブジェクトを作成、インスタンス レベルでプロパティ/メソッドの別のレイヤーを追加します。
したがってFoo.prototype instanceof Foo、真です。しかし、Fooオブジェクトであること:

Object.getPrototypeOf(Foo.prototype) === Object.prototype

本当です。同じように

Object.getPrototypeOf(Array.prototype) === Object.prototype.

これを JS (プロトタイプ) 言語に翻訳すると、次のようになります。

JS が作成する関数オブジェクトごとに、このオブジェクトにprototypeプロパティが割り当てられます。プロパティはのprototypeインスタンスですがObject、1 つの特別なプロパティがあります。
オブジェクトのプロパティまたはメソッドにアクセスしようとして、JS がインスタンス レベルで定義されたこのプロパティを見つけられない場合、JS はプロトタイプ プロパティの名前を解決しようとします。

instance.nonExistantProperty;
//js scans instance variable, doesn't find property:
instance.prototype.nonExistantProperty
//js uses prototype, if not found:
instance.prototype.prototype.nonExistantProperty
//all the way up to Object.prototype, which does not have a prototype, so here an exception is raised (TypeError is thrown)

ここに私の古い投稿の 1 つからコピーしたこのルックアップの短い概略図を示します。一見の価値があるかもしれません。下部にあるリンクされた回答も確認してください。この問題についてさらに詳しく説明しています。

[      F.divide      ]<=========================================================\ \
F[divide] ===> JS checks instance for property divide                           | |
 /\ ||                                                                          | |
 || || --> property found @instance, return value-------------------------------| |
 || ||                                                                          | |
 || ===========> Function.prototype.divide could not be found, check prototype  | |
 ||      ||                                                                     | |
 ||      ||--> property found @Function.prototype, return-----------------------| |
 ||      ||                                                                     | |
 ||      ==========> Object.prototype.divide: not found check prototype?        | |
 ||          ||                                                                 | |
 ||          ||--> property found @Object.prototype, return---------------------|_|
 ||          ||                                                                 |=|
 ||          =======>prototype is null, return "undefined.divide"~~~~~~~~~~~~~~~|X|
 ||                                                                             \ /
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< TypeError can't read property 'x' of undefined

基本的にはそれだけです。

さて、おそらくあなたも、なぜ関数をFoo.prototype.constructor参照するのかについて少し挫折しているでしょう。 繰り返しますが、これは非常に簡単です。各インスタンスには、処理しているオブジェクトのタイプを決定するために必要なすべての情報が含まれていることが期待されるからです。Foo

function Foo{}
var inst = new Foo();
console.log(inst.constructor);//references the constructor function

によって返されるすべてのインスタンスは、すべてのプロパティと (オプションで) インスタンス レベルの一部のプロパティFooも参照するオブジェクトを返すことに注意してください。prototype

では、なぜわざわざそのようなインスタンスを作成するのでしょうか? 繰り返しますが、これは完全に単純です: インスタンスを変更しても、プロトタイプは変更されません:

console.log(Foo.prototype.constructor === inst.constructor);//true
inst.constructor = function(){};//override constructor property
console.log(Foo.prototype.constructor === inst.constructor);//false, prototype did not change
于 2013-10-30T08:49:18.823 に答える