我不知道如何解决以下JavaScript问题:
function A() {
var numbers = [];
this.addNumber = function(number) {
numbers.push(number);
}
this.getNumbers = function() {
return numbers;
}
}
A.prototype.alertNumbers = function() {
var numbers = this.getNumbers();
var length = numbers.length;
var number;
var numbersString = "";
for (var i = 0; i < length; i++) {
number = numbers[i];
numbersString += " " + number;
}
alert(numbersString);
}
B.prototype = new A();
function B() {
this.addNumber(1);
this.addNumber(2);
}
var b = new B();
b.alertNumbers();
var otherB = new B();
otherB.alertNumbers();
工作代码在这里:http://jsfiddle.net/pFxse/
我期待otherB.alertNumbers();也显示“1 2”而不是“1 2 1 2”。
由于
答案 0 :(得分:1)
问题是当你这样做时:
B.prototype = new A();
您将B.prototype设置为A的实例,因此B.prototype将有2个访问私有变量数的函数。
现在,当您访问(new B()).addNumber()
时,您将使用原型中的函数,从而使用原型中的数组。所有实例都将使用该数组。所有实例都将推送到该阵列。
要修复它,就足够了:
function B() {
A.call(this); // call superclass
this.addNumber(1);
this.addNumber(2);
}
通过调用B的构造函数中的超类,您已为B的每个实例创建了一个数字变量,以及包含该变量的2个函数。每个实例都将使用其特定的addNumbers函数,该函数使用其特定的闭包数组。
既然你已经这样做了,你的继承方案也可以简化:
B.prototype = Object.create(A.prototype);
不是创建A类型的新对象并将其设置为B的原型,而是将B的原型设置为直接从A的原型继承。您仍然在A的构造函数中定义了方法,因为您调用了超类。优点是,现在您不再为每个子类创建A的实例,并且(可能更重要)您现在可以将参数传递给构造函数:
function A(name) {
this.name = name;
}
function B(name) {
A.call(this, 'B' + name);
}
B.prototype = Object.create(A.prototype);
您的继承模型中不能有这种情况。
答案 1 :(得分:0)
你有一个“A”实例,它是“B”构造函数的原型。因此,每个“B”实例在“A”实例中共享相同的闭包变量。