当一个基本问题出现时,我刚刚写了一些测试。我写了一个测试框架的裸骨架。它首先在一个数组中收集所有测试(它们的回调),然后在一个单独的循环中执行它们。但是,这个
//test.js
var testArray = [
{
n : 1,
d : 'text1'
},
{
n : 2,
d : 'text2'
}
];
var cbs = [];
function fnWithCallback(d, cb) {
console.log('d=('+d+')');
cbs.push(cb);
}
for(var i=0; i < testArray.length; i++) {
var v = testArray[i];
fnWithCallback(v.d, function() {
console.log('v=('+v.n+'), i=('+i+')');
});
}
for(var j=0; j < cbs.length; j++) {
cbs[j]();
}
当我运行此示例时,我得到了这个:
> node test.js
d=(text1)
d=(text2)
v=(2), i=(2)
v=(2), i=(2)
这意味着在回调'v'已被分配给最后一个数组的最后一个元素并且'i'被分配给它的最后一个状态,而不是当回调被'创建'并传递给'fnWithCallback'时的那个功能。但是,由于'd'在回调中被打印出来,因此当调用'fnWithCallback'时,它具有元素的值。
“Unlooping”循环无济于事。
var v = testArray[0];
fnWithCallback(v.d, function() {
console.log('v=('+v.n+')');
});
v = testArray[1];
fnWithCallback(v.d, function() {
console.log('v=('+v.n+')');
});
导致相同的行为。
有人可以解释一下并提供解决方案吗?
答案 0 :(得分:1)
使用闭包
fnWithCallback(v.d, (function(v,i){
return function() {
console.log('v=('+v.n+'), i=('+i+')');
};
})(v,i)));