JavaScript组合继承的一点思考

今天看《JavaScript高级程序设计》一书中关于组合继承模式时,书上有这么一个Demo程序:

<html>
<head>
</head>
<body>
<script>
	function SuperType(name){
		this.name = name;
	}
	SuperType.prototype.sayName = function(){
		alert(this.name);
	};
	function SubType(name, age){
		SuperType.call(this, name);
		this.age = age;
	}
	SubType.prototype = new SuperType();//SuperType.prototype;
	SubType.prototype.sayAge = function(){
		alert(this.age);
	};
	var instance1 = new SubType("Nicholas", 29);
	instance1.sayName();
	instance1.sayAge();

	//var instance2 = new SuperType("Greg", 27);
	//instance2.sayAge();
</script>
</body>
</html>

其中的SubType.prototype = new SuperType()让我产生了疑问,这个语句的目的不就是要让子类型的原型指向父类型的原型实例吗?为什么不直接写出SubType.prototype = SuperType.prototype呢?为何非要new一个出来?

仔细考虑之后,我把Demo做了如下的修改,弄清楚了这么做的理由何在:

<html>
<head>
</head>
<body>
<script>
	function SuperType(name){
		this.name = name;
	}
	SuperType.prototype.sayName = function(){
		alert(this.name);
	};
	function SubType(name, age){
		SuperType.call(this, name);
		this.age = age;
	}
	SubType.prototype = SuperType.prototype;
	SubType.prototype.sayAge = function(){
		alert(this.age);
	};
	var instance1 = new SubType("Nicholas", 29);
	instance1.sayName();
	instance1.sayAge();

	var instance2 = new SuperType("Greg", 27);
	instance2.sayAge();
</script>
</body>
</html>

运行以后会发现instance2.sayAge弹出的提示是undefined,也就是说我们在为子类型的添加一个子类型想要持有的方法sayAge时,不小心也污染了父类型,使得父类型也同样拥有了sayAge方法,而父类型根本不具有age属性,当然就会提示这个属性undefined了,这些奇怪现象出现的原因就是直接使用了SubType.prototype = SuperType.prototype造成的。如果你把这句换成SubType.prototype = new SuperType()的话再去调用sayAge方法就会执行出错,因为父类型这时候并没有这个方法(没有被子类型污染),所以说使用new是非常科学合理的。

JavaScript组合继承的一点思考

时间: 2024-08-26 20:00:54

JavaScript组合继承的一点思考的相关文章

javascript组合继承

javascript继承有几种继承方式,现在来说说其中的组合继承. 组合继承是结合了原型链和借用构造函数这两种技术的继承方式,分别利用它们的长处,避免了短处.那就先说说这两种技术吧. 原型链  原型链就是实例与原型之间的链条. 子类型构造函数   与  超类型构造函数  之间没有关联,只需将   子类型构造函数的原型  作为  超类型构造函数的实例.这样,子类型构造函数的实例   就可以共享    超类型构造函数原型的方法  以及  超类型构造函数的属性. 如: var subType.prot

JavaScript ----------- 组合继承

继承 实现继承:继承实际的方法.ECMAScript 只支持实现继承,而且其实现基础主要是依靠原型链来实现的. 基本思想是:利用原型来实现一个引用类型继承另外一个引用类型的属性和方法. 原型 - 构造函数 - 实例 之间的关系 构造函数(prototype) <-------> 原型(constructor) <------- 实例(_proto_) 实现原型链有一种基本模式,其代码大致如下 1 function SuperType(){ 2 3 this.property = true

Javascript 组合继承 原型链继承 寄生继承

Javascript继承通常有三种方式. 第一种:组合式继承: function SuperType(name) { this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function() { console.log(this.name); }; function SubType(name, age) { //通过ca

Javascript之对象组合继承

感悟: 最近看了一些关于Javascript对象继承的知识,发现自己之前虽然看了一些书,但是很多知识都忘了.虽然很多东西都忘了,但再次看的过程中对这些东西不会再向刚接触时那么陌生,而且理解起来也比之前顺畅和透彻多了. 充分说明:多看书是有意义的. ————————————————————————————————————————————————————————————————————————————————————————————碎碎念 关于对象之间的继承,在Javascript中主要是通过原型对

JavaScript中的继承之组合继承

组合继承,又叫伪经典继承. 顾名思义,集原型链与构造函数之长,将两者结合在一起,使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承.这样既通过在原型上定义方法实现了函数复用,又能保证每个实例都有自己的属性. 来看一个例子. function superType(){ this.name = name; this.colors = ["red","blue","green"]; } superType.prototype.

JavaScript各种继承方式(六):寄生组合继承

一 原理 用寄生继承来改造组合继承. function Fruit(name){ this.name = name; } Fruit.prototype.eat = function(){ console.log('eat'); } function Mango(name,level){ Fruit.call(this,name); this.level = level; } function create(obj){ let instance = Object.create(obj); //

关于模板方法和策略模式的一点思考

该随笔的思想原点,应该算是在两三年前了.当时和一前同事聊天.不知怎得就聊到了Http访问. 一.我记得他和我说过的第一句话,大概是:有没有已经封装好的.比较强大的HttpUtil.也可能是受业务的影响(接口对内).我当时接触到的Http访问,大多比较“规范”,至少有一个接口约束在约定着某些东西,不至于一会传递json,返回json, 一会又要传递xml,返回xml,甚至更奇葩的是,上传个文件.返回0或者1.如果真出现这样的状态,HttpUtil依然能够方便.灵活的适应着各种情况.我想这个Util

JavaScript之继承(原型链)

我们知道继承是oo语言中不可缺少的一部分,对于JavaScript也是如此.一般的继承有两种方式:其一,接口继承,只继承方法的签名:其二,实现继承,继承实际的方法.JavaScript不支持签名,因此只有实现继承.其中实现继承主要是依赖于原型链的.下面我将以原型链为重点说说继承的几种主要的方式: 原型链继承 借用构造函数继承 组合继承(重点) 第一部分:原型链继承 A 要说原型链继承,不得不首先介绍一下原型链的概念. 想象一下,如果使原型对象等于另一个对象的实例,则此时原型对象将包含一个指向另一

JavaScript实现继承的几种方式总结一

虽然在ES6中有了继承,使用extends关键字就能实现.本篇讲的不是这种,而是ES6之前的几种实现继承的方式. (一)原型链 ECMAScript中将原型链作为实现继承的主要方法.其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.(不理解原型链的童鞋们可以翻阅一下我之前的博客,里面有详细的说明) 实现原型链的一种基本模式 function SuperType(){ this.prototype=true; } SuperType.prototype.getSuperValue=