JavaScript はプロトタイプ継承が広く使用されている唯一の言語であるため、2 つの継承方法の違いを理解するには時間がかかります。
最初の大きな違いは、JavaScript が継承にプロトタイプ チェーンを使用することです。
function Foo() { this.value = 42; } Foo.prototype = { method: function() {} }; function Bar() {}
Bar のプロトタイプを Foo のオブジェクト インスタンスに設定します:
Bar.prototype = new Foo(); Bar.prototype.foo = 'Hello World';
Bar のコンストラクターがそれ自体であることを確認し、新しい Bar オブジェクト インスタンスを作成します。
Bar.prototype.constructor = Bar; var test = new Bar();
プロトタイプチェーン全体の構成を見てみましょう:
test [instance of Bar] Bar.prototype [instance of Foo] { foo: 'Hello World' } Foo.prototype { method: ... } Object.prototype { toString: ... /* etc. */ }
上記の例では、オブジェクト テストは Bar.prototype と Foo.prototype の両方を継承します。したがって、Foo で定義された関数メソッドにアクセスできます。もちろん、プロパティ値にアクセスすることもできます。 new Bar() が呼び出されるとき、新しい Foo インスタンスは作成されませんが、そのプロトタイプ オブジェクトに付属する Foo インスタンスが再利用されることに注意してください。同様に、すべての Bar インスタンスは同じ value プロパティを共有します。例を挙げてみましょう:
test1 = new Bar(); test2 = new Bar(); Bar.prototype.value = 41; test1.value //41 test2.value//41
プロトタイプチェーン検索メカニズム
オブジェクトのプロパティにアクセスすると、JavaScript はオブジェクト自体から開始して、対応するプロパティが見つかるまでプロトタイプ チェーン全体を走査します。この時点でプロトタイプ チェーンの先頭 (上記の例では Object.prototype) に到達しても、検索対象のプロパティがまだ見つからない場合、JavaScript は未定義の値を返します。
プロトタイプ オブジェクトのプロパティ
プロトタイプ オブジェクトのプロパティは Javascript によってプロトタイプ チェーンを構築するために使用されますが、値を割り当てることもできます。ただし、元の値をプロトタイプにコピーすることは無効です。たとえば、
function Foo() {} Foo.prototype = 1; // no effect
ここでは、この記事からの余談で、元の値が何であるかを紹介します。
Javascriptでは、変数にはプリミティブ値と参照値の2種類の値を格納できます。
1.プリミティブ値:
プリミティブ値は固定の単純な値であり、スタックに格納される単純なデータセグメントです。つまり、その値は変数がアクセスされる場所に直接格納されます。
5 つのプリミティブ型があります: Unknown、Null、Boolean、Number、および String です。
2.参考値:
参照値はヒープに格納される比較的大きなオブジェクトです。つまり、変数に格納される値は、オブジェクトが格納されているメモリを指すポインタです。すべての参照型は Object から統合されます。
プロトタイプチェーンのパフォーマンスの問題
検索する必要があるプロパティがプロトタイプ チェーンの上端にある場合、検索プロセスは間違いなくパフォーマンスに悪影響を及ぼします。これは、パフォーマンス要件が必然的に厳しいシナリオでは考慮すべき重要な要素になります。さらに、存在しないプロパティを見つけようとすると、プロトタイプ チェーン全体を横断することになります。
同様に、オブジェクトのプロパティをトラバースするときは、プロトタイプ チェーン上のすべてのプロパティにアクセスします。
概要
プロトタイプの継承を理解することは、より複雑な Javascript コードを記述するための前提条件です。同時に、コード内のプロトタイプ チェーンの高さに注意してください。パフォーマンスのボトルネックに直面した場合に、プロトタイプ チェーンを分割する方法を学びます。さらに、プロトタイプ オブジェクトのプロトタイプとプロトタイプ __proto__ は区別される必要があります。ここではプロトタイプ オブジェクトのプロトタイプについて主に説明し、プロトタイプ __proto__ に関する問題については詳しく説明しません。