我正在尝试用JavaScript编写符号处理计算器。我遍历一个符号列表。我的样本输入是1 + 2。
for <every element in the list> {
...
// this case handles simple numbers
var tmp = o.val;
list[pos] = {type: 'expression', val: +tmp, calc: function (x) {return +tmp} };
...
// this case handles addition
var v1 = list[pos-1].val, v2 = list[pos+1].val;
var f1 = list[pos-1].calc, f2 = list[pos+1].calc;
list[pos-1] = {type: 'expression', val: v1 + ' + ' + v2, calc: function (x) {return f1(x) + f2(x)} };
...
}
alert(list[0].val + '=' + list[0].calc(0));
问题是这显示4而不是3.对第一个操作数的calc()调用不再返回1但是2.我希望'calc'保存当前值,以制作深度副本f1和f2的功能。我该如何实现这一目标?什么是好的编程实践?
答案 0 :(得分:1)
虽然已经链接了正确的解释,但这是解决问题的简单方法:您必须打开一个新的变量范围,以确保每次“tmp”实际上是一个新变量,而不是相同的变量一遍又一遍:
for <every element in the list> {
(function() {
... loop body ...
)();
}
答案 1 :(得分:0)
您的问题可以简化为:
var funcs = [];
for (var i=0; i<2; i++) {
var temp = i;
funcs.push(function() { console.log(temp) });
}
funcs[0](); // 1 - expected 0
funcs[1](); // 1
问题是你的函数会在temp上创建一个闭包。它们处理实际的临时变量,而不是定义它们时临时变量值的副本。
解决方案很简单:创建临时变量的副本(通过将其作为参数传递给函数):
var funcs = [];
for (var i=0; i<2; i++) {
var temp = i;
funcs.push(function(copy) { // anonymous function that copies temp
return function() { console.log(copy); }
}(temp) // call the anonymous function
);
}
funcs[0](); // 0
funcs[1](); // 1