【发布时间】:2014-07-02 15:36:44
【问题描述】:
我在上一个项目中偶然发现了一个非常奇怪的问题。我已经实现了如下继承:
function Parent(){}
Parent.prototype.hi = function(){
alert("Parent: hi!");
};
Parent.prototype.bye = function(){
alert("Parent: bye!");
};
function Child(){
this.hi = function(){
alert("Child: hi!");
};
}
Child.prototype = new Parent();
这样我可以在 Child 构造函数中只覆盖我需要的函数,其余的将从父级继承。
这工作正常。这是测试:
var test = function(){
var p = new Parent();
p.hi();
p.bye();
var c = new Child();
c.hi();
c.bye();
};
test();
并且输出是预期的:
Parent: hi!
Parent: bye!
Child: hi!
Parent: bye!
但是,当我将实例存储在数组中时,子实例中的 bye 函数不会被继承,并且会引发错误。测试代码:
var anArray = [
new Parent(),
new Child()
];
var test2 = function(){
for(var i = 0, m = null; i < anArray.length; i++){
m = anArray[i];
m.hi();
m.bye(); //WTF not working for the child?
}
};
test2();
输出:
Parent: hi!
Parent: bye!
Child: hi!
TypeError: m.bye is not a function
我花了一个多小时盯着这段代码并调试它,我看不出问题出在哪里。原始代码要复杂得多,功能也更多。我认为数组有问题,但我不想放弃它,因为我认为表驱动方法是我要实现的最佳方法。
【问题讨论】:
-
在您的 Child() 函数中,您只定义了 this.hi,而不是 this.bye。这就是为什么 bye() 会以未定义的形式返回。
-
@athms:不,不是这个原因。
-
为变量或属性赋值从不更改另一个变量或属性的值。因此,为
Child.prototpye分配新值不能更改现有 实例的原型。 -
@FelixKling 是的,“现有”是关键词。我没有展示它,但整个代码都在一个模块中。我碰巧忘记了很多模块是执行的常规代码,并且倾向于将其视为一堆函数定义。
标签: javascript arrays inheritance prototypal-inheritance