Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why a newline between parentheses of two function calls not treat as two statements in js?

why this kind of bad design is made on js? Is there any special reason to design the automatic semicolon insertion like this?

Here is my code, It is not work in js in chrome:

(function(){console.log("abc");})()

(function(){console.log("123");})();

Here is the error:

Uncaught TypeError: (intermediate value)(...) is not a function

I know the right version of this code is :

(function(){console.log("abc");})();

(function(){console.log("123");})();

I just want to know why js syntax is designed so stupid. History reason?

I also add this question as a warning to everybody try to use the automatic semicolon insertion of javascript, please just add ; everywhere it needs, the automatic semicolon insertion of javascript is rubbish. It does not work as your expect.

The exist answer is too complex to my case, so I ask a new one:

https://stackoverflow.com/a/2846298/1586797

Another looks good but not work case 2:

x=1

(function(){console.log("123");})()
like image 242
bronze man Avatar asked Aug 13 '18 06:08

bronze man


3 Answers

The linked question's answers explain the spec's three rules for ASI, for example this one. tl;dr:

  • If it doesn't work, try with semicolon.

  • The program should end with a semicolon.

  • If a statement says "can't put newline here", punish it with semicolon.

Your code does not satisfy any of the criteria.

  • The first line could return a function, and if so that function should be allowed to be invoked; so ( that the second line begins with is not illegal

  • The first line is not the last line of the program

  • There is no restricted syntax here.

Therefore, no automatic semicolon for you.

Some people have thus claimed that while (f(){})() syntax is good IIFE syntax, it might be good to do !f(){}() instead:

!function(){console.log("abc");}()

!function(){console.log("123");}();

This works as intended because ! just negates the (discarded) result of the function application, and also because ! as purely unary operator is an illegal character to continue the first line (i.e. f(){}()! is not a thing). This triggers rule 1, and ASI can take place.

The counterargument is that it is butt-ugly (i.e. for anyone not already familiar with the practice, it takes a while for them to understand the purpose of ! in this idiom).

Your second example is similar in nature: as far as the JS parser is concerned, 1 is a value (the fact that it is an integer and could not possibly be a function is a bit lost to it). Look at this example that syntactically is completely equivalent to yours:

a=function(f) { console.log("A CALLED!"); return f; }
x=a
(function(){console.log("123");})()
# => A CALLED!
     123

Here, a is a function, so it can be invoked with function(){console.log("123");} as an argument; it returns function(){console.log("123");} unchanged after printing to the console; then () invokes that return value, and 123 is printed as well. Everything works. Thus, Rule #1 is not triggered, no semicolon for you.

like image 88
Amadan Avatar answered Oct 07 '22 09:10

Amadan


(function(){console.log("abc");})()

(function(){console.log("123");})();

is equivalent to:

(function(){console.log("abc");})()(function(){console.log("123");})();

And is what is usually referred to as function currying. For IIFEs (immediately invoked function expressions) you need to end with ;

For more on function currying see this post. Obviously your console log functions do not work as currying functions, but the syntax yourFunction(a)(b)(c) is a cool feature of the language that is used for currying.

like image 2
Jensei Avatar answered Oct 07 '22 07:10

Jensei


Your code can be simplified as:

(function(){})()()();

This code will get same error.

The () expect a expression to call.

The first () call the (function(){}), the second () call the (function(){})()'s result, but the result is not a function, so it's wrong.

like image 2
Degas Avatar answered Oct 07 '22 07:10

Degas