如何将JSvariables的值(不是引用)传递给函数?
这里是我试图运行的一个简化版本:
for (var i = 0; i < results.length; i++) { marker = results[i]; google.maps.event.addListener(marker, 'click', function() { change_selection(i); }); }
但我发现每个侦听器都使用results.length(for循环终止时的值)的值。 我如何添加监听器,使得每次使用我添加它时的值,而不是对i的引用?
您需要创build一个单独的作用域,通过将其作为函数parameter passing,将该variables保存在当前状态中:
for (var i = 0; i < results.length; i++) { (function (i) { marker = results[i]; google.maps.event.addListener(marker, 'click', function() { change_selection(i); }); })(i); }
通过创build一个匿名函数并使用variables作为第一个参数来调用它,您将函数传递给函数并创build闭包。
除了闭包之外,还可以使用function.bind
:
google.maps.event.addListener(marker, 'click', change_selection.bind(null, i));
在调用的时候把i
的值作为parameter passing给函数。 ( null
用于绑定this
,在这种情况下你不需要)
function.bind
由Prototype框架引入,并已在ECMAScript第五版中进行了标准化。 在浏览器本身支持它之前,您可以使用闭包添加自己的function.bind
支持:
if (!('bind' in Function.prototype)) { Function.prototype.bind= function(owner) { var that= this; var args= Array.prototype.slice.call(arguments, 1); return function() { return that.apply(owner, args.length===0? arguments : arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments, 0)) ); }; }; }
closures:
for (var i = 0, l= results.length; i < l; i++) { marker = results[i]; (function(index){ google.maps.event.addListener(marker, 'click', function() { change_selection(index); }); })(i); }
编辑,2013年:这些现在通常被称为一个IIFE
你正在封闭。 这里有一篇关于closures和如何与他们合作的文章。 查看页面上的示例5; 这是你正在处理的场景。
编辑:四年后,那个链接已经死了。 上面问题的根源在于for
循环forms的闭包(特别是在marker = results[i]
)。 当marker
被传入addEventListener
,你会看到闭包的副作用:共享的“环境”在循环的每一次迭代中被更新,在最后一次迭代之后通过闭包最终“保存”之前。 MDN很好地解释了这一点。
for (var i = 0; i < results.length; i++) { marker = results[i]; google.maps.event.addListener(marker, 'click', (function(i) { return function(){ change_selection(i); } })(i)); }
我想我们可以定义一个临时variables来存储我的值。
for (var i = 0; i < results.length; i++) { var marker = results[i]; var j = i; google.maps.event.addListener(marker, 'click', function() { change_selection(j); }); }
我还没有testing过。