1. はじめに:こんにちは、皆さん最近調子はどうですか?😃関数の継承は JS の基本かつ重要な部分であり、面接でもよく質問されます。以下では、JS でよく使用され、習得する必要がある継承メソッドを簡単に紹介します。以下の内容をマスターしておけば面接も問題なしですよ~ もちろん、これにはプロトタイプ チェーンの一定の基礎が必要です。プロトタイプ チェーンに詳しくない場合は、私の記事「js プロトタイプ チェーンの簡単な理解」をお読みください。 2. プロトタイプチェーン継承:プロトタイプ チェーン継承の重要なポイントは、親クラスのインスタンスが子クラスのプロトタイプとして機能することです。次の例を見てください。 // 親関数 Person 関数 Person(名前, 年齢) { // いくつかのプロパティを定義します this.name = name; this.age = 年齢; this.nature = ["オーロラ", "風", "月"]; } // Personプロトタイプにメソッドを定義する Person.prototype.sayLove = function () { console.log(this.name + " 好き " + this.nature[0]); }; // サブ関数ジャック 関数 Jack() {} // 親クラスのインスタンスはサブクラスのプロトタイプとして使用されます (------------------実装コア--------------------------) Jack.prototype = 新しい Person(); ここで、Jack のインスタンスを 2 つ作成し、Person の継承が実装されているかどうかをテストします。 var jack1 = 新しい Jack(); var jack2 = 新しい Jack(); jack2.nature[0] = "海"; jack1.sayLove(); jack2.sayLove(); コンソールにログ出力します。 コンソールにログ出力します。 実行結果から、確かに継承されており、sayLove メソッドを実行できることがわかります。しかし、欠点もたくさんあります。Jack インスタンスを作成するときに、name と age パラメータを渡すことができず、異なるインスタンスの nature 参照型属性が互いに影響を及ぼします。1 つを変更すると、すべてが変更されます。 3. コンストラクタ継承の借用(オブジェクトの偽装):核心は「コンストラクタの盗用」にあります。サブクラスのコンストラクターから親クラスのコンストラクターを呼び出します。結局のところ、関数は特定のコンテキストでコードを実行する単なるオブジェクトなので、apply() メソッドと call() メソッドを使用して、新しく作成されたオブジェクトをコンテキストとしてコンストラクターを実行できます。プロトタイプ チェーン継承におけるパラメーターと参照型プロパティ間の競合を解決できます。または、直接例を見てみましょう: // 親関数 Person 関数 Person(名前, 年齢) { // いくつかのプロパティを定義します this.name = name; this.age = 年齢; this.nature = ["オーロラ", "風", "月"]; } // Personプロトタイプにメソッドを定義する Person.prototype.sayLove = function () { console.log(this.name + " 好き " + this.nature[0]); }; // サブ関数 Lucy 関数 Lucy(名前, 年齢) { // 呼び出しを通じてこれを Lucy にポイントすることは、親関数 Person のコンテンツをコピーすることと同じです (---------実装コア--------------) Person.call(this, 名前, 年齢); } // 子関数プロトタイプにメソッドを定義する Lucy.prototype.syaName = function () { console.log("私の名前は " + this.name です); }; ここで、Lucy のインスタンスを 2 つ作成し、Person の継承が実装されているかどうかをテストします。 var lucy1 = new Lucy("lucy1", "20"); var lucy2 = new Lucy("lucy2", "22"); lucy2.nature[0] = "海"; コンソールにログ出力します。 コンソールにログ出力します。 コンソールにログ出力します。 lucy1.syaName(); lucy2.syaName(); lucy1.sayLove(); その結果、継承が可能になり、パラメータを渡すことができ、参照型のプロパティは互いに影響を及ぼしません。ただし、デメリットは明らかです。エラーが表示され、親クラスのプロトタイプで sayLove メソッドを使用できません。 4. 組み合わせ継承:複合継承は、プロトタイプチェーン継承と借用コンストラクタ継承のコア実装を組み合わせた継承方法です。パラメータを渡すことができ、参照型プロパティは互いに影響しません。同時に、サブクラスは親クラスのメソッドも取得できます。これは現在最も一般的に使用されている継承方法でもあります。直接例を見てみましょう: // 親関数 Person 関数 Person(名前, 年齢) { // いくつかのプロパティを定義します this.name = name; this.age = 年齢; this.nature = ["オーロラ", "風", "月"]; } // Personプロトタイプにメソッドを定義する Person.prototype.sayLove = function () { console.log(this.name + " 好き " + this.nature[0]); }; // サブ関数 Lisa 関数 Lisa(名前, 年齢) { // 呼び出しを通じてこれを Lisa にポイントすることは、親関数 Person のコンテンツをコピーすることと同じです (------実装コア-----------) Person.call(this, 名前, 年齢); } // 親クラスのインスタンスはサブクラスのプロトタイプとして使用されます (---------------実装コア-------------------) Lisa.prototype = 新しいPerson(); //ちょっとした知識ポイントですが、ここでは Lisa のコンストラクタが再び Lisa を指すようにします。そうしないと、Lisa のプロトタイプが Person インスタンスであるため、コンストラクタは Person を指すことになります。 Lisa のプロトタイプを作成します。 ここで、Lisa のインスタンスを 2 つ作成し、Person の継承が実装されているかどうかをテストします。 var lisa1 = new Lisa("lisa1", "20"); var lisa2 = new Lisa("lisa2", "21"); lisa2.nature[0] = "海"; コンソールログ(lisa1.name); コンソールにログ出力します。 コンソールにログ出力します。 lisa1.sayLove(); lisa2.sayLove(); 継承した機能が基本的に実現されていることがわかります。また、プロトタイプチェーンと借用コンストラクタ継承の欠点も修正します。ただし、まだ小さな欠点があります。コード コメントの実装コアでは、Person が 2 回呼び出されているため、Lisa プロトタイプとインスタンスに 2 つの同一のプロパティがあり、パフォーマンスがいくらか浪費されることがわかります。 5. 寄生的組み合わせ遺伝:実際、寄生的なコンポジション継承はコンポジション継承に似ていますが、コンポジション継承のプロトタイプとインスタンスが同じプロパティのコピーを 2 つ生成するという欠点に対する追加の解決策があります。ソリューションの核心は、サブクラスのプロトタイプを親クラスのプロトタイプに割り当てるだけなので、新しい親クラスのインスタンスを作成する必要がないことです。親クラスのプロトタイプを値とする新しいオブジェクトを作成し、それを子クラスのプロトタイプに割り当てるだけです。 Object.create(proto, [propertiesObject]) メソッドは、新しいオブジェクトを作成するために使用されます。新しいオブジェクトの __proto__ は、そのパラメータ proto と同等です。もちろん、Object.create は IE の下位バージョンでは使用できない可能性があるため、Object.create メソッドも以下のようにカスタム カプセル化されていますが、これは単純なカプセル化にすぎません。直接例を見てみましょう: // 親関数 Person 関数 Person(名前, 年齢) { // いくつかのプロパティを定義します this.name = name; this.age = 年齢; this.nature = ["オーロラ", "風", "月"]; } // Personプロトタイプにメソッドを定義する Person.prototype.sayLove = function () { console.log(this.name + " 好き " + this.nature[0]); }; // サブ関数 Andy 関数 Andy(名前, 年齢) { Person.call(this, 名前, 年齢); } // Object.create() メソッドがない場合は、単に if (!Object.create) { をカプセル化します。 Object.create = 関数 (proto) { 関数 Temp() {} Temp.prototype = proto; 新しい Temp() を返します。 }; } // Object.create メソッドを呼び出して、__proto__ が Person.prototype である新しい画像のペアを作成し、それを Andy.prototype に割り当てます (-------実装コア----------) Andy.prototype = Object.create(Person.prototype); // Andy を指すようにコンストラクターを変更します。prototype.constructor = Andy; ここで、Andy のインスタンスを 2 つ作成し、Person の継承が実装されているかどうかをテストします。 console.log(Andy.prototype.__proto__ === Person.prototype); var andy1 = new Andy("andy1", "20"); var andy2 = new Andy("andy2", "21"); andy2.nature[0] = "海"; コンソールにログ出力します。 コンソールにログ出力します。 コンソールにログ出力します。 andy1.sayLove(); andy2.sayLove(); 完璧に動作します: 6. クラスの継承:ES6 でクラス構文シュガーがリリースされてからは、クラスを通じてクラスを定義し、クラスの継承を実装できるようになりました。直接例を見てみましょう: //親クラス Animal を定義する クラス動物{ //ここでコンストラクタはクラス自体を指しており、es5の動作と同じです。constructor(name) { this.name = 名前; } いいね食べる() { console.log(this.name + " like eat " + this.food); } } //親クラスAnimalを継承してサブクラスDogを定義する クラスDogはAnimalを拡張します{ コンストラクタ(名前、食べ物) { //親クラスの属性 super(name) を super(attribute name) を通じて継承します。 this.food = 食べ物; } いいね食べる() { // super を通じて親クラス メソッドを継承します。+親クラス メソッド super.likeEat(); } } 新しい Dog インスタンスを作成し、Dog が Animal を継承するかどうかをテストします。 var jinmao = new Dog("jinmao", "bone"); console.log(jinmao.name); ジンマオ 完璧に実装されていることがわかります。 7. 要約:
この記事はこれで終わりです。皆さんのお役に立てれば幸いです。また、123WORDPRESS.COM のその他のコンテンツにも注目していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: Linux で NFS のワンクリック展開を実装する方法
>>: CentOS7 64でのMySQL5.6.40の詳細なインストール手順
データベースでは、UNION キーワードと UNION ALL キーワードの両方が 2 つの結果セッ...
要件:PC側とモバイル側は2つの独立したプロジェクトです。2つのプロジェクトの内容は基本的に同じで、...
目次成果を達成する実装コード最近、会社でelementUIを使い始めたため、開発の過程でテーブルのセ...
不明なドメイン名 www.baidu.com を Ping するホストのIPアドレスを変更する右クリ...
今日も Watch アプリのデザインに関する話です。私はケーススタディが大好きなので、同じトピックを...
目次DOMContentLoadedとロードjs ブロッキングとは何ですか? CSS ブロッキングと...
解決: pythearn2 パッケージをダウンロードしたディレクトリで、setup.py ファイルを...
適切に機能するテーブル プロパティ設定:コードをコピーコードは次のとおりです。 <テーブル セ...
3D座標の概念要素が回転すると、その座標軸も一緒に回転します。注 -y方向の問題立方体を回転させる効...
目次序文1.v-ショー2.v-if 3. v-showとv-ifの違い1. 原則の違い2. アプリケ...
Vue2.0/3.0双方向データバインディングの実装原理双方向データバインディングとは、データの変更...
目次Rractとは何ですか?背景React スキャフォールディングJSXとは何かRractとは何です...
以下のように表示されます。 XML/HTML コードコンテンツをクリップボードにコピーbody、di...
この記事では、ウィンドウ表示効果を実現するためのJavaScriptの具体的なコードを参考までに紹介...
最近Bステーションでスマートアンチブロッキング弾幕と呼ばれる弾幕エフェクトを見ました。これは伝説のマ...