コンストラクタの借用この手法の基本的な考え方は単純です。サブタイプ コンストラクター内からスーパータイプ コンストラクターを呼び出します。また、関数は特定の環境でコードを実行するオブジェクトにすぎないため、apply() メソッドと call() メソッドを使用すると、新しく作成されたオブジェクトでコンストラクターを実行することもできます。 関数 Box(名前){ this.name = 名前 } ボックスプロトタイプ年齢 = 18 関数デスク(名前){ Box.call(this, name) // オブジェクトの偽装、オブジェクトの偽装はコンストラクタ内の情報のみを継承できます} var デスク = 新しいデスク('ccc') console.log(desk.name) // --> ccc console.log(desk.age) // --> 未定義 このことから、インスタンス プロパティのみが継承され、プロトタイプのプロパティにはアクセスできないことがわかります。このパターンは 2 つの問題を解決します。パラメータの受け渡しと継承は可能ですが、プロトタイプがないと再利用できません。 コンポジション継承関数 Box(名前){ this.name = 名前 } Box.prototype.run = 関数 (){ console.log(this.name + '実行中...') } 関数デスク(名前){ Box.call(this, name) // オブジェクトの偽装} Desk.prototype = new Box() // プロトタイプチェーン var desk = new Desk('ccc') console.log(desk.name) // --> ccc desk.run() // --> ccc が実行中です... この継承方法の背後にある考え方は、プロトタイプ チェーンを使用してプロトタイプ プロパティとメソッドを継承し、コンストラクターを使用してインスタンス プロパティを継承することです。 プロトタイプ継承プロトタイプの継承: プロトタイプを使用すると、カスタム タイプを作成しなくても、既存のオブジェクトに基づいて新しいオブジェクトを作成できます。これについて言えば、ある人物について言及しなければなりません。Douglas Crockford 氏は、2006 年に執筆した記事「Javascript でのプロトタイプ継承」で、次のようなメソッドを紹介しました。 function object(o) { // リテラル関数を渡す function F(){} // コンストラクターを作成する F.prototype = o; // リテラル関数をコンストラクターのプロトタイプに割り当てる return new F() // 最後にインスタンス化されたコンストラクターを返す } 次の例を考えてみましょう。 関数obj(o) { 関数F(){} F.プロトタイプ = o; 新しいF()を返す } var ボックス = { 名前: 'ccc', 年齢: 18歳 家族: ['兄弟','姉妹'] } var box1 = obj(ボックス) console.log(box1.name) // --> ccc box1.family.push('姉妹') console.log(box1.family) // --> ["兄弟", "姉妹", "姉妹"] var box2 = obj(ボックス) console.log(box2.family) // --> ["兄弟", "姉妹", "姉妹"] 上記コードの実装ロジックはプロトタイプチェーン継承と非常に似ているため、参照配列、つまりファミリ属性が共有されます。 寄生遺伝関数obj(o) { 関数F(){} F.プロトタイプ = o; 新しいF()を返す } 関数create(o){ var clone = obj(o) // 関数を呼び出して新しいオブジェクトを作成します clone.sayName = function(){ // 何らかの方法でこのオブジェクトを強化します console.log('hi') } return clone // このオブジェクトを返す } var 人 = { 名前: 'ccc', 友達: ['aa','bb'] } var anotherPerson = create(人) anotherPerson.sayName() // --> こんにちは この例のコードは、person に基づいて新しいオブジェクト anotherPerson を返します。新しいオブジェクトには person のすべてのプロパティとメソッドがあるだけでなく、独自の sayHi() メソッドもあります。寄生継承は、カスタム型やコンストラクターではなくオブジェクトを主に考慮する状況でも役立つパターンです。寄生継承を使用してオブジェクトに関数を追加すると、関数を再利用できないため効率が低下します。これはコンストラクター パターンに似ています。 寄生的組み合わせ継承前述したように、複合継承は JavaScript で最も一般的に使用される継承モードですが、独自の欠点もあります。複合継承の最大の問題は、状況に関係なく、スーパータイプ コンストラクターが 2 回呼び出されることです。1 回はサブタイプ プロトタイプを作成するときに、もう 1 回はサブタイプ コンストラクター内で呼び出されます。はい、サブタイプには最終的にスーパータイプ オブジェクトのすべてのインスタンス プロパティが含まれますが、サブタイプ コンストラクターを呼び出すときにこれらのプロパティを書き換える必要があります。次の例を見てみましょう。 関数SuperType(名前){ this.name = 名前; this.colors = ['赤','黒'] } SuperType.prototype.sayName = 関数 (){ console.log(この名前) } 関数 SubType(名前, 年齢){ SuperType.call(this, name) // SuperType への 2 回目の呼び出し this.age = 年齢 } SubType.prototype = new SuperType() // SuperTypeへの最初の呼び出し SubType.prototype.constructor = サブタイプ SubType.prototype.sayAge = 関数 (){ コンソールログ(this.age) } SuperType コンストラクターが初めて呼び出されると、SubType.prototype は name と colors という 2 つのプロパティを取得します。これらはすべて SuperType のインスタンス プロパティですが、現在は SubType のプロトタイプに配置されています。 SubType コンストラクターが呼び出されると、SuperType コンストラクターが再度呼び出され、新しいオブジェクトにインスタンス属性の名前と色が再度作成されます。したがって、これら 2 つのプロパティは、プロトタイプ内の同じ名前を持つ 2 つのプロパティをマスクします。つまり、名前と色の属性のセットが 2 つあります。1 つはインスタンスにあり、もう 1 つはプロトタイプにあります。これは、SuperType コンストラクターを 2 回呼び出した結果です。この問題の解決策は寄生的組み合わせ継承です。 関数オブジェクト(o) { 関数F(){} F.プロトタイプ = o; 新しいF()を返す } 関数 inheritPtototype(サブタイプ、スーパータイプ){ var prototype = object(superType.prototype) // オブジェクトを作成 prototype.constructor = subType // オブジェクトを拡張 subType.prototype = prototype // オブジェクトを指定 } 関数SuperType(名前){ this.name = 名前 this.colors = ['赤', '白'] } SuperType.prototype.sayName = function(){ console.log(この名前) } 関数 SubType(名前,年齢){ SuperType.call(これ、名前) this.age = 年齢 } 継承Ptototype(サブタイプ、スーパータイプ) SubType.prototype.sayAge = function(){ コンソールログ(this.age) } var インスタンス = 新しいサブタイプ ('ccc'、18) instance.sayName() // --> ccc instance.sayAge() // --> 18 console.log(インスタンス) コンソールによって出力される構造: 詳細図: この例の効率性は、SuperType コンストラクターを 1 回だけ呼び出すため、SubType.prototype に不要な冗長プロパティが作成されないことです。同時に、プロトタイプ チェーンは変更されないため、instanceof と isPrototypeOf() は引き続き正常に使用できます。これは多くの大企業が採用している継承方法でもあります。 以上がjsで継承を実装する5つの方法の詳細です。js継承の詳細については、123WORDPRESS.COMの他の関連記事にも注目してください。 以下もご興味があるかもしれません:
|
<<: Linux ファイルシステムの説明: ext4 以降
>>: テーブルパーティションとパーティション分割とは何ですか?MySqlデータベースパーティションとテーブルパーティション分割方法
この記事では、カード ウォーターフォール レイアウトを実現するための CSS3 列のサンプル コード...
目次シナリオ要件glibc バージョンglibcのインストールglibc ソフトリンクシナリオ要件C...
1. Dockerをインストールする1. 仮想マシンに Centos7 をインストールしました。Li...
目次【共通コマンド】 [一般的な esxi コマンドの概要] [esxcli コマンドの調査] ES...
序文ソースコードは合計で 100 行強しかありません。これを読めば、react-dnd などの成熟し...
最近、会社のサーバーの時間が不正確で、外部の時間ソースと同期できないことがわかりました。会社はドメイ...
VMware が異常シャットダウンした後、再起動すると「この構成ファイルを排他的にロックできませんで...
この記事では主にボタンのスタイルについて説明します。 1. オプション2. サイズ3. 活動状況4....
CentOS6.9はMysql5.7をインストールします。参考までに、詳細は次のとおりです。 1. ...
目次ルートの場所が見つかりませんオフバイスラッシュ安全でない変数の使用スクリプト名$uri を使用す...
汎用ロード/書き込みメソッドオプションを手動で指定するSpark SQL の DataFrame イ...
ネットワーク データを読み込むときは、ユーザー エクスペリエンスを向上させるために、通常は円形の読み...
1. nginxシェルスクリプトを保存するフォルダを作成する /usr/local/タスク/ngin...
この記事では、カルーセルアニメーションを実現するためのVueコンポーネントの具体的なコードを例として...
私たちが毎日使っているブラウザや Word 文書のスクロール バーはなぜ右側にあるのでしょうか。多く...