今回紹介したいのは、複数のオブジェクトを「継承」するインスタンスを生成する方法です。
たとえば、「animal」オブジェクトのコンストラクターが追加されました。
function Animal(){
this.species = "Animal";
}
「猫」オブジェクトのコンストラクタもあります,
Function Cat(name,color){
this.name = name;
this.color = color;
「猫」に「動物」を継承させるには?
1. コンストラクターのバインディング
最も簡単な方法は、おそらく、call または apply メソッドを使用して、親オブジェクトのコンストラクターを子オブジェクトにバインドすることです。つまり、子オブジェクトのコンストラクターで追加します。関数への行: Function Cat( name,color) {
Animal.apply(this, argument);
this.name = name;
}
var cat1 = new Cat(" ","黄");
alert(cat1.species); // 動物
2. プロトタイプ モード
より一般的なアプローチは、プロトタイプ属性。
「cat」のプロトタイプ オブジェクトが Animal のインスタンスを指している場合、「cat」のすべてのインスタンスは Animal を継承できます。 Cat.prototype = new Animal();
Cat.prototype.constructor = 猫;
var cat1 = new Cat("Big Hair", "Yellow")
alter(cat1.species); // 動物
コード 最初の行では、Cat のプロトタイプ オブジェクトが Animal インスタンスを指すようにしています。
Cat.prototype = new Animal();
プロトタイプオブジェクトの元の値を完全に削除してから、新しい値を代入することと同じです。しかし、2行目は何を意味するのでしょうか?
Cat.prototype.constructor = Cat;
すべてのプロトタイプ オブジェクトには、そのコンストラクターを指すコンストラクター属性があることがわかります。つまり、Cat.prototype オブジェクトのコンストラクター プロパティは Cat を指します。
前のステップでこのプロトタイプ オブジェクトの元の値を削除したため、新しいプロトタイプ オブジェクトにはコンストラクター属性がないため、手動で追加する必要があります。そうしないと、後で「継承チェーン」に問題が発生します。これが 2 行目の意味です。
つまり、これは非常に重要な点であり、プログラミング時に必ず従わなければなりません。この点の後には次のようになります。つまり、プロトタイプ オブジェクトが置き換えられる場合、
o.prototype = {};
次に、コンストラクター属性を新しいプロトタイプ オブジェクトに追加し、この属性をポイントし直す必要があります。元のコンストラクターに。
o.prototype.constructor = o;
3. プロトタイプを直接継承する
Animal オブジェクトでは、変更されていない属性を Animal.prototype に直接書き込むことができます。したがって、Cat() に Animal() をスキップさせて、Animal.prototype を直接継承させることもできます。
さて、まず Animal オブジェクトを書き直しましょう: function Animal(){ }
Animal.prototype.species = "Animal";
次に、Cat のプロトタイプ オブジェクトを Animal のプロトタイプ オブジェクトにポイントすることで、継承。
Cat.prototype = Animal.prototype; 🎜> 猫 .prototype.constructor = 猫;
var cat1 = new Cat("Big Hair","Yellow")
alter(cat1.species); // 動物
前の方法と比較して、この方法の利点は、より効率的であり (Animal のインスタンスを実行して作成する必要がない)、メモリを節約できることです。欠点は、Cat.prototype と Animal.prototype が同じオブジェクトを指すようになったため、Cat.prototype への変更が Animal.prototype に反映されることです。
つまり、上記のコードには実際には問題があります。 2 行目を見てください。
Cat.prototype.constructor = Cat;
この文は実際に Animal.prototype オブジェクトのコンストラクター プロパティを変更します。
alert(Animal.prototype.constructor); // Cat
4. 空のオブジェクトを仲介として使用する
「プロトタイプを直接継承」には上記の欠点があるため、空のオブジェクトを使用できます。オブジェクト オブジェクトは仲介者として機能します。
var F = function(){};
F.prototype = Animal.prototype;
Cat.prototype = new F();
Cat.prototype.constructor = Cat;
F は空のオブジェクトですメモリはほとんど必要としません。この時点では、Cat のプロトタイプ オブジェクトを変更しても、Animal のプロトタイプ オブジェクトには影響しません。
alert(Animal.prototype.constructor); // Animal
5. プロトタイプモードのカプセル化関数
使いやすくするために、上記のメソッドを関数にカプセル化します。
Function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype.constructor = Child; uber = Parent .prototype; }
使用時のメソッドは次のとおりです
var cat1 = new Cat("Big Hair","Yellow"); cat1.species); // Animal
この拡張関数は、YUI ライブラリが継承を実装する方法です。
あと、ちょっと説明させてください。関数本体の最後の行
Child.uber = Parent.prototype;
は、親オブジェクトのプロトタイプ属性を直接指す子オブジェクトの uber 属性を設定することを意味します。これは子オブジェクトでチャネルを開くのと同じで、親オブジェクトのメソッドを直接呼び出すことができます。この行は、継承を完全にするためだけにここに配置されており、純粋にバックアップの目的で使用されています。
6. 継承のコピー
上記では、プロトタイプ オブジェクトを使用して継承を実装しています。また、考え方を変えて、純粋に「コピー」メソッドを使用して継承を実装することもできます。簡単に言えば、親オブジェクトのプロパティやメソッドをすべて子オブジェクトにコピーすれば、継承も実現できるのではないでしょうか?
まず、Animal の不変プロパティをすべてそのプロトタイプ オブジェクトに配置します。
コードをコピー
コードは次のとおりです: function Animal(){} Animal.prototype .species = "Animal";
次に、属性コピーの目的を達成するための関数を書きます。
コードをコピー
コードは次のとおりです。 Function extend2(Child, Parent) { var p = Parent.prototype;
var c = Child.prototype;
for (var i in p) {
c[i] =
c.uber = p;
}
この関数の機能は、親オブジェクトのプロトタイプ オブジェクトの属性を子オブジェクトのプロトタイプ オブジェクトに 1 つずつコピーすることです。
を使用する場合は、次のように記述します:
コードをコピー
まだ終わっていないので、パート 3「非コンストラクターの継承」を読み続けてください。
(終わり)