0

Why is this not working as expected:

$(function(){
   var datas=[[1],[3]];
   var functions=[];
   for(var i in datas ){ 
   	var data=datas[i];
    functions.push(function(){
    	$("div").append($("<p/>").text("data[0]="+data[0]+", datas["+i+"][0]="+datas[i][0]));
    });
   }
   for(var i in functions )
   	functions[i](); 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div />

I expect:

data[0]=1, datas[0][0]=1

data[0]=3, datas[1][0]=3

Can some one help me to understand whats going on here?

Thanks a lot, greetings Patrick

---------Solution-------

var data is past in the scope of the function but it will still change after.

Therefor the best solutions is bind():

$(function(){
   var datas=[[1],[3]];
   var functions=[];
   for(var i in datas ){ 
   	var data=datas[i];
    functions.push(function(data){
    	$("div").append($("<p/>").text("data[0]="+data[0]+", datas["+i+"][0]="+datas[i][0]));
    }.bind(null,data));
   }
   for(var i in functions )
   	functions[i](); 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>

5
  • what is the problem? Commented Nov 3, 2015 at 9:51
  • I expect data[0]=1, datas[0][0]=1 and i get data[0]=3, datas[0][0]=1 why? Commented Nov 3, 2015 at 9:55
  • 1
    Possible duplicate of JavaScript closure inside loops – simple practical example Commented Nov 3, 2015 at 10:00
  • sorry it was my mistake Commented Nov 3, 2015 at 11:01
  • if you have an answer, post it as an answer, dont include it in your question, please Commented Nov 5, 2015 at 12:00

1 Answer 1

2

This is all about scope. Try to change

var data=datas[i];
functions.push(function(){
    $("div").append($("<p/>").text("data[0]="+data[0]+", datas["+i+"][0]="+datas[i][0]));
});

to

(function (data) {
    functions.push(function(){
        $("div").append($("<p/>").text("data[0]="+data[0]+", datas["+i+"][0]="+datas[i][0]));
    });
})(datas[i]);

Within for-loop scope value of data has changed. This is why when functions are called they use last modified value of data. That's why we created a new scope where data and function live together in a friendly fashion.

Sign up to request clarification or add additional context in comments.

1 Comment

I'd prefere a solution with .bind() mentioned in a duplicate flag, somehow cleaner, hwoever the above should work, anyway the question is to be closed as duplicate

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.