生成的函数保留对变量的引用,而不是值替换
Generated functions keep reference to variable instead of value replacement?
我对javascript的特定行为有一个问题:
我有一个对象,我想用生成的函数填充它。每个函数都包含一个变量,该变量在函数生成循环期间会发生变化。
我的问题是在将函数分配给对象时不会替换变量。相反,对变量的引用保留在函数中,并且在执行函数时仅记住变量的最后一个值。
这是一个最小的例子(也在jsfiddle上:http://jsfiddle.net/2FN6K/(:
var obj = {};
for (var i = 0; i < 10; i++){
var nr = i;
obj[i] = function(){
console.log("result: " + nr);
}
}
for (var x = 0; x < 10; x++){
obj[x]();
}
第二个循环执行所有生成的函数,并全部打印 9 作为结果。但我希望他们打印变量在生成时的值(0、1、2、...(。
有没有办法做到这一点?提前谢谢。
一种方法是调用返回函数的函数:
function makeFunc(i) {
return function() {
console.log("result: " + i);
}
}
for (...) {
obj[i] = makeFunc(i);
}
另一种方法是立即调用的函数表达式:
for (i = 0; ...; ...) {
(function(i) {
obj[i] = function() {
console.log("result: " + i);
}
})(i);
}
在后一种情况下,(function(i) ... )(i)
会导致i
作为参数传递给内部函数范围内的外部函数的永久绑定
问题是您创建的所有函数都共享对同一nr
变量的引用。当您调用它们时,它们使用该引用获取值,因此它们都得到相同的结果。
像这样解决它:
for (var i = 0; i < 10; i++){
(function(nr) {
obj[nr] = function(){
console.log("result: " + nr);
}
})(i);
}
你的猜测是正确的,是的,有一个解决方案:
obj[i] = function( nr_copy ) {
return function() {
console.log("result: " + nr_copy);
};
}( nr );
JavaScript 变量的作用域在函数级别,不像其他一些块结构语言。也就是说,你在for
循环中声明"nr"这一事实并不能使它成为该块的"本地"——效果与你在函数顶部声明它的效果完全相同。
通过使用该匿名函数引入另一个函数作用域,可以创建"nr"值的新副本,然后返回的实际函数可以私下访问该副本。 这些函数中的每一个都有自己的"nr"值副本,就像初始化"obj"数组的插槽时一样。
为你创建的每个函数创建一个闭包。
然而,var 没有块作用域,所以你的代码与 :
var obj = {};
var i;
var nr;
for (i = 0; i < 10; i++){
nr = i;
obj[i] = function(){
console.log("result: " + nr);
}
}
这有望使所有函数都更明显地引用相同的"nr"var。
您要做的是每次创建一个新作用域,这可以使用绑定来完成,但是让我们坚持您的原始意图,每次都使用 lambda 构建一个新的闭包:
var obj = {};
for (var i = 0; i < 10; i++) {
obj[i] = (function(){
var this_nr = i;
return function(){
console.log("result: " + this_nr);
}
}() );
}
- window.location替换并传递URL历史记录条目中的变量
- 替换变量时,JavaScript字符串replace()不起作用
- 在 Javascript 中替换变量的值
- JavaScript正则表达式替换变量
- 如何替换变量中的更多字符串
- 替换变量[Javascript]时出现问题
- "[对象对象]”;在警报提示中使用时替换变量字符串
- 通过jQuery替换变量和静态文本
- Swap()函数用于替换变量'
- 用函数(变量)替换变量
- 数据表用其作用域之外的数据替换变量
- Javascript替换变量"在HTML代码中更快
- 在TinyMCE中保存替换变量,但在可视化编辑器中显示替换的内容
- 替换变量中的字符
- 用gulp替换变量
- Javascript正则表达式:替换变量
- 如何使用jquery替换变量中的元素并在另一个变量中获取结果
- 用grunt替换变量
- 如何在正则表达式中替换变量
- 如何替换变量设置的 Replace() - Javascript