Javascript closure syntax

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

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

against

  (function(obj) { console.log(obj); })(extObj); 
+6
source share
3 answers

If you are looking for a direct action using a function called immediately, then there is no real difference between them, except that the first returns this inside the function to the outside world automatically (this is what new does), and by default, if no other return value specified (regular functions return undefined ).

The remaining significant differences are not really significant - access to the prototype chain will be pointless if the return point this.constructor on an anonymous function gives you access to cache an anonymous function to use (for example, remove it from the event listener if you managed to insert a closed function in ...... that would be a trick in itself).

Allowing users to cache your immediate function as a constructor property of the this return object can be a security risk ...... or it can be really useful ...... in very specific scenarios.

The daily shooting targets in the line - there is no real difference.

+4
source

The first returns a link to the newly created instance of your anonymous constructor function (= this ).

The second 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 s.)

The difference becomes 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 (function)() much more useful for everyday usecase - you assign the return value of the execution of this function to a variable, which will usually be what you want if you work with immediately called functions. Especially when you have more complex 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 a function declaration into an expression that is immediately called. Therefore, you can also write:

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

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

+9
source

Another difference is that the first call creates an additional object. Here I put the names f and o to denote objects:

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

In the second case, we still create an object of function f , but we do not create o :

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

The closure is still being created, but it's cheaper than the actual JavaScript object, since it does not carry a whole chain of prototypes or other attributes (like a hidden class reference) with it,

+1
source

Source: https://habr.com/ru/post/922551/


All Articles