使js闭包立即执行
我可以在以下代码中看到一个问题:
var elems = { 'elem1': 'param1fds', 'elem2': 'paramaafds2', 'elem3': 'paramfdsfd3fdsfds' }; for (var k in elems) { $('#' + k).click(function(e) { // k is always elem3 when I click on the element // elems[k] == 'paramfdsfd3fdsfds'
在代码执行时, k
等于elem3
。 我该怎么处理?
标准的通用解决方案是在闭包中添加一个保护变量的IIFE :
for (var k in elems) { (function(k){ $('#' + k).click(function(e) { // k is always elem3 when I click on the }) })(k); }
当你使用jQuery时,你也可以使用$.each
:
$.each(elems, function(k){ $('#' + k).click(function(e) {
第三种解决方案是使用并提供data
:
for (var k in elems) { $('#' + k).on('click', {k:k}, function(e) { // use e.data.k here
在不久的将来,使用ES6,第四个解决方案将是使用let
块作用域变量:
for (let k in elems) { $('#' + k).click(function(e) { // k is OK
var elems = { 'elem1': 'param1fds', 'elem2': 'paramaafds2', 'elem3': 'paramfdsfd3fdsfds' }; for (var k in elems) { (function(elem){ $('#' + elem).click(function(e) {}); })(k); ... }
我认为现代解决方案是在function上做,而不是循环:
Object.keys(elems).forEach( function(elKey) { $('#' + elems[elKey]).click(function(e) {}); });
这与使用IIFE的结果相同,但我认为更容易理解。