1

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
}

3 Answers 3

5

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

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

2 Comments

I have heard this solution when I reading Professional JavaScript for Web Developers, 3rd Edition. I think my solution can alse work. But it does not,can you tell my why?
@whatout your solution will not work as there is one more concept involved called variable hoisting. So even if you have var now = i it will be like now = i and declaration of now will happen only one time as a first line of the function body. Also as its a case of closure i will act as reference so does the now both will get updated at the same time.
1

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.

Comments

0

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

2 Comments

that why I use now to get the current value,every time I defined now by var, I get a copy of i. Am I right?
No actually its not like that. Even when you define var everytime it will get hoisted over the top inside the function and it will be like defining only one time. Do check the variable hoisting..it will help you to understand this situation :)

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.