JS之理解组合继承模式和寄生式组合继承的区别

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title</title>
</head>
<body>
<script type="text/javascript">
//test 组合继承
function SuperType(name) {
	this.name = name;
	this.colors = ["red","green","black"];
};

SuperType.prototype.sayName = function() {return this.name};

function SubType(name, age) {
	SuperType.call(this, name);
	this.age = age;
};

SubType.prototype = new SuperType(null);
SubType.prototype.sayAge = function () {return this.age};

var sub = new SubType("oyxb", 25);
sub.colors.push("grey");
console.log(sub.colors);
delete sub.colors;
console.log(sub.colors);
delete SubType.prototype.colors;
console.log(sub.colors);
console.log(sub.sayName());
console.log(sub.sayAge());
delete sub.name;
console.log(sub.sayName());
delete sub.age;
console.log(sub.sayAge());

//组合继承的缺点:需要两次调用superType的构造函数,从而导致name和colors属性冗余,在subType中存在一份,在superType中又存在一份,只不过是sub把super里的属性覆盖了

//采用寄生组合继承模式可以解决上述问题
function object(o) {
	function F(){};
	F.prototype = o;
	return new F(); 
	/*通过构造一个介于superType与subType之间的对象,并使该对象的prototype属性指向superType prototype对象,来避开通过调用superType构造函数的方式来产生一个prototype指向superType prototype对象的对象。有点绕,好好理解*/
};

function inheritPrototype(Sub, Super) {
	/*这里为何需要调用object函数去构造一个新的对象,而不直接让Sub.prototype=Super.prototype呢?原因是如果这么做的话,当我们想给Sub的prototype里面添加共享属性或者方法时,如果其prototype指向的是Super的prototype,那么在Sub的prototype里添加的属性和方法也会反映在Super的prototype里面,这明显是不合理的,这样做的后果是当我们只想使用Super时,也能看见Sub往里面扔的方法和属性。所以需要每个构造函数都需要持有自己专用的prototype对象。*/
	var prototype = object(Super.prototype);
	prototype.constructor = Sub;
	Sub.prototype = prototype;
};

function Super(name) {
	this.name = name;

	if(typeof Super.prototype.sayName != "function") {
		Super.prototype.sayName = function () { console.log(this.name)};
	};
}

function Sub(name, age) {
	Super.call(this, name);
	this.age = age;

	if(typeof Super.prototype.sayAge != "function") {
		Super.prototype.sayAge = function () { console.log(this.age)};
	};
};

inheritPrototype(Sub, Super);

var sub = new Sub("bobo", 26);
sub.sayAge();
sub.sayName();
console.log("typeof sub:" + typeof sub);
delete sub.name;
sub.sayName();//undifined
sub.sayAge();
</script>
</body>
</html>

你可能感兴趣的:(JS之理解组合继承模式和寄生式组合继承的区别)