8

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?

asked Oct 19, 2011 at 13:32

3 Answers 3

11

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.

answered Oct 19, 2011 at 13:33
Sign up to request clarification or add additional context in comments.

12 Comments

setTimeout(callback.bind(this, 'This works aswell'), 6000);
@jAndy: yup, but not in older browsers without a shim. Thank you for not suggesting setTimeout(callback, 6000, 'This works as well'), though ;)
@AndyE what do you mean it doesn't work in older browsers? they don't have apply in Function.prototype ?
@AndyE: lmao, didn't even know that setTimeout curry's the arguments to the callback function. I guess its not standard if you comment it like you did ?
@Esailija: 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.
|
5

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);
}
answered Oct 19, 2011 at 13:37

Comments

5

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.

answered Oct 19, 2011 at 14:26

1 Comment

+1, this is one of those edge cases that most don't think about. FWIW, this is another scenario where Function.prototype.bind() can be useful.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.