前端继承

感情迁移 提交于 2020-10-08 02:22:04

一、原型链继承:

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

优点:能通过instanceOf和isPrototypeOf的检测

注意:给原型添加方法的语句一定要放在原型替换SubType.prototype = new SuperType();之后

缺点:(1)SuperType中的属性(不是方法)也变成了SubType的prototype中的公用属性,
     如上面例子中的color属性,可以同时被instance1和instance2修改
     (2)创建子类型的时候,不能像父类型的构造函数中传递参数。

二、借用构造函数继承

function father(){
    this.name="张飞"
}
function son(){
    father.call(this);
}
var son1=new son();
son1.name='hale';
console.log(son1.name)//hale
var son2=new son();
console.log(son2.name)//张飞


 
function father(name){
    this.name = name;
}
function son(){
    //继承了father,同时还传递了参数
    father.call(this, "Nicholas");
    //实例属性
    this.age = 29;
}
var instance = new son();
alert(instance.name); //"Nicholas";
alert(instance.age); //29

原理:在子类型构造函数的内部调用超类型构造函数
优点:解决了father中的私有属性变公有的问题,可以传递参数
缺点: 方法都在构造函数中定义,每次创建实例都会创建一遍方法,不能复用,然后就出现了下面这种-- 组合继承

三、组合继承:  


function father(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
father.prototype.sayName = function(){
    alert(this.name);
};
function son(name, age){
    father.call(this, name);//借用构造函数继承属性,二次调用
    this.age = age;
}
son.prototype = new father();//借用原型链继承方法,一次调用
son.prototype.constructor = son;
son.prototype.sayAge = function(){
    alert(this.age);
};
var instance1 = new son("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new son("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";

优点:继承前两者的优点,能通过instanceOf和isPrototypeOf的检测
缺点:两次调用父构造器函数,浪费内存。

四、原型式继承:


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

  使用场合:没必要构建构造函数,仅仅是想模拟一个对象的时候

  五、寄生继承:

function createAnother(original){
    var clone = Object.create(original); //通过调用函数创建一个新对象
    clone.sayHi = function(){ //以某种方式来增强这个对象
        alert("hi");
    };
    return clone; //返回这个对象
}
var person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); //"hi"

缺点:方法在函数中定义,无法得到复用

  六:寄生组合继承(最理想):


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);
};

比较简单的介绍网站 https://www.bilibili.com/read/cv6150071

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!