admin管理员组

文章数量:1279043

What is the difference, pros/cons (if any) between these constructs?

 new function(obj) {
     console.log(obj);
 }(extObj);

vs

 (function(obj) {
     console.log(obj);
 })(extObj);

What is the difference, pros/cons (if any) between these constructs?

 new function(obj) {
     console.log(obj);
 }(extObj);

vs

 (function(obj) {
     console.log(obj);
 })(extObj);
Share Improve this question asked Aug 10, 2012 at 7:44 vearutopvearutop 4,07226 silver badges42 bronze badges 1
  • Could I add - is there a difference between (function(obj) { .. })(extObj); and function(obj) { .. })(extObj); ? – Matt Roberts Commented Aug 10, 2012 at 8:48
Add a ment  | 

3 Answers 3

Reset to default 9

The first one returns a reference to the newly constructed instance of your anonymous constructor function (= this).

The second one returns the return value of the anonymous function. Since your function does not have a return statement, it will implicitly return undefined.

Try the following:

var t1 = new function(obj) { console.log(obj); }(extObj);
var t2 =    (function(obj) { console.log(obj); })(extObj);

typeof t1 => "object"
typeof t2 => "undefined"

(Btw, t1.constructor will return the original function you created t1 with.)

The difference bees much clearer, if you add a return statement:

var t1 = new function(obj){ return(obj); }("foo");
var t2 =    (function(obj){ return(obj); })("bar");

console.log(t1) => "object"
console.log(t2) => "bar"

IMO, this makes the (function)() much more useful for the everyday usecase - you assign the returnvalue of the execution of this function to the variable which normally would be what you want if you are working with immediately invoked functions. Especially when having more plex things like (pseudocode):

var myNameSpace = (function(){
    /* do some private stuff here*/
    ...
    /* expose parts of your anonymous function by returning them */
    return{
       functionX,
       variable1,
       variable2
    }
}();

Basically you can use an arbitrary unary operator to turn the function declaration into an expression, that is immediately invoked. So you could also write:

!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();

depending on the return statement of your function, these will give different return results. ! - negate the returnvalue +|- evaluate as Number (apply negative sign) ~ apply bitwise not to the return value.

If you're looking at dealing expressly with an immediately-invoked function, then there isn't any real difference between the two, except that the first one will return this inside the function, to the outside world, automatically (that is what new does), and by default if a different return value is not specified (regular functions return undefined).

The rest of the major differences are not really going to matter -- access to the prototype chain is going to be pointless, having the returned this.constructor point to the anonymous function would give you access to caching the anonymous function for use at a later time (like removing it from an event listener, if you somehow managed to stick the enclosed function in... ...that would be a trick in and of itself).

Allowing people to cache your immediately-invoked function as a constructor property of the returned this object might be a security-risk... ...or it might be really useful... ...in very specific scenarios.

Every-day purposes of firing code in-line -- no real difference.

Another difference is that the first invocation creates an extra object. Here I've put the names f and o to denote an objects:

var o = new function f(obj) {
    console.log(obj);
}(extObj);

In second case we still create a function object f but we don't create an o:

(function f(obj) {
    console.log(obj);
})(extObj);

A closure is still created but that's cheaper than the actual JavaScript object since it doesn't carry the whole prototype chain or other attributes (like hidden class reference) with it,

本文标签: Javascript closure syntaxStack Overflow