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 plex to my case, so I ask a new one:
Another looks good but not work case 2:
x=1
(function(){console.log("123");})()
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 plex to my case, so I ask a new one:
https://stackoverflow./a/2846298/1586797
Another looks good but not work case 2:
x=1
(function(){console.log("123");})()
Share
Improve this question
edited Aug 13, 2018 at 7:15
bronze man
asked Aug 13, 2018 at 6:33
bronze manbronze man
1,6272 gold badges18 silver badges30 bronze badges
1
-
The correct way to join two js files into one is add
;
between them. Add"\n"
may not work. – bronze man Commented Aug 13, 2018 at 7:01
7 Answers
Reset to default 4The 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 illegalThe 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 pletely 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.
(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.
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.
Without the semicolon those statements are chained. You call the first function and give the second func as argument to the return value of the first one. This could actually work, if the first function had a function as return value.
When you expand the code it bees more obvious:
var a = function(){console.log("abc");};
var b = function(){console.log("123");}
(a)()
(b)();
the last two lines bee:
(a)()(b)();
this is equivalent to
var x = a();
x(b);
since a
does not return anything, it cannot call it as function with b
as argument.
I think this will be clearer if you use this:
x=1
(function(){console.log("123");})()
The error states 1
is not a function. Makes it clear that (function...)
is treated like the argument of a function call to 1
:
x=1(function(){console.log("123");})()
Because ()() is self-invoking function and ();() are two differnt functions and interpreter is interpreting it accordingly.
Here two pieces of code are totally different for an interpreter.
(function(){console.log("abc");})()(function(){console.log("123");})();
and
(function(){console.log("abc");})();(function(){console.log("123");})();
however, this code will work fine
var a=12
var b=10
console.log(a+b)
Long answer sort :
(function(){console.log("abc");})()
is trying to immediately-invoke the preceding expression which is
(function(){console.log("123");})();
Which would be the return value of the preceding IIFE.
IIFEs can act differently in the missing semicolon situation. That is why we see code as follows:
;(function() {
console.log('abc');
})()
Please have a look of details description here : https://gist.github./khellang/8518964