3

I'm not sure exactly how to describe what I want. I want to define a function with the parameters being a local VALUE not a reference.

say I have list of objects I want to create

for(i = 0; i < 10; i++){
  var div = document.createElement("div");
  div.onclick = function(){alert(i);};
  document.appendChild(div);
}

Now I believe in this example no matter what div I click on, it would alert "10"; as that is the last value of the variable i;

Is there a way/how do I create a function with the parameters being the value they are at the time I specify the function... if that makes any sense.

user187291
  • 53,363
  • 19
  • 95
  • 127
Sheldon Ross
  • 5,364
  • 7
  • 31
  • 37
  • 1
    Inside the function, `i` is a captured variable, not a parameter. – SLaks Mar 16 '10 at 00:11
  • See also: http://stackoverflow.com/questions/1734749/ http://stackoverflow.com/questions/643542/ http://stackoverflow.com/questions/1582634/ http://stackoverflow.com/questions/1331769/ http://stackoverflow.com/questions/1552941/ http://stackoverflow.com/questions/750486/ http://stackoverflow.com/questions/933343/ http://stackoverflow.com/questions/1579978/ http://stackoverflow.com/questions/1413916/ ...and more... :) – Christian C. Salvadó Mar 16 '10 at 00:27
  • @CMS: Yes; I've gotten a lot of reputation answering this kind of question. – SLaks Mar 16 '10 at 00:28
  • @SLaks: Yes, I've also answered this question many *many* times, I think at some point we will need a sort of FAQ by *tag* or something like that... – Christian C. Salvadó Mar 16 '10 at 00:32
  • It's difficult to find existing answers when you're not sure exactly how to phrase the question :) – Sheldon Ross Mar 16 '10 at 00:32

2 Answers2

5

You need to create the function inside another function.

For example:

div.onclick = (function(innerI) {
    return function() { alert(innerI); }
})(i);

This code creates a function that takes a parameter and returns a function that uses the parameter. Since the parameter to the outer function is passed by value, it solves your problem.

It is usually clearer to make the outer function a separate, named function, like this:

function buildClickHandler(i) {
    return function() { alert(i); };
}

for(i = 0; i < 10; i++){
    var div = document.createElement("div");
    div.onclick = buildClickHandler(i);
    document.appendChild(div);
}
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Now I suppose I have to curry the functions if I want to pass 'this' also? div.onclick= function(){somefunction(i,this)}; – Sheldon Ross Mar 16 '10 at 00:24
  • @Sheldon: Correct. Alternatively, `someFunc.call(this, i)` will allow you to use `this` inside of `someFunc`. – SLaks Mar 16 '10 at 00:27
0

You could use an anonymous function:

for(i = 0; i < 10; i++){
    (function(i){
        var div = document.createElement("div");
        div.onclick = function(){alert(i);};
        document.appendChild(div);
    })(i)
}
Pim Jager
  • 31,965
  • 17
  • 72
  • 98