Possible Duplicate:
Javascript closure inside loops - simple practical example
I have a for loop with an anonymous function inside, and in the function I want to access the current loop iteration. But for some reason instead of the loop iteration, I'm getting 4. The only other place 4 is a value is myArray.length. If I pass i as an argument, I get [object Object] out. What am I doing wrong? My code:
var width = function(){
for(var i = 0, len = myArray.length; i < len; ++i){
alert(i) //this outputs the current iteration
myArray[i].load(function(){
alert(i) //this outputs 4 (or [object Object])
});
};
};
Thanks.
Your anonymous function passed to .load
is being executed way after your loop has finished.
You have to create a local scope, and copy the i
variable:
var width = function(){
for(var i = 0, len = myArray.length; i < len; ++i){
(function(i){
myArray[i].load(function(){
alert(i) //this outputs 4 (or [object Object])
});
})(i);
};
};
ECMAScript 5
includes bind()
[docs], which is used to get a function with the this
value as well as argument values bound to it.
function loader( i ){
alert( i );
}
var width = function(){
for(var i = 0, len = myArray.length; i < len; ++i){
alert( i );
myArray[i].load( loader.bind( null, i ) );
}
};
Here I bound null
as the this
value in the function returned, but you can set it to something else. Then I bound the current value of i
as the first argument.
To get support for older browsers (if needed), include the shim from MDN:
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") // closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be fBound is not callable");
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP ? this : oThis || window, aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
This is a mostly compatible shim that will work for most cases.