Is there any advantage of wrapping a function with an anonymous function? I mean a particular example:
function asyncFuntion(callback) {
setTimeout(callback, 6000);
};
asyncFuntion(function() {
console.log('Calling after 6 s.');
});
and with the wrapped function:
function asyncFuntion(callback) {
setTimeout(function() {
callback();
}, 6000);
};
asyncFuntion(function() {
console.log('Calling after 6 s.');
});
In both cases output is the same. So is there any difference? The second version is what I found learning js. I realize that such a form is useful when we need closures but here?
3 Answers 3
The second form allows you to pass arguments to callback, whereas the first form doesn't.
// 1st form
setTimeout(callback("This doesn't work as you might expect"), 6000);
// 2nd form
setTimeout(function() {
callback("This works");
}, 6000);
If you're not passing arguments, then there is no advantage in wrapping the function whatsoever.
To be more thorough,
Function.prototype.bind can help us with the first form:
setTimeout(callback.bind(this, "This works fine too"), 6000);
// Even with Richard JP Le Guen's example by specifying the thisObj
setTimeout(customObj.alert.bind(customObj), 6000);
However, you will need to provide this method to browsers that don't support the event (namely Opera, Safari and IE 8, 7, 6). The code to shim the method is available on the MDN documentation page.
12 Comments
setTimeout(callback.bind(this, 'This works aswell'), 6000);setTimeout(callback, 6000, 'This works as well'), though ;)apply in Function.prototype ?apply is not sufficient for that purpose. We don't want the callback to immediately execute, but we want to bind the context and arguments for a call at some later point. So bind() is rather new.Wrapping a function in an anonymous function can avoid complications with the this keyword. (read about them on quirksmode)
For example:
function CustomObject() {
this.msg = "Hello world from my custom object";
this.alert = function() {
alert(this.msg);
};
}
var customObj = new CustomObject();
setTimeout(customObj.alert, 1000); // the alert message says `undefined`
setTimeout(function() {
customObj.alert();
}, 2000); // the alert message says "Hello world from my custom object"
Wrapping a function in an anonymous function is also key to using closures in JavaScript:
var arr = ['a','b','c','d','e'];
// will always alert undefined
for(var i=0; i<arr.length; i++) {
setTimeout(function() {
console.log(arr[i]);
}, 1000*i);
}
// outputs the values of `arr`
for(var j=0; j<arr.length; j++) {
setTimeout((function(indx) {
return function() {
console.log(arr[indx]);
}
}(j)), 1000*j);
}
Comments
Wrapping is useful if you need to have separate identity.
var x = function () { cleanup(); };
var y = function () { cleanup(); };
if (x === y) ... // not true
For example, some functions like addEventListener operate on identity.
element.addEventListener("myEvent", beep, false);
element.addEventListener("myEvent", beep, false);
The second time you call addEventListener, it says "I've already got a beep; I don't need to add another." When the myEvent event is fired, you get only one beep. If you want two beeps, you need to make sure the callbacks are different.
element.addEventListener("myEvent", function() { beep(); }, false);
element.addEventListener("myEvent", function() { beep(); }, false);
Each anonymous function is different, so this time you registered two functions (which happen to do the same thing). Now it will beep twice.
1 Comment
Function.prototype.bind() can be useful.