问题描述
我在网上看到call的用法时,他这样写道: “应用call和apply更有一个技巧在里面,就是用call和apply应用另一个函数(类)以后,当前的函数(类)就具有了另一个函数(类)的方法或是属性,这也能称之为“继承”。” 于是我用下面的这段代码做了实验:得出了下面结论:1、确实能够起到继承的作用。2、给原型里添加的属性和方法为什么继承不到? 第二点我百思不得其解,希望哪位高高手帮我解答下。以下便是我实验代码:<script type="text/javascript"> function Base(){ this.name = "base";this.age = 25;this.sayName = function(){alert(this.name);}; } Base.prototype.sayAge = function(){alert(this.age)}; function Extend(){ //继承 Base.call(this);//覆盖this.name = "extend"; } var e = new Extend(); var b = new Base(); e.sayName(); //正常。“extend” //e.sayAge(); //会报错。 b.sayAge(); //正常。 b.sayName(); //正常。</script>问题补充 昨天晚上回去看了下《JavaScript高级程序设计(第2版)》,正巧是你推荐的那本。自认为弄懂了个大概,今日看兄台所写,觉得我有必要再看一次。 因为我昨天也看到了“组合继承模式”就是“原型继承模式”和“构造函数继承模式”的组合(不知对否?),却没联想到这上面来。
解决方案
具体解释看我加的代码注释:<script type="text/javascript"> function Base(){ this.name = "base";this.age = 25;this.sayName = function(){alert(this.name);}; } Base.prototype.sayAge = function(){alert(this.age)}; function Extend(){ /* 此处是将Base()当成一个普通的函数来调用,而不是把它当做父类的构造函数; Base.call(this);实际是将Extend的作用域指定给Base()函数,也就是给Extend动态添加了两个成员变量(属性),name和age; 而并没有进行任何关于原型方面的操作,没有构成原型链。 这种继承方法叫做“借用构造函数”。 */ Base.call(this);this.name = "extend"; } // (1) // Extend.prototype = new Base(); var e = new Extend(); var b = new Base(); e.sayName(); //正常。“extend” /* 由于没有来自于Base()的原型继承,自然找不到原型中定义的sayAge。如果想要同样实现原型的继承,需要在var e = new Extend();之前将Extend()的原型指定为Base()类型的实例,即在(1)处加上:Extend.prototype = new Base();这就构成了原型链,与“借用构造函数”共同构成了“组合继承”,也称为“伪经典继承”。*/ //e.sayAge(); b.sayAge(); b.sayName();</script>伪经典继承,也不是最完美的继承方式,更理想的是使用“寄生组合式继承”。具体的内容推荐阅读《JavaScript高级程序设计(第2版)》。