コンストラクタの借用この手法の基本的な考え方は単純です。サブタイプ コンストラクター内からスーパータイプ コンストラクターを呼び出します。また、関数は特定の環境でコードを実行するオブジェクトにすぎないため、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データベースパーティションとテーブルパーティション分割方法
MySQL sql_modeの適切な設定sql_mode は見落とされやすい変数です。デフォルト値は...
目次ブートストラップと関連コンテンツの紹介グリッドシステムネストされた列列オフセット列の並べ替えナビ...
序文私たちのビジネスがまだ初期段階にあり、同時実行の度合いが比較的低い場合、数年間はデッドロックの問...
ステップ1: Alibaba Cloudプライマリドメイン名にセカンダリドメイン名を追加する2 番目...
目次splice() メソッドjoin() メソッド逆() メソッドevery() メソッド削減()...
1) jdkファイルが保存されているフォルダパスを入力します私はここにいますusr/local/jd...
目次背景1. クエリ条件に「or」が含まれているため、インデックスが失敗する可能性があります。 2....
最新の Windows 10 アップデートをインストールした後、システム UI の詳細な効果が顕著に...
<br />ネットワーク設計の分野では、アイトラッキングに関する研究が非常に盛んに行われ...
このエラーは初心者によく発生します。この記事では主に、エラー 2003 (HY000): '...
これ以上時間を無駄にせず、早速本題に入りましょう。 1. ロゴに代替テキストを追加するこれには 2 ...
1. 三角形境界線の設定 コード: 幅: 300ピクセル; 高さ: 300px; 背景: 赤; 境界...
同僚から、MySQL データ型 DECIMAL(N,M) の N と M の意味を尋ねられました。言...
序文実際には、次のような問題に遭遇する可能性があります。特定のレコードの ID がわかっていて、その...
ここでは比較的簡単なインストール方法のみを紹介します。 1. yumを使用してインストールするyum...