我在网上看到call的用法时,他这样写道:
“应用call和apply更有一个技巧在里面,就是用call和apply应用另一个函数(类)以后,当前的函数(类)就具有了另一个函数(类)的方法或是属性,这也能称之为“继承”。”
于是我用下面的这段代码做了实验:得出了下面结论:
<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>
具体解释看我加的代码注释:
[code="java"]
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();[/code]
伪经典继承,也不是最完美的继承方式,更理想的是使用“寄生组合式继承”。具体的内容推荐阅读《JavaScript高级程序设计(第2版)》。