eval is not a function [duplicate] - javascript

This question already has answers here:
TypeError: console.log(...) is not a function [duplicate]
(6 answers)
Closed 5 years ago.
It might interest somebody and save few hours, a nasty bundling problem, eval is from one file and function is from second file.
eval('console.log(0)')
(function(x){console.log(x)})(1)
will result with: Uncaught TypeError: eval(...) is not a function
and this is the fix
eval('console.log(0)');
(function(x){console.log(x)})(1)
missing semicolon, I've read few times that semicolon in JS optional most of the time.
any comments why eval is not a function in this context?

The JS runtime is not perfect at guessing where semi-colons should go.
When it sees this:
eval('console.log(0)')
(function(x){console.log(x)})(1)
It incorrectly assumes that the result of the immediately invoked function expression is part of the eval line (a potential parameter to be passed to the potential function that the eval evaluates to).
Here's an example of when that would work:
eval("(function(message){ alert(message); })")
("Hi there!");
But, in your case, eval is not evaluating to a function, so trying to pass an argument to it fails, thus your error message.
But, it actually has less to do with eval(), in particular. This can pop up anytime a semi-colon is omitted just prior to an IIFE or any expression starting with a (.
Adding the semi-colon, allows the runtime to know that the IIFE is separate.
The rule is that you must insert semi colons on any line that is followed by a ( (as this is how an expression can begin) in order to keep them separate . But, the better rule is to not rely on automatic semi-colon insertion at all and always put them in yourself.

This is one of the few situations in which Javascript's semicolon insertion will trip you up.
This code:
eval('console.log(0)')
(function(x){console.log(x)})(1)
Is equivalent to this code:
eval('console.log(0)')(function(x){console.log(x)})(1)
In other words, Javascript thinks that the expression eval('console.log(0)') evaluations to a function which you are trying to call with the parameter (function(x){console.log(x)}). That is obviously not what you intended, so you need semicolons at the end of your lines.

Related

Using semi-colons to close functions in JavaScript. Necessary? [duplicate]

This question already has answers here:
Do you recommend using semicolons after every statement in JavaScript?
(11 answers)
Closed 6 years ago.
When executing a function in JavaScript, I've always ended my code block with a semi-colon by default, because that's what I've been taught to do. Coming from Java it felt a bit unorthodox at first, but syntax is syntax.
function semiColon(args) {
// code block here
};
or
function sloppyFunction(args) {
// code block here
}
Lately I've been seeing more and more code where the developer left the semi-colon out after functions, but the intended code still executed normally. So are they actually required? If not, why is it common practice to include them? Do they serve another purpose?
Function declarations do not need a semi-colon, though if you put a semi-colon there, it won't be harmful, it is just a redundant empty statement.
function semiColon(args) {
// code block here
};;;; // 4 empty statements
Most statements require a semi-colon, but if you leave the semi-colon out it will be inserted automatically in most cases by Automatic Semi-Colon Insertion, with caveats. In general it is easier to just always add a semi-colon after your statements, so that you, and other developers working with your code, don't have to worry about those caveats.
This code is correct:
function semiColon(args) {
// code block here
} // No need for semi-colon
var semiColon = function (args) {
// code block here
}; // Semi-colon required here
Whereas this code is wrong, but will still usually work:
function semiColon(args) {
// code block here
}; // Redundant unnecessary Empty Statement
var semiColon = function (args) {
// code block here
} // Semi-colon required here,
// but ASI will sometimes insert it for you, depending on
// the subsequent token
NO - using semicolons to end function declarations are NOT necessary in JavaScript. While they will not throw an error, they are the equivalent of using more than one semicolon to end a line of code - harmless, but unnecessary. Being superfluous, they are considered poor stylistic and programming practice.
The one exception is a function expression, e.g.
var my_function = function(a, b){ };
where you DO need the semicolon to terminate the line.
You shall not add a semicolon after a function declaration.
Because, after checking the Javascript grammar:
StatementList:
StatementListItem
StatementList
StatementListItem:
Statement
Declaration
Declaration:
HoistableDeclaration
ClassDeclaration
LexicalDeclaration
HoistableDeclaration:
FunctionDeclaration
GeneratorDeclaration
Here's the grammar production for a function:
FunctionDeclaration → HoistableDeclaration → Declaration → StatementListItem → StatementList
which proves that my former response is wrong (no need to look at the former edits, as it's wrong! ;) ).
A function xx() {} construct alone is a special case, neither — strictly speaking — a statement or an expression, and thus is NOT to be ended with a semicolon.
You only need to add a semicolon (or leave the ASI take care of it) if you're using the expression function() construct, which exists when it is part of a statement. To make it a statement you need to either have it part of a statement:
var foo = function() {};
or embedded within another expression:
(function() {})();
!function x() { ... }();
And in either cases, you need to add the semicolon at the end of the full statement, obviously.
Generally speaking, I like the python mantra "explicit is better than implicit" so when you hesitate to add a semicolon that the ASI would add otherwise, just add it.
sorry for being wrong in the first version of my answer, I'll debug some PHP code as a penitence. ☺
HTH

Why does Google Closure Compiler optimize with null==a instead of a==null? [duplicate]

This question already has an answer here:
Why does Google Closure swap arguments?
(1 answer)
Closed 8 years ago.
So I use the Google Closure Compiler to minify my JavaScript before using it in production. Today, I paid attention to how it minifies and optimizes(?) the code and realized this trend:
Compiling the code below :
function b(a) {
if ( a == null ) {
console.log('ohai');
}
}
resulted in an optimization in the comparison expression where the literal is moved to the left and the variable to the right. As in
function b(a){null==a&&console.log("ohai")}
(Btw, it subsitutes single quotes for double quotes.) The expression remains the same if the other operand is an object. Why is moving the literal to the left of the operator an optimization of the expression?
There's no optimisation improvement (EDIT: possibly a hasty statement, DCoder's comment for e.g. is valid), but you could make the argument that it's just prudent practice.
For example, a programmer might accidentally use a single = instead of == - resulting in assignment instead of an equality check.
The following code would silently evaluate with no error:
var a = null;
function b(a){a=null&&console.log("ohai")} // notice the single =
b(a); // nothing
However, the way google does it, it produces an error in the console (tested in Chrome):
var a = null;
function b(a){null=a&&console.log("ohai")} // notice the single =
b(a); // produces error Uncaught ReferenceError: Invalid left-hand side in assignment
Hence, using null as the left-hand side makes these kind of user errors easier to spot.

Javascript code snippet explanation [duplicate]

This question already has answers here:
Automatic semicolon insertion & return statements [duplicate]
(3 answers)
Closed 9 years ago.
I have seen this trick question online without any answer or description. Not sure what's going on here:
function identity() {
var name = 'Jack';
alert(name);
return
name
};
var who = identity();
alert(who)
This snipped outputs, jack & then undefined, why?
Change this
return
name
to this:
return name;
The return statement is one of the few places where javascript does not like whitespace. EDIT. What's happening in the original is the browser inserts a semicolon after the return statement, like this
return;
name // this gets ignored
So the return value is undefined.TehShrike links to a very good document explaining the exact rules ECMAAScript environments must follow when ignoring whitespace/line breaks and when semicolons must be inserted.
The ECMAScript standard says this (among other things)
Certain ECMAScript statements (empty statement, variable statement,
expression statement, do-while statement, continue statement, break
statement, return statement, and throw statement) must be terminated
with semicolons. Such semicolons may always appear explicitly in the
source text. For convenience, however, such semicolons may be omitted
from the source text in certain situations. These situations are
described by saying that semicolons are automatically inserted into
the source code token stream in those situations.
identity is a function. who then declares a new instance of that, which we can tell from the func that it will create a local variable name and assign jack to it, then alert.
The function then looks like it return nothing (although name is on the next line, so I'd imagine you want to return that, change to return name;).

Why use (function(){})() or !function(){}()?

I was reading In JavaScript, what is the advantage of !function(){}() over (function () {})()? then it hit me, why use :
(function(){})() or !function(){}() instead of just function(){}()?
Is there any specific reason?
It depends on where you write this. function(){}() by itself will generate a syntax error as it is evaluated as function declaration and those need names.
By using parenthesis or the not operator, you enforce it to be interpreted as function expression, which don't need names.
In case where it would be treated as expression anyway, you can omit the parenthesis or the operator.
I guess you are asking why use:
var fn = (function(){}());
versus:
var fn = function(){}();
The simple answer for me is that often the function on the RHS is long and it's not until I get to the bottom and see the closing () that I realise I've been reading a function expression and not a function assignment.
A full explanation is in Peter Michaux's An Important Pair of Parens.
A slight variation on RobG's answer.
Many scripts encompass the entire program in one function to ensure proper scoping. This function is then immediately run using the double parentheses at the end. However, this is slightly different then programs which define a function that can be used in the page but not run initially.
The only difference between these two scenarios is the last two characters (the addition of the double parentheses). Since these could be very long programs, the initial parenthesis is there to indicate that "this will be run immediately."
Is it necessary for the program to run? No. Is it helpful for someone looking at the code and trying to understand it? Yes.

Are semicolons needed after an object literal assignment in JavaScript?

The following code illustrates an object literal being assigned, but with no semicolon afterwards:
var literal = {
say: function(msg) { alert(msg); }
}
literal.say("hello world!");
This appears to be legal, and doesn't issue a warning (at least in Firefox 3). Is this completely legal, or is there a strict version of JavaScript where this is not allowed?
I'm wondering in particular for future compatibility issues... I would like to be writing "correct" JavaScript, so if technically I need to use the semicolon, I would like to be using it.
Not technically, JavaScript has semicolons as optional in many situations.
But, as a general rule, use them at the end of any statement. Why? Because if you ever want to compress the script, it will save you from countless hours of frustration.
Automatic semicolon insertion is performed by the interpreter, so you can leave them out if you so choose. In the comments, someone claimed that
Semicolons are not optional with statements like break/continue/throw
but this is incorrect. They are optional; what is really happening is that line terminators affect the automatic semicolon insertion; it is a subtle difference.
Here is the rest of the standard on semicolon insertion:
For convenience, however, such semicolons may be omitted from the source text in certain situations. These situations are described by saying that semicolons are automatically inserted into the source code token stream in those situations.
The YUI Compressor and dojo shrinksafe should work perfectly fine without semicolons since they're based on a full JavaScript parser. But Packer and JSMin won't.
The other reason to always use semi-colons at the end of statements is that occasionally you can accidentally combine two statements to create something very different. For example, if you follow the statement with the common technique to create a scope using a closure:
var literal = {
say: function(msg) { alert(msg); }
}
(function() {
// ....
})();
The parser might interpret the brackets as a function call, here causing a type error, but in other circumstances it could cause a subtle bug that's tricky to trace. Another interesting mishap is if the next statement starts with a regular expression, the parser might think the first forward slash is a division symbol.
JavaScript interpreters do something called "semicolon insertion", so if a line without a semicolon is valid, a semicolon will quietly be added to the end of the statement and no error will occur.
var foo = 'bar'
// Valid, foo now contains 'bar'
var bas =
{ prop: 'yay!' }
// Valid, bas now contains object with property 'prop' containing 'yay!'
var zeb =
switch (zeb) {
...
// Invalid, because the lines following 'var zeb =' aren't an assignable value
Not too complicated and at least an error gets thrown when something is clearly not right. But there are cases where an error is not thrown, but the statements are not executed as intended due to semicolon insertion. Consider a function that is supposed to return an object:
return {
prop: 'yay!'
}
// The object literal gets returned as expected and all is well
return
{
prop: 'nay!'
}
// Oops! return by itself is a perfectly valid statement, so a semicolon
// is inserted and undefined is unexpectedly returned, rather than the object
// literal. Note that no error occurred.
Bugs like this can be maddeningly difficult to hunt down and while you can't ensure this never happens (since there's no way I know of to turn off semicolon insertion), these sorts of bugs are easier to identify when you make your intentions clear by consistently using semicolons. That and explicitly adding semicolons is generally considered good style.
I was first made aware of this insidious little possibility when reading Douglas Crockford's superb and succinct book "JavaScript: The Good Parts". I highly recommend it.
In this case there is no need for a semicolon at the end of the statement. The conclusion is the same but the reasoning is way off.
JavaScript does not have semicolons as "optional". Rather, it has strict rules around automatic semicolon insertion. Semicolons are not optional with statements like break, continue, or throw. Refer to the ECMA Language Specification for more details; specifically 11.9.1, rules of automatic semicolon insertion.
Use JSLint to keep your JavaScript clean and tidy
JSLint says:
Error:
Implied global: alert 2
Problem at line 3 character 2: Missing
semicolon.
}
The semi-colon is not necessary. Some people choose to follow the convention of always terminating with a semi-colon instead of allowing JavaScript to do so automatically at linebreaks, but I'm sure you'll find groups advocating either direction.
If you are looking at writing "correct" JavaScript, I would suggest testing things in Firefox with javascript.options.strict (accessed via about:config) set to true. It might not catch everything, but it should help you ensure your JavaScript code is more compliant.
This is not valid (see clarification below) JavaScript code, since the assignment is just a regular statement, no different from
var foo = "bar";
The semicolon can be left out since JavaScript interpreters attempt to add a semicolon to fix syntax errors, but this is an extra and unnecessary step. I don't know of any strict mode, but I do know that automated parsers or compressors / obfuscators need that semicolon.
If you want to be writing correct JavaScript code, write the semicolon :-)
According to the ECMAscript spec, http://www.ecma-international.org/publications/standards/Ecma-262.htm, the semicolons are automatically inserted if missing. This makes them not required for the script author, but it implies they are required for the interpreter. This means the answer to the original question is 'No', they are not required when writing a script, but, as is pointed out by others, it is recommended for various reasons.

Categories

Resources