JS提示:Don't在循环中生成函数
JSHint: Don't make functions within a loop
在这种情况下,解决JSHint错误的正确方法是什么?删除function(i)
能解决问题吗?这样做会妨碍性能吗?
for (var i = 0; i + 1 <= pinlatlong.length; i++) {
(function(i) {
setTimeout(function() {
var latlong_array = pinlatlong[i].lat_long.split(','),
marker = new google.maps.Marker({
position: new google.maps.LatLng(latlong_array[0],latlong_array[1]),
map: map,
animation: google.maps.Animation.DROP,
icon: pinimage,
optimized: false
});
// info windows
var infowindow = new google.maps.InfoWindow({
content: pinlatlong[i].title,
maxWidth: 300
});
infoWindows.push(infowindow);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindows[i].open(map, this);
};
})(marker, i));
}, i * 250); // end setTimeout
}(i)); // end auto function
} // end for
如果外部(function (i)
)函数被删除,那么所有setTimeouts都将使用相同的i
,因为(函数参数中的)新i
将不会被引入(这将导致类似的问题)。因此,在不更改其他代码的情况下,不能通过简单地从外部匿名函数中删除"提示"来消除它。(另请参阅JavaScript闭包是如何工作的?)
虽然我通常不同意这个"提示"(以及JSLint的其他一些建议),但在这种特殊情况下,除了禁用/忽略"提示"之外,还有几种不同的方法可以避免"提示"。
避免警告的一种方法是使用setInterval
一次,并且只使用一个回调函数。迭代(在第i个点上)然后在内部回调中进行,完成后使用clearInterval
。请注意,这里的意图是而不是来"提高性能"或消除"提示",但显示了一种替代方法,有些方法可能会更好或更干净。
function addPins (map, pinLatLong, infoWindows) {
// In separate function so these variables are guaranteed to be
// in a new function scope.
var i = 0;
var timer = setTimeout(function() {
if (i == pinLatLng.length) {
clearTimeout(timer);
timer = null;
return;
}
var latLng = pinLatLong[i]; // only use `i` here
var latlong_array = latlong.lat_long.split(','),
// If combining `var` statements, which is another hint I disagree with,
// consider NOT using a previously introduced var's value immediately as it
// makes it harder to see the introduction (of latlong_array in this case).
marker = new google.maps.Marker({
position: new google.maps.LatLng(latlong_array[0],latlong_array[1]),
map: map,
animation: google.maps.Animation.DROP,
icon: pinimage,
optimized: false
});
// info windows
var infowindow = new google.maps.InfoWindow({
content: latlong.title,
maxWidth: 300
});
infoWindows.push(infowindow);
// Eliminated use of extra uneeded closure as all the variables
// used are contained within the callback's function context.
google.maps.event.addListener(marker, 'click', return function() {
infoWindow.open(map, this);
});
i++;
}, 250);
}
作为奖励,它避免了我个人在一般情况下不同意的"暗示"。继续,创建数百个函数对象:JavaScript代码总是这样做。
第二种方法是使用setTimeout
对其他参数的支持,这些参数将作为回调参数提供。因此,代码也可以在没有导致"提示"警告的额外function (i)
的情况下进行修改。虽然这确实会创建许多超时(与原来一样),但它只使用一个函数进行回调,并避免了额外的闭包。
function showPin (i) {
// Everything that was in the setTimeout callback
// ..
}
for (var i = 0; i + 1 <= pinlatlong.length; i++) {
setTimeout(showPin, 250, i);
}
另一种方法是在另一个函数中创建闭包,这与原始代码的作用相同。可以说,这本书比原作更干净、更容易阅读,即使没有试图消除"暗示"本身。
function mkShowPin (i) {
return function () {
// Everything that was in the setTimeout callback
// ..
}
}
for (var i = 0; i + 1 <= pinlatlong.length; i++) {
setTimeout(mkShowPin(i), 250);
}
相关文章:
- JavaScript/Jquery:一个特殊用途的for循环函数
- 为循环函数中的元素指定单击
- Jquery下一个和上一个按钮循环函数
- 循环函数(Javascript回调帮助)
- 循环函数不起作用
- 使用ajax调用循环函数
- 在Javascript中修改循环函数的参数
- 如何循环函数数组并在单击时一次执行一个
- 设置超时可以保存我的循环函数不被视为无响应
- 具有超时的循环函数
- j查询如何在一系列延迟后循环函数
- 如何将 JavaScript forEach 循环/函数转换为 CoffeeScript
- for 循环函数似乎未运行
- 对于内部循环函数(新手)
- 循环函数会导致它在 javascript 中无响应
- 循环函数
- 如何优化循环函数
- JS拒绝循环函数
- 中断循环函数
- 在 JavaScript 中循环函数可以吗?