js继承

js继承

1.原型链继承

将构造函数的原型设置为另一个构造函数的实例对象,这样就可以继承这个实例对象的所有属性和方法,然后就可以根据原型链继续往上寻找属性和方法。

	//父类
    function Father() {
        this.color = ['red', 'green', 'blue']; //设置属性
    }
    
    //子类
    function Son() {
    }
    
    Son.prototype = new Father(); //创建父类的实例,赋给子类的原型
    
    var gSon1 = new Son();

    gSon1.color.push('black');

    console.log(gSon1.color); //red, green, blue, black
    
    var gSon2.color = new Son();
    
    console.log(gSon2.color); //red, green, blue, black
优点:
 - 简单,易于实现
缺点:
 - 引用类型的原型属性会被所有实例共享
 - 创建子类时,无法向父类构造函数传参

2.构造函数继承

在子类型构造函数的内部调用超类型构造函数。(只要把Son.prototype的构造函数换成其他的,而不是默认的Object(),那Son便成为了那个类的子类;这就实现了自己定义的超类和子类关系。 当然Son还是Object的子类,但那是因为那个类最终也是Object的子类。 )

	function Father(name){
        this.name = name;
        this.color = ['red', 'green', 'blue'];
    }
    
    function Son() {
        Father.call(this, 'Tom');
        this.size = 'big';
    }
    
    var instance1 = new Son();
    instance1.color.push('black');
    console.log(instance1.color); //red, green, blue, black
    
    var instance2 = new Son();
    console.log(instance2.color); //red, green, blue
    
    console.log(instance1.name);//Tom
    console.log(instance2.size);//big
优点:
 - 可以向父类传递参数
 - 解决了子类实例共享引用属性的问题
缺点:
 - 无法实现函数复用。方法都是在父类的原型中定义方法,对于子类而言是不可见的

3.组合式继承(最常用)

将原型链和构造函数的技术组和到一块。即通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。

	function Father(name){
        this.name = name;
        this.color = ['red', 'green', 'blue'];
    }
    
    Father.prototype.sayName = function() {
        alert(this.name);
    }
    
    function Son(name){
        Father.call(this, name);//继承属性
    }
    
    Son.prototype = new Father(); //继承方法
    
    var gSon1 = new Son('Tom');
    gSon1.color.push('black');
    console.log(gSon1.color);//red, green, blue, black
    gSon1.sayName();//Tom
    
    var gSon2 = new Son('Jerry');
    console.log(gSon2.color);//red, green, blue
    gSon2.sayName();//Jerry
优点:
 - 不存在引用属性共享问题
 - 可以传参
 - 函数可复用
缺点:
 - 父类构造函数被调用了两次

4.原型式继承

借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。

	function object(o) {
        function F(){};
        F.prototype = o;
        return new F();
    }
    //在object函数内部,先创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。
    //本质上来说,object对传入其中的对象执行了一次浅复制。
    function Person() {
        this.name = 'Tom';
        this.color= ['red', 'green', 'blue'];
    }
    
    var instance = new Person();
    
    var anotherPerson = object(instance);
    
    anotherPerson.age = 18;
    anotherPerson.color.push('black');
    
    console.log(anotherPerson.name);//Tom
    console.log(anotherPerson.color);//red, green, blue, black
    console.log(anotherPerson.age);//18
优点:
 - 从已有对象衍生新对象,不需要创建自定义类型
缺点:
 - 原型引用属性会被所有实例共享,因为是用整个对象来充当子类原型对象
 - 无法实现代码复用

5.寄生式继承

寄生式继承是创建一个仅用于封装继承过程的函数。

	function createAnother(original) {
        var clone = object(original); //通过调用函数创建一个新对象
        //object原型式继承种创建的函数
        clone.sayHi = function() {//添加方法
            alert('Hi');
        }; 
        return clone; //返回这个对象
    }
    
    var person = {
        name: 'Venciki',
        color: ['yellow', 'black', 'white']
    };
    
    var anotherPerson = createAnother(person);
    anotherPerson.sayHi(); //Hi
优点:
 - 跟原型式继承一样,简单易于实现,不需要创建自定义类型
缺点:
 - 无法实现函数复用

6.寄生组合式继承(最佳方式)

 //寄生组合式继承的基本模式
    function inheritPrototype(subType, superType) {
        var prototype = object(superType.prototype); //创建对象(object为原型式继承里面的方法)
        //object原型式继承种创建的函数
        prototype.constructor = subType; //增强对象
        subType.prototype = prototype; //指定对象
    }

在此函数内部,第一步式创建父类型原型的一个副本;第二步是为创建的副本添加constructor属性,从而弥补因重写原型而失去默认的constructo属性;最后一步,将创建的对象(即副本)赋值给子类型的原型。这样我们就可以用调用inheritPrototype()函数的语句,去替换前面例子中为子类原型赋值的语句。

	function SuperType(name) {
        this.name = name;
        this.color = ['red', 'green', 'blue'];
    }
    
    SuperType.prototype.sayName = function() {
        alert(this.name);
    }
    
    function SubType() {
        SuperType.call(this, 'Tom');
    }
    
    inheritPrototype(SubType, SuperType);
    
    var instance = new SubType();
    instance.color.push('black');
    console.log(instance.name);//Tom
    console.log(instance.color);//red, green, blue, black

    instance.sayName();//Tom
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值