フロントエンド開発が知っておくべきJSプロトタイプと継承_jsオブジェクト指向
すべての JS 関数には、オブジェクト (プロトタイプ オブジェクトとも呼ばれる) を参照するプロトタイプ属性があります。この関数にはコンストラクターと通常の関数が含まれます。コンストラクターのプロトタイプについて詳しく説明しますが、通常の関数にもプロトタイプがあることは否定できません。たとえば、通常の関数:
関数 F (){
alert(F.prototypeinstanceofObject) //true;
コンストラクター、つまりオブジェクトを構築します。まず、コンストラクターを通じてオブジェクトをインスタンス化するプロセスを理解しましょう。
this.x =x;
}
var obj=new A(1);
obj オブジェクトをインスタンス化するには、次の 3 つの手順があります。 1. obj オブジェクトを作成します: obj=new Object();
2. obj の内部 __proto__ をそれを構築する関数 A のプロトタイプにポイントします。 obj.constructor===A.prototype.constructor (A.prototype が元の A プロトタイプを指さなくなった場合でも、これは常に true です。つまり、クラスのインスタンス オブジェクトのコンストラクター プロパティは常にこれにより、obj.constructor.prototype が A.prototype を指すようになります (obj.constructor.prototype===A.prototype、以下で説明するように、A.prototype が変更された場合、これは当てはまりません) )。 obj.constructor.prototype と内部 _proto_ は、オブジェクトをインスタンス化するときに使用されます。obj にはプロトタイプ属性がありませんが、プロトタイプ チェーンのプロトタイプ属性を取得するために __proto__ を使用できます。 . およびプロトタイプ メソッド、FireFox は、FireFox でアラートできる __proto__ を公開します (obj.__proto__); 3. これとして obj を使用して、コンストラクター A を呼び出してメンバー (つまり、オブジェクトのプロパティとオブジェクトのメソッド) を設定し、初期化します。 。
これら 3 つの手順が完了すると、obj オブジェクトはコンストラクター A との接続がなくなりました。この時点で、コンストラクター A がメンバーを追加しても、インスタンス化された obj オブジェクトには影響しなくなります。このとき、obj オブジェクトは x 属性とコンストラクター A のプロトタイプ オブジェクトのすべてのメンバーを持ちます。もちろん、この時点ではプロトタイプ オブジェクトにはメンバーがありません。
プロトタイプ オブジェクトは最初は空です。つまり、メンバー (つまり、プロトタイプ プロパティとプロトタイプ メソッド) を持ちません。次のメソッドを使用して、プロトタイプ オブジェクトに含まれるメンバーの数を確認できます。
コードをコピーします
alert("member: " num);//alert はプロトタイプの属性名を出力しますプロトタイプのすべてのメンバーの数。
ただし、プロトタイプ プロパティまたはプロトタイプ メソッドが定義されると、コンストラクターを通じてインスタンス化されたすべてのオブジェクトは、これらのプロトタイプ プロパティおよびプロトタイプ メソッドを継承します。これは内部的に行われ、_proto_ チェーンが実装されます。
例:
A.prototype.say=function(){alert("Hi")};
すべての A オブジェクトには、say メソッドがあります。すべてのオブジェクトが Say メソッドのコピーを持つのではなく、プロトタイプ オブジェクトの Say メソッドが全員に共有される唯一のコピーです。
2. プロトタイプと継承
まず、単純な継承の実装を見てみましょう。
コードをコピー
5、6、7 行目: コンストラクター A を参照する一時属性 tmpObj を作成し、B 内で実行し、実行後に削除します。 B 内で this.x=x が実行されると (this は B のオブジェクトです)、B は当然 x 属性を持ちます。 もちろん、B の x 属性と A の x 属性は独立しているため、それらは独立ではありません。厳密には継承。行 5、6、および 7 は、 call(apply) メソッドを使用したより単純な実装です。 A.call(this,x);
両方のメソッドが this を A の実行に渡します。 B のオブジェクトです。そのため、A(x) は直接使用されません。この継承方法はクラス継承です(jsにはクラスはありません。ここではコンストラクタのみを指します)。Aの構築されたオブジェクトの属性メソッドはすべて継承されますが、Aのプロトタイプオブジェクトのメンバーは継承できません。この目標を達成するには、これに基づいてプロトタイプの継承を追加する必要があります。
次の例を通じて、プロトタイプとプロトタイプが参加する完全な継承について深く理解することができます。 (この記事の核心はここです^_^)
function A( x){
this.x = x;
}
A.prototype.a = "a";
function B(x,y){
this .y = y;
A.call(this,x);
B.prototype.b1 = function(){
アラート("b1"); >B.prototype = new A();
B.prototype.b2 = function(){
alert("b2");
B.prototype.constructor = B; >var obj = new B (1,3);
この例は、B が A を継承するものです。 7 行目 クラス継承: A.call(this.x); 前述の通り。プロトタイプの継承は 12 行目で実装されています: B.prototype = new A();
これは、B のプロトタイプが A のインスタンス オブジェクトを指すことを意味します。このインスタンス オブジェクトには、未定義の x 属性があります。値「a」の属性を持ちます。したがって、B プロトタイプにもこれら 2 つの属性があります (つまり、B と A はプロトタイプ チェーンを確立しており、B は A の下位です)。先ほどのクラス継承により、B のインスタンス オブジェクトも x 属性を持ちます。つまり、obj オブジェクトには同じ名前の x 属性が 2 つあります。このとき、プロトタイプ属性 x はインスタンス オブジェクトに譲らなければなりません。属性 x なので、 obj.x は未定義ではなく 1 になります。 13 行目ではプロトタイプ メソッド b2 も定義しているため、B プロトタイプにも b2 があります。 9行目から11行目ではプロトタイプのメソッドb1が設定されていますが、12行目の実行後、Bプロトタイプにはb1メソッドが存在しなくなり、obj.b1が未定義になっていることがわかります。 12 行目で B プロトタイプ ポインタが変更されるため、b1 を持つ元のプロトタイプ オブジェクトは破棄され、当然 b1 は存在しません。
alert(B.prototype.constructor) は「function A(x){...}」として出てきます。同様に、obj.constructor も A コンストラクター オブジェクトです。alert(obj.constructor) が出た後は、「関数 A(x){...}」、つまり B.prototype.constructor=== になります。 obj.constructor(true) ですが、 B.prototype===obj.constructor.prototype(false) です。前者は B のプロトタイプであり、メンバー: x、a、b2 を持ち、後者は A のプロトタイプであり、メンバーがいます:この問題を解決するにはどうすればよいでしょうか? 16 行目で、B プロトタイプのコンストラクターを B コンストラクターにリダイレクトし、次に B.prototype===obj.constructor.prototype(true) となり、すべてのメンバーが x、a、b2 になります。
16 行目がない場合、obj = new B(1,3) はインスタンス化のために A コンストラクターを呼び出しますか?答えは「いいえ」です。obj.y=3 であるため、呼び出された B コンストラクターによって依然としてインスタンス化されていることがわかります。 obj.constructor===A(true) ですが、new B() の動作では、コンストラクターを通じてインスタンス オブジェクトを作成するための上記の 3 つの手順が実行されます。最初の手順は空のオブジェクトを作成することです。ステップ、obj.__proto__ === B.prototype、B.prototype には x、a、b2 のメンバーがあり、obj.constructor は B.prototype.constructor、つまりコンストラクター A を指します。 、コンストラクター B と呼ばれます。メンバーを設定および初期化するには、属性 x、y を持ちます。 16 行を追加しないことは obj のプロパティには影響しませんが、前の段落で述べたように、obj.constructor と obj.constructor.prototype には影響します。したがって、プロトタイプ継承を使用した後は、修正操作を実行する必要があります。
12行目と16行目について、簡単に説明すると、12行目はBのプロトタイプにAのプロトタイプオブジェクトのメンバーをすべて継承させるだけでなく、Bのインスタンスオブジェクトのコンストラクタのプロトタイプもプロトタイプを指すようにしています。したがって、この欠陥は 16 行目まで修正する必要があります。
終了しました。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











関数の継承では、「基底クラス ポインター」と「派生クラス ポインター」を使用して継承メカニズムを理解します。基底クラス ポインターが派生クラス オブジェクトを指す場合、上方変換が実行され、基底クラスのメンバーのみにアクセスされます。派生クラス ポインターが基本クラス オブジェクトを指す場合、下向きキャストが実行される (安全ではない) ため、注意して使用する必要があります。

継承とポリモーフィズムはクラスの結合に影響します。派生クラスは基本クラスに依存するため、継承により結合が増加します。ポリモーフィズムにより、オブジェクトは仮想関数と基本クラス ポインターを通じて一貫した方法でメッセージに応答できるため、結合が軽減されます。ベスト プラクティスには、継承を控えめに使用すること、パブリック インターフェイスを定義すること、基本クラスへのデータ メンバーの追加を回避すること、依存関係の注入を通じてクラスを分離することが含まれます。ポリモーフィズムと依存性注入を使用して銀行口座アプリケーションの結合を軽減する方法を示す実践的な例。

継承エラーのデバッグのヒント: 正しい継承関係を確認します。デバッガーを使用してコードをステップ実行し、変数値を調べます。仮想修飾子を正しく使用してください。隠れた相続によって引き起こされる相続ダイアモンド問題を調べてください。抽象クラスに実装されていない純粋仮想関数がないか確認します。

PHP のカプセル化テクノロジとアプリケーションのカプセル化は、オブジェクト指向プログラミングにおける重要な概念であり、外部プログラムに統一されたアクセス インターフェイスを提供するために、データとデータに対する操作を一緒にカプセル化することを指します。 PHP では、アクセス制御修飾子とクラス定義を通じてカプセル化を実現できます。この記事では、PHP のカプセル化テクノロジとそのアプリケーション シナリオを紹介し、いくつかの具体的なコード例を示します。 1. カプセル化されたアクセス制御修飾子 PHP では、カプセル化は主にアクセス制御修飾子によって実現されます。 PHP には 3 つのアクセス制御修飾子が用意されています。

C++の関数継承を詳しく解説:「is-a」と「has-a」の関係をマスターしよう 関数継承とは?関数の継承は、派生クラスで定義されたメソッドを基本クラスで定義されたメソッドに関連付ける C++ の手法です。これにより、派生クラスが基本クラスのメソッドにアクセスしてオーバーライドできるようになり、基本クラスの機能が拡張されます。 「is-a」および「has-a」関係 関数継承では、「is-a」関係は、派生クラスが基本クラスのサブタイプであること、つまり、派生クラスが基本クラスの特性と動作を「継承」することを意味します。基本クラス。 「has-a」関係は、派生クラスに基本クラス オブジェクトへの参照またはポインターが含まれていること、つまり、派生クラスが基本クラス オブジェクトを「所有」していることを意味します。構文関数継承を実装する方法の構文は次のとおりです: classDerivedClass:pu

C++ 関数の継承は、次の状況では使用しないでください。 派生クラスが異なる実装を必要とする場合、異なる実装を持つ新しい関数を作成する必要があります。派生クラスが関数を必要としない場合は、空のクラスとして宣言するか、プライベートの未実装の基本クラス メンバー関数を使用して関数の継承を無効にする必要があります。関数が継承を必要としない場合は、コードの再利用を実現するために他のメカニズム (テンプレートなど) を使用する必要があります。

原神 バージョン 4.4 の新しいマップの紹介. 皆さん、原神 4.4 バージョンでは、立月のシー ランタン フェスティバルも始まりました. 同時に、バージョン 4.4 では神羽渓谷と呼ばれる新しいマップ エリアが開始されます。提供された情報によると、沈雨谷は実際には喬営村の一部ですが、プレイヤーはそれを沈雨谷と呼ぶことに慣れています。それでは、新しい地図をご紹介します。原神バージョン 4.4 の新マップのご紹介です。バージョン 4.4 では、立月北部に「陳兪渓谷・上谷」、「陳兪渓谷・南嶺」、「来新山」がオープンします。谷・上谷」。 ※魔神クエスト・第3幕「ドラゴンと自由の歌」プロローグをクリアすると、テレポートアンカーポイントが自動で解放されます。 2. 喬営荘 暖かい春風が再び陳嶼の山野を撫でるとき、香りのよい

オブジェクト指向プログラミングとは何ですか?オブジェクト指向プログラミング (OOP) は、現実世界のエンティティをクラスに抽象化し、オブジェクトを使用してこれらのエンティティを表すプログラミング パラダイムです。クラスはオブジェクトのプロパティと動作を定義し、オブジェクトはクラスをインスタンス化します。 OOP の主な利点は、コードの理解、保守、再利用が容易になることです。 OOP の基本概念 OOP の主な概念には、クラス、オブジェクト、プロパティ、メソッドが含まれます。クラスはオブジェクトの設計図であり、オブジェクトのプロパティと動作を定義します。オブジェクトはクラスのインスタンスであり、クラスのすべてのプロパティと動作を備えています。プロパティは、データを保存できるオブジェクトの特性です。メソッドは、オブジェクトのデータを操作できるオブジェクトの関数です。 OOP の利点 OOP の主な利点は次のとおりです。 再利用性: OOP はコードをより高度なものにすることができます。
