• js继承详解


    一、原型链继承

    function a() {
        this.speack = function () {
            console.log('第一个元素');
        }
    }
    function b() {
        this.ask = function () {
            console.log('第二个元素');
        }
    }
    b.prototype = new a();
    b.prototype.constructor = b;   //b的prototype的constructor重新改写为它自身
    let c = new b();
    c.speack();
    
    定义:构造函数在创建实例前,将它的原型设置为另一个构造函数的实例,这样创建的实例可以通过原型链继承属性和方法,称为原型链继承。

    特点:1、构造函数可以继承父元素的属性和方法,但是构造函数只有一个prototype,所以只能单继承,不能多继承。

       2、构造函数的原型上的属性在继承的实例上改变时,其他实例上的原型属性也会改变。

    特点2代码解释:

    function a() {
        this.speack = function () {
            console.log('第一个元素');
        }
        this.arr=[1,2,3]
    }
    function b() {
        this.ask = function () {
            console.log('第二个元素');
        }
    }
    b.prototype = new a();
    b.prototype.constructor = b;
    let c = new b();
    let d = new b();
    c.arr.push(4);
    console.log(c.arr);
    console.log(d.arr);
    

    可以看见c实例改变arr属性,d实例上的arr属性也改变,可以这样理解,c、d都是b的实例,c、d查找arr属性时,通过__proto__查找到b的prototype,然后c修改b的prototype中的arr属性,当打印d的arr属性时,d会查找__proto__找到b的prototype,找到的是c修改的arr属性,所以c、d的arr属性是一致的,这就是原型链继承的缺陷。

    二、借用构造继承

    function a1() {
        this.speack = function () {
            console.log('第一个元素');
        }
    }
    function b1() {
        a1.call(this, '借用构造继承');
    }
    let c1 = new b1();
    c1.speack();
    
    定义:构造函数内部使用call/apply/bind,执行另一个函数,将这个函数的属性和方法通过this赋值给构造函数,称为借用构造继承。可以使用apply、bind、call继承多个。
    特点:1、借用构造继承可以向构造函数传参数。
       2、借用构造继承只能继承函数中的属性,不能继承函数原型中的属性,所以不能实现复用。
       3、可以实现多继承。
    三、组合继承
    function a2() {
        this.speack = function () {
            console.log('第一个元素')
        }
    }
    function b2() {
        a2.call(this);
    }
    b2.prototype = new a2();
    b2.prototype.constructor = b2;
    let c2 = new b2();
    c2.speack();
    

    定义:函数将原型链继承和借用构造继承组合在一起。

    特点:1、可以继承构造函数的属性和原型,并且一个实例修改继承属性后,不会影响其他的实例。

       2、可以继承原型,所以能实现函数的复用。

    四、原型式继承

    function a3(obj) {
        let fn = function () { }
        fn.prototype = obj;
        return new fn();
    }
    function b3() {
    
    }
    let c3 = new b3();
    let d3 = a3(c3);

    特点:1、跟原型链继承缺陷一样,其中一个实例修改原型上的属性,其它实例上的原型属性也会改变,也就是原型共享。

    五、寄生式继承

    function a4(obj) {
        let fn = function () { }
        fn.prototype = obj;
        return new fn();
    }
    function b4() {
    
    }
    function c4(arg) {
        let obj = a4(arg);
        obj.name = 'custom';
        return obj
    }
    let d4 = new b4();
    let e4 = c4(d4);
    console.log(e4.name)
    

    特点:1、跟原型链继承缺陷一样,其中一个实例修改原型上的属性,其它实例上的原型属性也会改变,也就是原型共享。

       2、可以在构造函数上添加自定义属性。

    六、寄生组合继承

    function a5(arg) {
        let obj = function () {
    
        }
        obj.prototype = arg;
        return obj
    }
    function b5() { }
    const c5 = a5(b5.prototype)
    function d5() {
        b5.call(this)
    }
    d5.prototype = c5;
    d5.prototype.constructor = d5;
    let e5 = new d5();
    console.log(e5.name)
    

    特点:1、修复原型共享带来的问题。

       2、可以实现参数的复用。

  • 相关阅读:
    Java Web表达式注入
    Mysql:The Federated Storage Engine:联合(联盟)存储引擎:【远程连接】服务器引擎
    Mysql:16.11.1 Pluggable Storage Engine Architecture
    Mysql:Server Logs:mysqld服务器的各种日志
    Mysql:InnoDB Table Compression and InnoDB Page Compression:适用于InnoDB的:表压缩 & 页压缩
    Mysql:Redo Log
    kubectl相关指令
    使用alias简化kubectl输入
    使用Minikube运行一个本地单节点Kubernetes集群(阿里云)
    Javascript去掉base64中的回车换行
  • 原文地址:https://www.cnblogs.com/uimeigui/p/14439948.html
Copyright © 2020-2023  润新知