看啥推荐读物
专栏名称: Pomelo1213
目录
相关文章推荐
今天看啥  ›  专栏  ›  Pomelo1213

JavaScript面向对象之三(非构造函数继承)

Pomelo1213  · 掘金  ·  · 2018-04-13 02:28

JavaScript面向对象之三(非构造函数继承)

阮一峰博客,戳这里

上一篇:JavaScript面向对象之二(构造函数继承)

读了这三篇大佬的博客之后,突然顿悟,继承说白了就是对原型链的拷贝(笨笨的),因为这一篇基本扒开了,最后直接赤裸裸的拷贝嘛。

什么是“非构造函数继承”?


var Animal = {
    type: 'animal'
}

var cat = {
    name: 'po'
}

这里是两个对象,而不是两个构造函数,这样来去继承就是非构造函数的继承,那么该怎么做呢?

利用空对象来继承


先到这里,再再再提一次new做了哪些事,这个在理解继承中很重要!

//例如 new Animal()
var temp = {}
temp.__proto__ = Animal.prototype
Animal.call(temp)
return temp

new主要是将实例的__proto__指向了上级的prototype

然后来看看空对象继承是怎么做的?

function object(obj){
    function Fn(){} //创建了一个空函数
    fn.prototype = obj //然后将要继承的obj放到空函数的prototype
    return new Fn() //然后返回这个空函数的实例
}

知道了上面这两点,我们再来逐步分析

var xxx = object(Animal)

执行object函数,传入Animal,我们知道object函数返回的是里面空函数的实例,所以xxx.__proto__ = Fn.prototype,然后Fn的prototype又是我们的Animal,原因是这一句fn.prototype = obj,这样一来xx.__proto__ = Animal

做到这个地步之后,xxx没有的属性,就会通过自身的__proto__去上一层去找,就会找到Animal。这样一来就是集成父对象的属性了。

浅拷贝继承


这种方式就直接粗暴的去父对象里面的拷贝,我没有,我就直接从你身上拿就可以了。

function extendCopy(p) {
var c = {};
for (var i in p) { 
        c[i] = p[i];
    }
    c.uber = p;
    return c;
}

这样会有一个问题,父对象属性里面是一个对象或者数组的时候机会出现问题,因为是浅拷贝,拷贝的是数组或者对象的引用,这样一来,继承的子对象,如果修改了这类属性,就会对父对象里面响应的属性产生影响,于是我们需要深拷贝。

深拷贝继承


function deepClone(child, father){
    var child = child || {}
    var toStr = Object.prototype.toString
    for(var key in father){
        if(father.hasOwnProperty(key)){
            if(typeof(father[key]) === 'object' && father[key] !== null){
                //Object.assign(child[key] = father[key].prototype.constructor === Array?[]:{}, father[key])
                if(toStr.call(father[key]) === '[object, Object]'){
                    child[key] = {}
                }else{
                    child[key] = []
                }
                deepClone(child[key], father[key])
            }else{
                child[key] = father[key]
            }
        }
    }
    return child
}

另外,Object.assign是一种介于浅拷贝和深拷贝之间的一种形式,千万不要把它当做深拷贝! 如果是正则、日期什么的就需要另行判断。好了,到这里就差不多了。

总结一下子


其实继承并不是什么难题,无非两种:一种是我没有,就去你身上找;或者是从你身上拿到我的身上,这样我就有了。这样理解之后,基本就通了。最后感谢一波阮大佬~~




原文地址:访问原文地址
快照地址: 访问文章快照