关闭JavaScript的立即评估
考虑下面的Javascript代码:关闭JavaScript的立即评估
var a = [];
var f = function() {
for (var i = 0; i < 3; i++) {
a.push(function(){alert(i)});
}
for (var j = 0; j < 3; j++) {
a[j]();
}
};
警报打印出 '3' 的所有三次。我想要一个不同的行为 - 在循环的每次迭代中生成一个打印i的当前值的函数。即3个功能可以打印不同的索引。
任何想法?
创建它接受i
作为参数,并返回一个特定功能的匿名函数:
for (var i = 0; i < 3; i++) {
a.push((function(i) {
return function() {
alert(i);
}
})(i));
}
for (var j = 0; j < 3; j++) {
a[j]();
}
或者做类似的事情:建立它接受i
作为参数传递给函数添加到阵列的匿名函数:
for (var i = 0; i < 3; i++) {
(function(i) {
a.push(function() {
alert(i);
});
})(i);
}
for (var j = 0; j < 3; j++) {
a[j]();
}
var iterate = (function() {
var i, j = [];
for (i = 0; i < 3; i += 1) {
j.push(i);
alert(j[j.length - 1]);
}
}());
您不必封仅仅输出值。但是,您的代码应该包含在面向对象遏制的函数中。函数不必被调用来执行。
”不必调用函数来执行。“什么?这种说法不是很清楚,因为这听起来不对。澄清,拜托? – strager 2009-09-12 01:13:45
为了执行一个功能必须发生三件事情之一。 1)函数必须由正在执行的其他名称调用。 2)该函数可以被插入到一个方法中,在这种情况下该函数可以是匿名的并且仍然可以被执行。我强烈反对使用函数而不给它们命名。 3)函数可以在它们被解释时完全独立执行,如果它们在右括号之后用括号终止,如}()。这被称为即时召唤。 – 2009-09-12 01:24:14
我不同意。在Javascript中,函数是一个值类型,就像'42'或''hello world''一样。无论它是分配给变量还是直接使用都没有什么特别的。对于这种行为的例子,运行:'(function(i){var func = arguments.callee; if(!i)return; console.log('x'); window.setTimeout(function(){func(i - '0123)(4);' – strager 2009-09-12 01:31:10
功能(我){警报(我)
很可能,'i'将会是未定义的。 – strager 2009-09-12 01:10:42
+1简洁。如果 a.push(function(i){alert(i)});使用 代替 a.push(function(){alert(i)}); – 2014-01-18 15:13:23
只是另一种方法,使用currying:
var a = [];
var f = function() {
for (var i = 0; i < 3; i++) {
a.push((function(a){alert(a);}).curry(i));
}
for (var j = 0; j < 3; j++) {
a[j]();
}
};
// curry implementation
Function.prototype.curry = function() {
var fn = this, args = Array.prototype.slice.call(arguments);
return function() {
return fn.apply(this, args.concat(
Array.prototype.slice.call(arguments)));
};
};
检查上面的代码运行here。
你可以把你的循环体中的匿名函数:
var a = [];
for(var i = 0; i < 3; i++) (function(i) {
a.push(function() { alert(i); });
})(i)
for(var j = 0; j < 3; j++) {
a[j]();
}
通过创建功能和传递的“我”作为参数,我们正在创造一个新的“我”变循环的价值在基本隐藏外部“我”的循环体内。现在您将数组放入数组中,可以看到新变量,其值在第一个循环中调用外函数函数时设置。如果我们使用不同的名称,当我们创造了新的变量,这可能是更清楚...这做同样的事:
var a = [];
for(var i = 0; i < 3; i++) (function(iNew) {
a.push(function() { alert(iNew); });
})(i)
for(var j = 0; j < 3; j++) {
a[j]();
}
“INEW”的值赋给0,然后1,然后2,因为该功能被循环立即调用。
只是添加这个是因为Javascript没有块范围的唯一功能范围的概念,这也抛出了我... http://www.mattfreeman.co.uk/2010/03/closures-scope-in- javascript-vs-c/ – 2010-05-21 08:07:30