Why do I need parentheses for JavaScript IIFE?

I am reading JavaScript IIFE and still understand the concept, but I'm curious about the outer bracket. In particular, why are they needed? For instance,

(function() {var msg='I love JavaScript'; console.log(msg);}()); 

works fine but

 function() {var msg='I love JavaScript'; console.log(msg);}(); 

generates a syntax error. What for? There is a lot of discussion about IIFE, but I don’t see a clear explanation of why parentheses are needed.

+4
source share
3 answers

The IIFE version, which is wrapped in brackets, works because it marks the declaration of the declaration of an internal function as an expression.

http://benalman.com/news/2010/11/immediately-invoked-function-expression/

For more detailed explanations, see:

Advanced JavaScript: why is this function enclosed in parentheses?

Hint:

The call operator (()) only works with expressions, not with declarations.

+3
source

There are two ways to create functions in JavaScript (well, 3, but ignore new Function() ). You can either write a function declaration or write a function expression.

A function declaration is itself an operator, and the instructions themselves do not return values ​​(let them also ignore how the debug console or Node.js REPL print the return values ​​of the statements). However, a function expression is a valid expression, and JavaScript expressions return values ​​that can be used immediately.

Now you may have seen people saying that the following function expression:

 var x = function () {}; 

It may be tempting to conclude that the syntax is:

 function () {}; 

- this is what makes it an expression. But this is wrong. The syntax above makes it an anonymous function. And anonymous functions can be either a declaration or an expression. What makes an expression such a syntax:

 var x = ... 

That is, everything that is to the right of the = sign is an expression. Expressions make it easy to write mathematical formulas in programming languages. Thus, it is ubiquitous that mathematics is expected to be processed is an expression.

Some forms of expression in JavaScript include:

  • everything to the right of the operator =
  • things in braces () that are not function call brackets
  • everything to the right of the mathematical operator ( + , - , * , / )
  • all arguments to the ternary operator .. ? .. : .. .. ? .. : ..

When you write:

 function () {} 

this declaration and does not return a value (declared function). Therefore, an attempt to cause a non-result is a mistake.

But when you write:

 (function () {}) 

this expression returns a value (declared function) that can be used immediately (for example, can be called or can be assigned).

Pay attention to the rules for what is considered the expression above. It follows that braces are not the only things you can use to build IIFE. The following are valid ways to build IIFE (because we write function expressions):

 tmp=function(){}() +function(){}() -function(){}() 0/function(){}() 0*function(){}() 0?0:function(){}() (function(){}()) (function(){})() 

In fact, you can see one of the above non-standard forms (especially version + ) in third-party libraries, because they want to save one byte. But I strongly recommend that you use only curly braces (or they are beautiful), because they are widely recognized as IIFE by other programmers.

+5
source

It will be a long answer, but it will give you the necessary background. There are two ways to define functions in JavaScript: Function Definition (Classic View)

 function foo() { //why do we always use } 

and then a more hidden type, function expression

 var bar = function() { //foo and bar }; 

Essentially, the same thing happens when executed. A functional object is created, memory is allocated, and the identifier is bound to this function. The difference is in the syntax. The former is itself an expression declaring a new function; the latter is an expression.

An expression of a function enables us to insert a function in any place where a normal expression would be expected. This enables anonymous functions and callbacks. Take for example

 setTimeout(500, function() { //for examples }); 

Here an anonymous function will be executed whenever it says setTimeout. However, if we want to immediately execute a function expression, we need to make sure that the syntax is recognized as an expression, otherwise we have an ambiguity as to whether we mean a function expression or an operator.

 var fourteen = function sumOfSquares() { var value = 0; for (var i = 0; i < 4; i++) value += i * i; return value; }(); 

Here sumOfSquares is called immediately because it can be recognized as an expression. fourteen becomes 14 , and sumOfSquares collects trash. In your example, the grouping operator () forces its contents to an expression, so the function is an expression and can be called immediately as such.

It is important to note that the difference between my first example foo and bar is the rise. If you don’t know what it is, you should say a quick Google search or two, but a quick and dirty definition is that lifting is JavaScript behavior to bring declarations (variables and functions) to the top of the field. These declarations usually only raise the identifier, but not its initialized value, so the entire scope will be able to see the variable / function before it is assigned a value.

This is not the case with function definitions; the entire declaration is declared here and will be visible in the entire content area.

 console.log("lose your " + function() { fiz(); //will execute fiz buzz(); //throws TypeError function fiz() { console.log("lose your scoping,"); } var buzz = function() { console.log("and win forever"); }; return "sanity"; }()); //prints "lose your scoping, lose your sanity" 
+2
source

All Articles