ホームページ >ウェブフロントエンド >jsチュートリアル >js のプロトタイプチェーンと継承について理解する
jsのプロトタイプチェーンは理解が難しい知識の部分であり、継承もプロトタイプチェーンに依存するため、プロトタイプチェーンは習得しなければならないものです。プロトタイプ チェーンについて学ぶ前に、プロトタイプを紹介する必要があります。この部分は理解することに重点を置くことをお勧めします。丸暗記はお勧めしません。
1. プロトタイプ
js の関数オブジェクトのみがプロトタイプを持ち、プロトタイプもオブジェクトです。たとえば、save 関数を作成し、typeof を通じてその型をチェックすると、戻り値は「object」となり、それが実際にオブジェクトであることを示します。
図 1 関数オブジェクト では、関数の関数にはどのような内容が含まれるのでしょうか。出力を印刷すると、プロトタイプには 2 つの部分が含まれていることがわかります。1 つは
constructor、もう 1 つは proto です。まずコンストラクターについて理解しましょう。後で proto について紹介します。
図 2 関数オブジェクトのプロトタイプ
Java を勉強したことがある人は、コンストラクターがコンストラクターを意味し、パラメーターや呼び出し元など、コンストラクターに関する情報が含まれていることを知っています。
関数オブジェクトのみがプロトタイプを持つと前に述べましたが、通常のオブジェクトにもプロトタイプはありますか?以下は例を通じて検証され、save を通じてオブジェクト fileSave が構築されます。
図 3 通常のオブジェクト
上記の例から、通常のオブジェクトにはプロトタイプはありませんが、
proto 属性があることがわかります。 要約: 上記の分析から、関数オブジェクトにはプロトタイプ属性があるが、通常のオブジェクトにはプロトタイプ属性がないことがわかりました。
2. プロトタイプ チェーン
プロトタイプ チェーンの実装は、C 言語ではポインター、Java では参照として理解できるproto 属性に依存します。 js では、proto は何を指すのでしょうか?まだ例を投げますが、fileSave の proto 属性を出力してみましょう:
図 4 オブジェクトの
proto fileSave の proto
値が save 関数オブジェクトのプロトタイプと同じであることを発見しましたか?図 2 でも同じです。つまり、proto は save のプロトタイプを指します。 fileSave オブジェクトが new save(); を通じて作成されることがわかっているため、fileSave の proto はそのコンストラクター オブジェクトのプロトタイプを指していると結論付けます。結果を検証するために、オブジェクト imageSave を再度保存して作成し、その proto 属性値を確認します。
imageSave の proto
が save のプロトタイプを指していることが再びわかりました。したがって、オブジェクトの proto がそのコンストラクターのプロトタイプを指していることがわかります。次に、save もオブジェクトであり、その prto はそのコンストラクターのプロトタイプ、つまり Function のプロトタイプを指す必要があります。
さらに、最初のセクションから、プロトタイプもオブジェクトであることが分かりました。その proto
属性の方向は何でしょうか?例を挙げると、save.prototype.protoの値が以下に出力されます。
図 5 save.prototype.proto
図 5 から、save.prototype.proto
の値が Object のプロトタイプであることがわかります。 Obejct.prototype の proto の値に非常に興味があるので、印刷して見てみましょう。結局のところ、これは実際にはトップレベルのオブジェクトです。 上記の分析から、次のチェーン図が得られます:
図 6 プロトタイプ チェーン
要約: このセクションの分析を通じて、プロトタイプ チェーンの実装はオブジェクトの
proto
属性に依存していることがわかりました。関数オブジェクトを通じてオブジェクトを作成する場合、オブジェクトの proto
属性はそのコンストラクターのプロトタイプを指します。
3. 継承 継承について話す前に、まず属性検索について学びましょう。 js では、プロトタイプ チェーンに従って属性を検索します。属性がない場合は、proto 属性に従って検索します。まずはサンプルコードを書いてみましょう。
save.fileName = "oo"save.prototype.fileName = "lili";fileSave.fileName = "haha";
この時点で fileSave.fileName の値を出力すると、結果が「ははは」であることがわかります。しかし、fileSave.fileName = "haha"; を削除すると、再度印刷するときに何が出力されるでしょうか?
印刷結果から、fileName 属性が proto 属性に基づいて検出される、つまり、必要な属性が図 5 のチェーン図に基づいてクエリされることがわかります。ここで、save.prototype.fileName = "lili"; この割り当てコードがない場合、プロトタイプ チェーンに対応する属性がないため、出力される内容は未定義になります。なぜ「oo」が出力されないのかと疑問に思う人もいるかもしれません。実際、コードからは割り当てコード save.fileName = "oo" がわかりますが、このコードが実行されるときは、save が関数オブジェクトであることを知っておく必要があります。 will プロトタイプ内ではなくコンストラクター内で、Java の静的プロパティと同様です (ここでは、インスタンス オブジェクトを介してアクセスできません)。
覚えておいてください: 通常のオブジェクトを通じてプロパティを呼び出す場合、検索はコンストラクターではなく、プロトタイプのプロパティでのみ見つかります。保存プロトタイプで見つからない場合は、save.proto などで検索されます。
プロパティの検索方法を知っていれば、継承の実装は非常に簡単です。たとえば、空のオブジェクト saveDisk を作成します。save の fileName にアクセスしたい場合は、saveDisk の proto の値を save のプロトタイプと等しく設定するだけです (単純に、2 つの無関係なアイアンをリンクすると理解されます)。
以上がjs のプロトタイプチェーンと継承について理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。