构造继承
function SuperType() {
this.colors = ['red', 'green', 'blue']
}
function ChildType() {
SuperType.call(this);
}
let instance1 = new ChildType();
instance1.colors.push('yellow');
console.log(instance1.colors); // ["red", "green", "blue", "yellow"]
let instance2 = new ChildType();
console.log(instance2.colors); // ["red", "green", "blue"]
通过使用call()方法,我们实际上是在新创建的ChildType实例的环境下调用了SuperType,这样就会在新的ChildType的实例上执行SuperType中的初始化代码,这样每个实例都会有自己的colors属性副本。而借助构造函数相比于借用原型链的一大优势就是,子类型构造函数可以向超类型构造函数传递参数。
function SuperType(name) {
this.name = name;
}
function ChildType(name) {
SuperType.call(this, name);
}
let instance1 = new ChildType('Nick');
console.log(instance1.name); // 'Nick'
原型继承
Dog.prototype = Object.create(Cat.prototype);// 寄生继承
// Object.create()用于创建一个空对象,并把该对象的[[Prototype]]链接到Cat.prototype
实例继承
var Base = function()
{
this.level = 1;
this.name = "base";
this.toString = function(){
return "base";
};
};
Base.CONSTANT = "constant";
var Sub = function()
{
var instance = new Base();
instance.name = "sub";
return instance;
};
优点:是父类的对象,并且使用new构造对象和不使用new构造对象,都可以获得相同的效果。
缺点:生成的对象实质仅仅是父类的实例,并非子类的对象;不支持多继承。
拷贝继承
var Base = function()
{
this.level = 1;
this.name = "base";
this.toString = function(){
return "base";
};
};
Base.CONSTANT = "constant";
var Sub = function()
{
var base = new Base();
for(var i in base)
Sub.prototype[i] = base[i];
Sub.prototype["name"] = "sub";
};
混合继承
构造函数继承和原型链继承结合
function Cat(n,c){
this.name = n;
this.color = c;
this.say = function (){
console.log('卖萌~');
}
return {a:1,b:2}
}
Cat.prototype.type = 'animal';
Cat.prototype.skill = function (){
alert('抓老鼠');
}
function Dog(f,n,c){
this.food = f;
Cat.call(this,n,c);//构造函数继承
}
Dog.prototype = Object.create(Cat.prototype);//原型继承
Dog.prototype.constructor = Dog;//手动指正构造器
var dog1 = new Dog('shi','小花','red');
console.log( dog1.food );
console.log( dog1.name );
dog1.say();
dog1.skill();