1

当一个基本问题出现时,我刚刚编写了一些测试。我写了一个测试框架的骨架。它首先将所有测试(它们的回调)收集在一个数组中,然后在一个单独的循环中执行它们。然而,这

//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”时它具有元素的值。

“解开”循环没有帮助。

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+')');
});

导致相同的行为。

有人可以解释这一点并提供解决方案吗?

4

1 回答 1

1

使用闭包

fnWithCallback(v.d, (function(v,i){
    return function() {
        console.log('v=('+v.n+'), i=('+i+')');
    };
})(v,i)));
于 2012-04-17T14:35:37.507 回答