プロトタイプは通常のオブジェクトです。オブジェクトがプロトタイプを継承する場合、オブジェクトはプロトタイプのプロパティをコピーするだけでなく、プロトタイプへの参照を格納します。
そうです、オブジェクトのプロトタイプは、プロトタイプチェーンを通じて参照される単なる別のオブジェクトです。
2つのスニペットの違いは、のプロトタイプを変更し__proto__
ていることfood
です。2番目の例では、から継承する新しいオブジェクトを割り当てるだけです。これが、元のオブジェクトがその割り当てによって失われるため、に解決されるmore_food
理由です。food.fruit
undefined
food
Object.createは正確に何をしていますか?
Object.create
最初の引数として渡されたオブジェクトから継承する新しいオブジェクトを構築します(オブジェクトまたはのいずれかのみにすることができますnull
)。
変数foodには、プロトタイプmore_foodへの参照が割り当てられていますか、それともObject.createはオブジェクトmore_foodのコピーを返すだけですか?
food
変数は、から継承する新しいオブジェクトを保持しますmore_food
。この操作ではコピーは行われません。
例えば:
var food = {fruit:"apple"};
var more_food = Object.create(food, {
vegetable: { value: "celery" }
});
more_food.fruit; // "apple"
more_food.vegetable; // "celery"
上記の例では、more_food
から継承しfood
ます。つまり、food
のプロトタイプですmore_food
。このプロトタイプ参照は、と呼ばれる内部プロパティに格納されます[[Prototype]]
。の2番目の引数をObject.create
使用すると、この新しいオブジェクトのプロパティを初期化できます。
コピーはありません。上記の例の単純な委任more_food.fruit
は、プロトタイプチェーンを介してアクセスできます。プロパティの検索プロセスは非常に簡単です。プロパティがオブジェクトで見つからない場合は、オブジェクトのプロトタイプで再度検索(委任!)されます。プロトタイプが見つかったオブジェクトが見つかるまでnull
(のようにObject.prototype
)再帰的に。
したがって、more_food.fruit
継承されたプロパティは次のとおりです。
more_food.hasOwnProperty('fruit'); // false, inherited
'fruit' in more_food; // true
vegetable
の独自のプロパティですがmore_food
:
more_food.hasOwnProperty('vegetable'); // true
上記の例は、グラフィカルに次のようになります。
+ ---------------------+[[プロトタイプ]]+--------------- +
| more_food | + ---------------> | 食べ物|
| --------------------- | | --------------- |
| 野菜:「セロリ」| | フルーツ:「リンゴ|
+ --------------------- + + --------------- +
Object.createがコピーを作成しているだけの場合、変数foodにmore_foodへの参照がない場合、プロトタイプチェーンはどのように機能しますか?
Object.create
オブジェクトのコピーを作成するのではなく、作成時に新しいオブジェクトのプロトタイプを設定するだけです。
__proto__
これは非標準の機能であり、将来的に実装から削除される予定であり、Mozillaドキュメントで非推奨としてすでにリストされていることを覚えておいてください。これが主な理由であり、言語に方法がない可能性がある理由でもあります。プロトタイプチェーンを変更できるようにすると、VMとJITのレベルで最適化とセキュリティの問題が発生します。__proto__