ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptの継承方法を詳しく解説

JavaScriptの継承方法を詳しく解説

高洛峰
高洛峰オリジナル
2016-11-16 11:30:011126ブラウズ

主な継承方法は 6 つあります:

1. プロトタイプ チェーンの継承にはオブジェクト共有の問題があります。

2. コンストラクターの継承は call apply メソッドで実装されます。関数の再利用性の問題は親クラスがインスタンス化されるたびに再実行されます。 、親クラスのメソッドが繰り返し定義されています

3. 組み合わせモード (プロトタイプ チェーン + コンストラクター) コンストラクター継承メソッド、プロトタイプ チェーン継承メソッド: オブジェクトの共有を解決しますが、属性の継承は 1 つの空のスペースを使用します

4.関数

5. 寄生メソッド: プロトタイプメソッドにメソッドを追加

6. 寄生結合メソッド(属性継承が2回現れる問題を解決)

1. プロトタイプチェーンメソッド

の場合、それは、サブクラスのプロトタイプが親クラスのインスタンス オブジェクトを指すようにすることです。 サブクラスがインスタンス化されると、サブクラスのすべてのインスタンスは親クラス (p と呼ばれるものとします) のインスタンスの属性とメソッドを共有します。p に参照属性がある場合、サブクラスのインスタンスは参照を変更できます。 type.プロパティを変更すると、他のインスタンスのそのプロパティも変更されます。

//原型链方式
function A(){
    this.name = 'lc';
    this.stus = ['a','b','c'];
}
A.prototype.introduce = function (){
    alert(this.name);
}
 
function B(){}
B.prototype = new A();
 
var s1 = new B();
var s2 = new B();
console.log(s1.stus);  //['a','b','c']  
s1.stus.push('d');     //改变s1上的属性,会影响s2上的该属性
console.log(s2.stus);  // ['a','b','c','d']

以下に変更しても影響ありません。

//原型链方式
function A(){
    this.name = 'lc';
    this.stus = ['a','b','c'];
}
A.prototype.introduce = function (){
    alert(this.name);
}
 
function B(){}
B.prototype = new A();
 
var s1 = new B();
var s2 = new B();
 
s1.stus = ['d'];   //在s1上增加了属性,  就近原则,不在查找原型链上的同名属性
console.log(s1.stus);  //['d']
console.log(s2.stus);  // ['a','b','c']

2. コンストラクターメソッドの継承

共有コンストラクターとメソッドはすべて内部で定義されているため、返信関数の再利用性の問題については議論できません。

//构造函数方式继承
function A(name){
    this.name = name;
    this.type = 'parent';
    this.introduce = function (){ alert(this.name);}
}
A.prototype.sayhi = function (){
    alert(this.type);
}
function B(name,age){
    A.call(this,name);  //使用call方法 实现继承 但是父类中的方法重复定义 无复用性
    this.age = age;
    this.introduce = function (){ alert(this.name+this.age);}
}
 
var b = new B('lc',25);
b.introduce(); //lc25
b.sayhi();  //parent

3. 混合メソッド (プロトタイプメソッド + コンストラクターメソッド)

プロパティの継承にはコンストラクターを使用し、プロトタイプチェーンの継承メソッドを使用します

ただし、プロトタイプチェーンの継承を使用すると、実際にはプロパティも繰り返し継承されます。 。

function A(name){
    this.name = name;
    this.type = 'parent';
}
A.prototype.sayhi = function (){
    alert(this.type);
}
function B(name,age){
    A.call(this,name);
    this.age = age;
    this.introduce = function (){ alert(this.name+this.age);}
}
B.prototype = new A();

4. プロトタイプの継承

は、中間の空の関数を使用して、継承後にオブジェクトを返します。

function extend(parent){
    function F(){}
    F.prototype = parent;
    return new F();
}

5. 寄生継承 プロトタイプを基に、オブジェクトに属性メソッドを追加します

function extend(parent){
    function F(){}
    F.prototype = parent;
    return new F();
}
 
function createObj(p){  
    var clone = extend(p);
    clone.name = 'hello';    
    clone.say = function (){}
    return clone;
}

6. 寄生結合継承

メソッドを継承する際、親型のコンストラクターはインスタンス化されなくなり、inheritPrototype メソッドが使用されます中間の空の関数を使用し、この空の関数に親クラスのプロトタイプを継承させて、この空の関数をインスタンス化します (親クラスのプロトタイプのすべてのメソッドを継承します)。サブクラスのプロトタイプがこのインスタンス化された空のオブジェクトを指すようにするだけです。

親クラスのコンストラクターのインスタンス化は避けてください。

/* 寄生组合式继承 */
function inheritPrototype(subType, superType) {
  // var obj= extend(superType.prototype);
  function F(){}
  F.prototype = superType.prototype;
  var obj= new F();
 
  //obj.constructor = subType;
  subType.prototype = obj;    //不可将subType的prototype直接指向superType,否则的话,对子类prototype的修改会反应到父类上,  引用型变量
  subType.prototype.constructor = subType;
}

オブジェクトの偽装: コンストラクターを使用してクラスを宣言し、クラスメソッドを別のコンストラクターにポイントし(コンストラクター自体がメソッド関数であるため)、継承を実装します

function A(){
    this.name = {name1:'hello'};
    this.say = function (){ console.log(this.name);}
}
function B(){
    this.method = A;
    this.method();
    delete this.method;
}
 var bObj = new B();


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。