出于某种原因,无论如何,pageNumber最终成为loopCounter循环中的最后一个值。现在我明白如果我在闭包本身直接使用loopCounter,但我不是。从下面的代码中可以看出,我在闭包中创建了一个新变量来获取loopCounter的当前值。
我唯一可以想到的是(假设javascript将所有东西视为引用类型)pageNumber正在引用loopCounter,所以无论我创建一个新的pageNumber有多少次,它总是指向loopCounter对象。因此,loopCounter最终得到的值将是任何pageNumber将指向的值。
如何让它不指向loopCounter但是每次迭代创建一个新的pageNumber来保存当前的loopCounter值?
for (var loopCounter = result.StartingPoint; loopCounter <= result.HighestPageCount; loopCounter++)
{
...
var newDiv = document.createElement('div');
...
//trying to remove the reference to loopCounter
var pageNumber = loopCounter;
newDiv.onclick =
function(event)
{ //Right here ---V
getResultUsingUrl(result.PagerPreLink + "&pageNumber=" + pageNumber);
};
...
}
解
感谢下面的几个答案:
function createClickMethod(loopCounter, link)
{
var pageNumber = loopCounter;
return function(event) { getResultUsingUrl(link + "&pageNumber=" + pageNumber); };
}
我可以这样打电话:
newDiv.onclick = createClickMethod(loopCounter, result.PagerPreLink);
或者,如果我想使用jQuery ...建议如下:
jQuery(newDiv).click
(
createClickMethod(loopCounter, result.PagerPreLink)
);
答案 0 :(得分:9)
像其他人一样,这是一个范围问题。如果不使用JS库,您可以执行以下操作:
newDiv.onclick = (function() {
var num = loopCounter;
return function(evt) {
console.log( num );
}
})();
你只需要在值周围创建另一个闭包。
答案 1 :(得分:5)
您每次都不会创建新的pageNumber。你只有一个。 JavaScript中的范围不超出功能范围。你在一个函数中声明的任何“var” - 在循环中或循环外 - 的工作方式与你在函数顶部声明的完全相同。
答案 2 :(得分:2)
Javascript闭包存储对其变量的引用,因此所有onclick处理程序都使用相同的变量。
您需要在中间函数中捕获变量,如下所示:
function buildClickHandler(pageNumber) {
return function(event) { //Create and return a new function
getResultUsingUrl(result.PagerPreLink + "&pageNumber=" + pageNumber);
}
}
然后,使用该函数创建onclick
处理程序,如下所示:
for (var loopCounter = result.StartingPoint; loopCounter <= result.HighestPageCount; loopCounter++) {
//...
var newDiv = document.createElement('div');
newDiv.onclick = buildClickHandler(loopCounter);
}
每次调用buildClickHandler
都会创建一个单独的闭包,它有自己的变量。
顺便说一句,考虑使用jQuery进行DOM操作;它比原始DOM API容易得多。
在您的示例中,您可以编写
$('<div />').click(buildClickHandler(loopCounter));
答案 3 :(得分:1)
是result.StartingPoint真的是一种原始类型,例如实际的数字类型?如果没有,那么可能正在发生的是你正在获得对该对象的引用,然后字符串连接正在为你做类型强制。试试这个:
var pageNumber = new Number(loopCounter); // force coercion
答案 4 :(得分:0)
onclick闭包不会保持其范围,因此无法访问结果。
查看dojo.hitch以获得简单而强大的解决方案,以便您可以控制其范围。