zoukankan      html  css  js  c++  java
  • 谈谈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]
                }            
            }
        }
    }
    都读到最后了、留下个建议如何
  • 相关阅读:
    awk,seq,xarg实例使用
    Docker安装yapi
    基于阿里搭载htppd访问
    锐捷结课作业
    基于centos7搭建kvm
    基于django实现简易版的图书管理系统
    python 自定义log模块
    Interesting Finds: 2008.01.13
    Interesting Finds: 2008.01.24
    Interesting Finds: 2008.01.17
  • 原文地址:https://www.cnblogs.com/linjunfu/p/10763765.html
Copyright © 2011-2022 走看看