非构造函数的继承
1. 什么是“非构造函数”的继承?
例如:
var Cat = {
name : '',
color : ''
}
还有一个对象,叫做 “医生”
var cat1 = {};
cat1.name = '大毛';
cat1.color = '黄色';
var cat2 = {};
cat2.name = '二毛';
cat2.color = '黑色';
因为医生很有可能就是中国人,那么如何让医生去继承中国人呢?
也即:两个对象都是普通的对象,不是构造函数,无法使用构造函数的方式来实现继承。
2. object() 方法
Douglas Crockford 提出了一个函数,可以做到这一点,原理有点类似于构造函数继承中的,利用空对象做中介 继承
function Cat(name,color){
return {
name : name,
color : color
}
}
这个函数的左右就是利用一个中介来将子对象的 prototype 对象指向父对象,从而通过子对象的原型链使其连到了一起。因为普通对象其prototype为未定义,所以不能直接对其赋值来实现继承。
使用:
var cat1 = Cat('大毛','黄色');
var cat2 = Cat('二毛','黑色');
3. 浅拷贝
类似于上一节的拷贝继承,只不过这里直接拷贝的是对象的属性。
function Cat(name,color){
this.name = name;
this.color = color;
}
使用:
var cat1 = new Cat('大毛','黄色');
var cat2 = new Cat('二毛','黑色');
但是,与原型继承类似,这里也存在假如父对象的属性等于数组或对象的话,那么实际上只是一个内存地址,不是拷贝,所以如果修改了子对象,那么父对象也会被修改,这样是不可以的。
例如:
console.log(cat1 instanceof Cat); //true
console.log(cat2 instanceof Cat); //true
看,Chinese 的东西也被改掉了,同时继承 Chinese 的所有对象的此属性,都被改掉了,而这是多么打的问题啊。
这是 jQuery 早期实现继承的方式,其只能拷贝基本类型的数据。也即是“浅拷贝”。
4. 深拷贝
其实深拷贝也来源于浅拷贝,只是对于属性值是否是基本类型进行判断,如果非基本类型的数据,继续调用即可,也就是递归的浅拷贝就行了。
function Cat(name,color){
this.name = name;
this.color = color;
this.type = '猫科动物';
this.eat = function(){console.log('吃老鼠');}
}
使用:
var cat = Cat('大毛','黄色');
console.log(cat.type); // 猫科动物
cat.eat(); // 吃老鼠。
目前,jQuery 就使用的是这种方法。
没有评论