• 谈谈JavaScript中继承方式


    聊一聊js中的继承
    一、简单继承---使用原型赋值的方式继承,将实例化的对象,赋值给子级的原型
    父级构造函数
    function Parent(param) {
        this.name = 'parent'
        this.otherName = 'otherName'
        this.param = param || 'param'
    }
    Parent.prototype.sayName = function() {
        console.log('this.name :', this.name)
    }
    子级构造函数
    function Son() {
        this.name = 'son'
    }
    Son.prototype = new Parent() // 继承
    
    
    let newSon1 = new Son()
    let newSon2 = new Son()
    
    console.log('newSon1 :', newSon1)                   // newSon1 : Parent { name: 'son' }
    // newSon1 : Parent { name: 'parent', otherName: 'otherName' } // newSon1.__proto__ 指向构造函数 Son 的原型 prototype
    console.log('newSon1 :', newSon1.__proto__)         
    // newSon1.__proto__ 指向构造函数 Son 的原型 prototype
    // Son 的 prototype 赋值为 new Parent(),所以 Son 的构造函数不是自己,而是 Parent
    // newSon1.__proto__.constructor : function Parent() {
    //     this.name = 'parent'
    //     this.otherName = 'otherName'
    // }
    console.log('newSon1.__proto__.constructor :', newSon1.__proto__.constructor)         
    
    console.log('newSon2 :', newSon2)                   // newSon1 : Parent { name: 'son' }
    // newSon2 : Parent { name: 'parent', otherName: 'otherName' } // newSon2.__proto__ 指向构造函数 Son 的原型 prototype
    console.log('newSon2 :', newSon2.__proto__)         
    
    // 修改 newSon1 继承而来的 otherName 属性, newSon2也发生了变化
    newSon1.__proto__.otherName = 'son1-OtherName'
    console.log('newSon1.otherName :', newSon1.otherName)
    console.log('newSon2.otherName :', newSon2.otherName)

    缺点:

    所有的实例化对象会共享属性,对于任一个属性的修改,其他的实例化对象都会同步变化
    子级的构造函数也不是自己,需要重新指定
    二、经典继承---改变this指向到当前的实例化对象
    父级构造函数
    function Parent() {
        this.name = 'parent'
        this.otherName = 'otherName'
    }
    Parent.prototype.sayName = function() {
        console.log('this.name :', this.name)
    }
    子级构造函数
    function Son(param) {
        Parent.call(this, param) // 继承
    }
    缺点:
    解决了上面提到的属性共享问题
    新问题出来了,需要将方法定义在构造函数内部,否则无法被继承,
    每实例化一次,构造函数里面的函数方法就创建一次,对资源是一个浪费
    三、组合继承
    使用call/apply方法进行属性的继承
    用原型链继承的方法,继承原来的所有函数方法
    父级构造函数
    function Parent() {
        this.name = 'parent'
        this.otherName = 'otherName'
    }
    Parent.prototype.sayName = function() {
        console.log('this.name :', this.name)
    }
    子级构造函数
    function Son(param) {
        Parent.call(this, param)
    }
    Son.prototype = Parent.prototype  
    Son.prototype.constructor = Son // 修改构造函数为自己
    缺点:
    因为是使用赋值引用的模式进行原型继承,
    如果子级重写父级的某个属性或方法,父级也会发生改变
    四、组合继承+深拷贝
    父级构造函数
    function Parent() {
        this.name = 'parent'
        this.otherName = 'otherName'
    }
    Parent.prototype.sayName = function() {
        console.log('this.name :', this.name)
    }
    子级构造函数
    function Son(param) {
        Parent.call(this, param)
    }
    深拷贝原型链
    deepCopy(Son.prototype, Parent.prototype)
    Son.prototype.constructor = Son // 修改构造函数为自己
    function deepCopy(target, obj) {
        for (const prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                if (typeof obj[prop] === 'object') {
                    target[prop] = Object.prototype.toString.call(obj[prop]) === '[object Array]' ? [] : {}
                    deepCopy(target[prop], obj[prop])
                } else {
                    target[prop] = obj[prop]
                }            
            }
        }
    }
    都读到最后了、留下个建议如何
  • 相关阅读:
    智能指针之第二印象
    网易实习笔试真题C/C++
    map,hash_map和unordered_map 实现比较
    斐波那契堆(一)之 图文解析 和 C语言的实现
    二项堆(一)之 图文解析 和 C语言的实现
    寻找最小的k个数
    P、NP、NP-Complete、NP-hard问题
    网易有道笔试:求连通图的割点(关节点)
    块设备的读流程分析
    不相交集(The Disjoint Set ADT)
  • 原文地址:https://www.cnblogs.com/linjunfu/p/10763765.html
Copyright © 2020-2023  润新知