for(var i=1; i<496; i++) {
(function(num) {
myApp.getTerm(num, function (term, def){
myApp.quizlet[0].terms[num] = { term: term, definition: def};
});
})(i);
};
我正在调用for循环中的回调函数。 回调函数需要访问当前循环的迭代i 。我想出上面的解决方案。
有没有其他办法可以做这样的事情?
答案 0 :(得分:2)
定义要调用的命名函数更具可读性:
myApp.getTermForQuizzlet = function(num){
myApp.getTerm(num, function (term, def){
myApp.quizlet[0].terms[num] = { term: term, definition: def };
});
};
for(var i=1; i<496; i++) {
myApp.getTermForQuizzlet(i);
};
除此之外,我不知道你能做什么。
答案 1 :(得分:2)
你所做的并非不合理,应该可以正常工作。纯粹在可读性方面,我可能会选择
for(var i=1; i<496; i++) {
function get_callback(n) {
return function(term, def) {
myApp.quizlet[0].terms[n] = { term: term, definition: def};
};
}
myApp.getTerm(i, get_callback(i));
};
如果您习惯使用Function.bind:
function callback (n, term, def) {
myApp.quizlet[0].terms[n] = { term: term, definition: def};
}
for(var i=1; i<496; i++) {
myApp.getTerm(i, callback.bind(this,i));
}
我们将第一个参数绑定到i
,从而产生一个带有term
和def
参数的“curried”函数。
然后当然有这个可怕的黑客,不要在家里试试。
for(var i=1; i<496; i++) {
try { throw i; }
catch (i) {
myApp.getTerm(i, function (term,def) {
myApp.quizlet[0].terms[i] = { term: term, definition: def};
});
}
}
答案 2 :(得分:1)
循环内部的结构称为Immediately-Invoked Function Expression(IIFE)。
例如,在循环中创建事件处理程序时,IIFE可能很有用,并且希望锁定每个事件处理程序的循环变量的当前值以供以后使用。这个“锁定”被称为(lexical or function) closure:外部函数的词法范围(在您的情况下,IIFE),包括任何常量,局部变量和参数值(在您的情况下,num
参数IIFE,它是循环变量的实际值),即使在执行外部函数之后,也成为每个内部函数对象(在您的情况下,传递给myApp.getTerm
的回调函数)的内部状态的一部分( IIFE)总结。
所以我认为你这样做是正确的,在你的情况下使用IIFE是一个非常有效的解决方案。
可以在John Resig's implementation of inheritance中找到这种模式(IIFE用于结束)的有趣例子:
// ...
(function(name, fn){
return function() {
// use name and fn here
};
})(name, prop[name])
// ...
答案 3 :(得分:1)
大多数时候我使用迭代函数而不是bulidtin循环。它们适用于较新的浏览器和大多数JS库:
array.forEach(function(item, i){
//We can freely use "item" and "i" in callbacks without worrying
setTimeout( function(){ console.log(item, i) }, 1000 );
});
这通常比for循环版本更短(如果你至少迭代一个数组)并且它避免了“free”中的for-for-for循环错误,而不必添加额外的临时调用函数或类似的东西。
这种方法的主要缺点是它不支持使用“this”并使用break,continue和return语句以及内置循环,并且大多数库只带有数组或字典迭代的函数,没有支持更通用的循环样式。虽然我最终需要这种高级功能,但当它确实出现时,我通常只使用额外的闭包(就像你做的那样),或者,如果它是一个常见的模式,编写我自己的迭代器函数。
var forLoop = function(i0, n, f){
for(var i=i0; i<n; i++){
f(i);
}
};
forLoop(1, 496, function(i){
myApp.getTerm(i, function(term, def){
myApp.quizlet[0].terms[i] = { ... }
});
});
答案 4 :(得分:1)
好像你基本上希望
要设置您需要的属性,您可以执行以下操作..
var terms = ['js', 'php', 'css', 'html', 'as3'];
var defin = ['about js', 'about php', 'about css', 'about html', 'about as3'];
var myApp = {};
myApp.quiz = new Array;
myApp.quiz[0] = [];
myApp.quiz[0].terms = new Array;
terms.forEach(function(ele, idx){
myApp.quiz[0].terms[idx] = {term: terms[idx], def: defin[idx]};
})
现在您需要一种方法来访问任何测验中的任何术语。所以你可以使用像......这样的函数来做到这一点。
function getTerm(qn, tn){
return myApp.quiz[qn].terms[tn];
}
var q0t2 = getTerm(0, 2);
console.log(q0t2); // def: "about css", term: "css"
我不太确定你的需求是什么,但这是我最好的猜测。 请详细说明您的情况是否与我在这里使用的方法不符。 :)