开发者

Closure error with loops in javascript

开发者 https://www.devze.com 2023-04-05 04:18 出处:网络
I had a bug, it went like this for(var i=0; i<arr.length; i++){ var v = arr[i] var obj=new Thing obj.TheCallback = function(e) { blah = v; domorestuff(); ... }

I had a bug, it went like this

for(var i=0; i<arr.length; i++){
    var v = arr[i]
    var obj=new Thing
    obj.TheCallback = function(e) { blah = v; domorestuff(); ... }
    obj.runCodeToExecuteTheCallback()
}

The problem is v inside the function is using the v from the last loop. It's a closure thing where you can access variables in your parent scope. But my question is...

Why is javascript reusing v 开发者_如何学Cin each iteration? When it goes out of scope (at the end of the loop) i dont except it to be MODIFIED from any other scope unless it was passed in (such as the inner function). Why the heck is javascript clobbering my variable? Is there some kind of reason for this design? Is it a bug that has been decided never to be fixed?


This is a very common issue people encounter.

JavaScript doesn't have block scope, just function scope. So each function you create in the loop is created in the same variable scope, so they're referencing the same v variable.

To create a new scope, you need to invoke a function, and pass in whatever you want to exist in a new scope.

function createCallback( x ) {
    return function(e) { blah = x; domorestuff(); ... }
}

for(var i=0; i<arr.length; i++){
    var v = arr[v]
    var obj=new Thing
    obj.TheCallback = createCallback( v );
    obj.runCodeToExecuteTheCallback()
}

Here I invoked the createCallback() function, pass in v, and had createCallback() return a function that references the local variable (named x in the function, though you could name it v as well).

The returned function is of course assigned to obj.TheCallback.

Its variable scope exists as long as the function exists, so it will continue to have reference to any variables that it needs that were in the variable scope when it was created.


Another solution:

var i, obj;

for ( i = 0; i < arr.length; i++ ) {

    obj = new Thing;

    (function ( v ) {
        obj.callback = function ( e ) {
            // do stuff with v
        };
    })( arr[i] );

}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号