ssj
ssj

Reputation: 1797

an unexpected references error in javascript

I am trying to create a array made up by function in JavaScript. I writed the following code to ensure each function in the array return it position, but I get 10 for every function in the array,can any one explain why?

function createFunctionArray(){
    var result = new Array();
    for(i=0;i<10;++i){
        result[i] = function(){
            var now = i;
            return now;
        };
    }
    return result
}

Upvotes: 1

Views: 86

Answers (3)

Kelsadita
Kelsadita

Reputation: 1038

You are making use of closure. One thing you should always remember that closure stores there outer variables by reference not by value. So all the reference to i will get updated to final value of i that is 10.

One possible way of doing it correctly is,

function createFunctionArray(){
var result = new Array();
for(i=0;i<10;++i){
    (function(j){
        result[j] = function(){
        return j;
        };
    })(i);    
}
return result;
}

link for fiddle

Upvotes: 0

user1600124
user1600124

Reputation: 440

Your code:

function createFunctionArray(){
    var result = new Array();
    for(i=0;i<10;++i){
        result[i] = function(){
            var now = i;
            return now;
        };
    }
    return result
}

When you call this function. You loop i from 0 to 9 and push those functions you created into the array. But, those functions are never run yet. When the loop ended when i = 10, you have an array of functions that you created but never called. So now.. when you call any one of the funcions by result[.. say 4]. The function will set var now = i, which is currently 10, and return that value. This is way you always get 10.

Upvotes: 1

McGarnagle
McGarnagle

Reputation: 102723

The function execution is deferred, and it returns a reference to i, not its actual value. You need to put the i inside a closure, to create a local copy of its value. Like this:

result[i] = (function(i) { 
    return function(){
        var now = i;
        return now;
    } 
})(i);

Fiddle

To see how this works, you can extract the function above into a named function createFunction:

var createFunction = function(i) {
    return function(){
        var now = i;
        return now;
    } 
}

Use it simply like this:

result[i] = createFunction(i);

Fiddle

Upvotes: 5

Related Questions