在这种情况下解决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
答案 0 :(得分:1)
如果删除了外部(function (i)
)函数,则所有setTimeouts都将使用相同的 i
,因为新的i
(来自函数参数)会不被引入(它会lead to problems like this)。因此,通过简单地删除外部匿名函数而不改变其他代码也无法消除“提示”。 (另见How do JavaScript closures work?)
虽然我一般不同意这个“提示”(以及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);
}