遇到一个奇怪的问题,或许最好用代码解释:
var fruits = ["apples", "oranges", "pears"];
var Breakfast = {
_consume : function (fruit) {
Breakfast[fruit]._numConsumed++;
}
};
for (var f in fruits) {
var fruit = fruits[f];
Breakfast[fruit] = {
consume : function () {
Breakfast._consume(fruit);
},
_numConsumed: 0
}
}
Breakfast.pears.consume();
Breakfast.pears.consume();
Breakfast.apples.consume();
Breakfast.apples.consume();
Breakfast.apples.consume();
console.log("Pears eaten: " + Breakfast.pears._numConsumed);
console.log("Apples eaten: " + Breakfast.apples._numConsumed);
结果是:
$ node example.js
Pears eaten: 5
Apples eaten: 0
不太确定如何克服这种行为?
我编码错了吗?或者我应该使用不同的模式? (鉴于我希望“消费”功能可用于我所有的水果等)
非常感谢!
答案 0 :(得分:0)
你在功能关闭方面遇到了一些麻烦。这个问题有一个很好的解释:How do JavaScript closures work?
你的问题是这一行:
Breakfast._consume(fruit);
总是等同于
Breakfast._consume(fruits[2]);
您的for
循环完成后。
你可以通过为每个f
提供整个循环自己的上下文来解决它:
for (var f in fruits) {
(function(f) {
var fruit = fruits[f];
Breakfast[fruit] = {
consume : function () {
Breakfast._consume(fruit);
},
_numConsumed: 0
}
})(f);
}
...将导致......
"Pears eaten: 2"
"Apples eaten: 3"
但这是一个相当粗略的解决方案。一旦你阅读了关于函数闭包如何工作的解释,我相信你会想出一个更好的方法。
答案 1 :(得分:0)
问题是你的变量永远是for循环的最后一个。一种更简单的方法是在您正在创建的对象中定义属性。
即
var fruits = ["apples", "oranges", "pears"];
var Breakfast = {
_consume : function (fruit) {
Breakfast[fruit]._numConsumed++;
}
};
for (var f in fruits) {
var fruit = fruits[f];
Breakfast[fruit] = {
id:fruit,
consume : function () {
Breakfast._consume(this.id);
},
_numConsumed: 0
}
}
答案 2 :(得分:-1)
编辑回答:
var fruits = ["apples", "oranges", "pears"];
var Breakfast = {
_consume : function (fruit) {
console.log('other'+JSON.stringify(fruit));
Breakfast[fruit]._numConsumed++;
}
};
for (var f in fruits) {
//var fruit = fruits[f];
Breakfast[fruits[f]] = {
fruit: fruits[f],
consume : function () {
Breakfast._consume(this.fruit);
},
_numConsumed: 0
}
}
Breakfast.pears.consume();
Breakfast.pears.consume();
Breakfast.apples.consume();
Breakfast.apples.consume();
Breakfast.apples.consume();
console.log("Pears eaten: " + Breakfast.pears._numConsumed);
console.log("Apples eaten: " + Breakfast.apples._numConsumed);