Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS继承的几种方法 #35

Open
conan1992 opened this issue Jun 22, 2020 · 1 comment
Open

JS继承的几种方法 #35

conan1992 opened this issue Jun 22, 2020 · 1 comment

Comments

@conan1992
Copy link
Owner

No description provided.

@conan1992
Copy link
Owner Author

conan1992 commented Jun 22, 2020

原型链继承

其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。

function SuperType(){ 
	this.property = "super"; 
}
SuperType.prototype.getSuperValue = function(){ 
	return this.property; 
}; 
function SubType(){ 
	this.subproperty = "sub"; 
} 
//继承了 SuperType 
SubType.prototype = new SuperType(); 
SubType.prototype.getSubValue = function (){ 
	return this.subproperty; 
}; 
var instance = new SubType(); 
console.log(instance.getSuperValue()); //"super"

缺点

  • 引用类型值的原型属性会被所有实例共享
  • 在创建子类型的实例时,不能向超类型的构造函数中传递参数。实际上,应该说是没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数。
function SuperType(){ 
    this.colors = ['green','yellow','red'] 
}
function SubType(){ 
} 
//继承了 SuperType 
SubType.prototype = new SuperType(); 
var instance1 = new SubType();
var instance2 = new SubType();
instance1.colors.push("blue");
console.log(instance2.colors); // ["green", "yellow", "red", "blue"]

借用构造函数

function SuperType(){ 
	this.colors = ["red", "blue", "green"]; 
} 
function SubType(){ 
	//继承了 SuperType 
	SuperType.call(this); 
} 
var instance1 = new SubType(); 
instance1.colors.push("black"); 
console.log(instance1.colors); //"red,blue,green,black" 
var instance2 = new SubType(); 
console.log(instance2.colors); //"red,blue,gree

优点

  • 可以传递参数
function SuperType(name){ 
    this.name = name;
} 
function SubType( name ){ 
 //继承了 SuperType 
 SuperType.call(this, name); 
} 
var instance1 = new SubType("布加拉提"); 

console.log(instance1.name); //"布加拉提" 

缺点

  • 方法都在构造函数中定义,因此函数复用就无从谈起

组合继承

function SuperType(name){ 
	this.name = name; 
	this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function(){ 
	console.log(this.name); 
}; 
function SubType(name, age){ 
	//继承属性
	SuperType.call(this, name); 
 
	this.age = age; 
} 
//继承方法
SubType.prototype = new SuperType(); 
SubType.prototype.constructor = SubType; 
SubType.prototype.sayAge = function(){ 
	console.log(this.age); 
}; 
var instance1 = new SubType("Nicholas", 29); 
instance1.colors.push("black"); 
console.log(instance1.colors); //"red,blue,green,black" 
instance1.sayName(); //"Nicholas"; 
instance1.sayAge(); //29 
var instance2 = new SubType("Greg", 27); 
console.log(instance2.colors); //"red,blue,green" 
instance2.sayName(); //"Greg"; 
instance2.sayAge(); //27

优点

  • 结合了原型链和构造函数继承的优点,而且,instanceof 和 isPrototypeOf()也能够用于识别基于组合继承创建的对象。

原型式继承

function object(o){ 
 function F(){} 
 F.prototype = o; 
 return new F(); 
}
//Object.create()

寄生式继承

在原型式继承的基础上,添加方法,使用寄生式继承来为对象添加函数,会由于不能做到函数复用而降低效率;这一点与构造函数模式类似。

function createAnother(original){ 
 var clone = object(original); //通过调用函数创建一个新对象
 clone.sayHi = function(){ //以某种方式来增强这个对象
 alert("hi"); 
 }; 
 return clone; //返回这个对象
} 

寄生组合模式

组合模式是最常用的继承方式,但缺点是都调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部:

function SuperType(name){ 
 this.name = name; 
 this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function(){ 
 alert(this.name); 
}; 
function SubType(name, age){ 
 SuperType.call(this, name); //第二次调用 SuperType() 
 
 this.age = age; 
} 
SubType.prototype = new SuperType(); //第一次调用 SuperType() 
SubType.prototype.constructor = SubType; 
SubType.prototype.sayAge = function(){ 
 alert(this.age); 
};

那么怎么优化呢?
我们用寄生式继承来继承超类型的原型:

function inheritPrototype(subType, superType){ 
 var prototype = object(superType.prototype); //创建对象
 prototype.constructor = subType; //增强对象
 subType.prototype = prototype; //指定对象
}
function SuperType(name){ 
 this.name = name; 
 this.colors = ["red", "blue", "green"]; 
} 
SuperType.prototype.sayName = function(){ 
 alert(this.name); 
}; 
function SubType(name, age){ 
 SuperType.call(this, name); 
 
 this.age = age; 
} 
inheritPrototype(SubType, SuperType); 
SubType.prototype.sayAge = function(){ 
 alert(this.age); 
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant