Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy are objects' values captured inside function calls?
    primarykey
    data
    text
    <p>This code is supposed to pop up an alert with the number of the image when you click it:</p> <pre><code>for(var i=0; i&lt;10; i++) { $("#img" + i).click( function () { alert(i); } ); } </code></pre> <p>You can see it not working at <a href="http://jsfiddle.net/upFaJ/" rel="nofollow">http://jsfiddle.net/upFaJ/</a>. I know that this is because all of the click-handler closures are referring to the same object <code>i</code>, so every single handler pops up "10" when it's triggered. </p> <p>However, when I do this, it works fine:</p> <pre><code>for(var i=0; i&lt;10; i++) { (function (i2) { $("#img" + i2).click( function () { alert(i2); } ); })(i); } </code></pre> <p>You can see it working at <a href="http://jsfiddle.net/v4sSD/" rel="nofollow">http://jsfiddle.net/v4sSD/</a>.</p> <p>Why does it work? There's still only one <code>i</code> object in memory, right? Objects are always passed by reference, not copied, so the self-executing function call should make no difference. The output of the two code snippets should be identical. So why is the <code>i</code> object being copied 10 times? Why does it work?</p> <p>I think it's interesting that this version <a href="http://jsfiddle.net/vfwnU/" rel="nofollow">doesn't work</a>:</p> <pre><code>for(var i=0; i&lt;10; i++) { (function () { $("#img" + i).click( function () { alert(i); } ); })(); } </code></pre> <p>It seems that the passing of the object as a function parameter makes all the difference.</p> <hr> <p>EDIT: OK, so the previous example can be explained by primitives (<code>i</code>) being passed by value to the function call. But what about this example, which uses real objects?</p> <pre><code>for(var i=0; i&lt;5; i++) { var toggler = $("&lt;img/&gt;", { "src": "http://www.famfamfam.com/lab/icons/silk/icons/cross.png" }); toggler.click(function () { toggler.attr("src", "http://www.famfamfam.com/lab/icons/silk/icons/tick.png"); }); $("#container").append(toggler); } </code></pre> <p>Not working: <a href="http://jsfiddle.net/Zpwku/" rel="nofollow">http://jsfiddle.net/Zpwku/</a></p> <pre><code>for(var i=0; i&lt;5; i++) { var toggler = $("&lt;img/&gt;", { "src": "http://www.famfamfam.com/lab/icons/silk/icons/cross.png" }); (function (t) { t.click(function () { t.attr("src", "http://www.famfamfam.com/lab/icons/silk/icons/tick.png"); }); $("#container").append(t); })(toggler); } </code></pre> <p>Working: <a href="http://jsfiddle.net/YLSn6/" rel="nofollow">http://jsfiddle.net/YLSn6/</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload