关于继承 (二)

非构造函数的继承

非构造函数的继承即对已经封装好的,而没有构造函数的对象进行继承,就像下面的两个对象:

var MyFriend = {
	rel : 'friend',
	toBefriend : function(){
		alert('Hello?');
	}
} 

var BeautyPerson = {
	name : 'qi',
	sex : 'girl',
	year : 22
}

如果我们想要让 BeatyPerson 继承 MyFriend 的属性和方法,这时候就需要利用非构造函数的继承。

object() 继承

object() 通过建立一个空的构造函数,重写子对象:

// 创建空构造函数 使父对象成为其原型对象
function object(o){
	function F(){};
	F.prototype = o;
	return new F();
}

var BeautyPerson = object(MyFriend);

// 添加子对象属性
BeautyPerson.name = 'qi';
BeautyPerson.sex = 'girl';
BeautyPerson.year = 22;

console.log(BeautyPerson.rel)		// friend

这种方式能够获取到父对象的原型链,继承的比较完备,但是它的缺点也是很明显的。对后面子对象的属性添加来说,它不能使用对象字面量的方式进行重写(对象字面量会指向新的对象)。更谈不上封装了。

拷贝

那我们只能执行另外的一种思路,即拷贝,也就是伪继承。拷贝可以分为浅拷贝和深拷贝。这里我们直接写深拷贝。深拷贝相对于浅拷贝来说就是完全复制对象属性中的值,防止拷贝指针,导致子对象对父对象篡改的可能性。而实现的方式也很简单,就是根据数据类型判断结果,递归调用浅拷贝。

function deepCopy(Super,Sub){
	var Sub = Sub || {};

	for(var key in Super){
		if(typeof Super[key] === 'object'){
			Sub[key] = (Super[key].constructor === Array) ? [] : {} ;
			deepCopy(Super[key],Sub[key]);	
		}else{
			Sub[key] = Super[key];
		}
	}

	Sub.uber = Super;
	return Sub;
}

BeautyPerson = deepCopy(MyFriend,BeautyPerson);
console.log(BeautyPerson);
BeautyPerson.toBefriend();

这种方式可以解决 object() 出现的封装问题,但是这种方法并没有继承父对象的原型链,而是将父对象所有的可遍历属性和方法进行拷贝。for in 遍历效率较低,当原型链较长的时候耗费时间严重。

posted @ 2017-08-13 16:54  我是一个毛毛虫  阅读(93)  评论(0编辑  收藏  举报