阮一峰博客,戳这里javascript
上一篇:JavaScript面向对象之二(构造函数继承)html
读了这三篇大佬的博客以后,忽然顿悟,继承说白了就是对原型链的拷贝(笨笨的),由于这一篇基本扒开了,最后直接赤裸裸的拷贝嘛。java
var Animal = {
type: 'animal'
}
var cat = {
name: 'po'
}
复制代码
这里是两个对象,而不是两个构造函数,这样来去继承就是非构造函数的继承,那么该怎么作呢?数组
先到这里,再再再提一次new作了哪些事,这个在理解继承中很重要!bash
//例如 new Animal()
var temp = {}
temp.__proto__ = Animal.prototype
Animal.call(temp)
return temp
复制代码
new主要是将实例的__proto__
指向了上级的prototype
。函数
而后来看看空对象继承是怎么作的?post
function object(obj){
function Fn(){} //建立了一个空函数
fn.prototype = obj //而后将要继承的obj放到空函数的prototype
return new Fn() //而后返回这个空函数的实例
}
复制代码
知道了上面这两点,咱们再来逐步分析ui
var xxx = object(Animal)
复制代码
执行object函数,传入Animal,咱们知道object函数返回的是里面空函数的实例,因此xxx.__proto__ = Fn.prototype
,而后Fn的prototype又是咱们的Animal,缘由是这一句fn.prototype = obj
,这样一来xx.__proto__ = Animal
。spa
作到这个地步以后,xxx没有的属性,就会经过自身的__proto__去上一层去找,就会找到Animal。这样一来就是集成父对象的属性了。prototype
这种方式就直接粗暴的去父对象里面的拷贝,我没有,我就直接从你身上拿就能够了。
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是一种介于浅拷贝和深拷贝之间的一种形式,千万不要把它当作深拷贝! 若是是正则、日期什么的就须要另行判断。好了,到这里就差很少了。
其实继承并非什么难题,无非两种:一种是我没有,就去你身上找;或者是从你身上拿到个人身上,这样我就有了。这样理解以后,基本就通了。最后感谢一波阮大佬~~