Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible Access To Modified Closure Issue... How To Beat?

For some reason no matter what, the pageNumber ends up being the last value in the loop for the loopCounter. Now I would understand that if I were directly using loopCounter in the closure itself, but I'm not. As you can see from the code below, I am creating a new variable within the closure to take the current value of loopCounter.

Only thing I can figure is (Assuming that javascript treats everything as a reference type) that pageNumber is taking the reference to loopCounter so no matter how many times I create a new pageNumber, it's always pointing at the loopCounter object. Therefore, whatever value loopCounter ends up with will be the value any pageNumber will point to.

How do I get it to not point at loopCounter but create a new pageNumber per iteration that holds the current loopCounter value?

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);
    };

  ...
}

SOLUTION

Thanks to a couple answers below:

function createClickMethod(loopCounter, link)
{
    var pageNumber = loopCounter;

    return function(event) { getResultUsingUrl(link + "&pageNumber=" + pageNumber); };
}

and I can call like:

newDiv.onclick = createClickMethod(loopCounter, result.PagerPreLink);

Or if I want to use jQuery... suggested below:

jQuery(newDiv).click
(
    createClickMethod(loopCounter, result.PagerPreLink)
);
like image 821
Programmin Tool Avatar asked Dec 03 '22 14:12

Programmin Tool


2 Answers

Like everyone else said, it's a scoping problem. Without using a JS library, you can do something like this:

newDiv.onclick = (function() {
    var num = loopCounter;
    return function(evt) {
        console.log( num );
    }
})();

You just need to create another closure around the value.

like image 187
seth Avatar answered Dec 23 '22 13:12

seth


You are not creating a new pageNumber each time. You only have one. Scope in JavaScript does not extend beyond function-scope. Any "var" you declare in a function -- in or out of loops -- works exactly as it would had you declared it right at the top of the function.

http://javascript.crockford.com/code.html

like image 44
shuckster Avatar answered Dec 23 '22 11:12

shuckster