简体   繁体   中英

Strange TypeError in Node.js

I'm going through a JavaScript book and have been executing code samples using Node.js. I've been writing files then running node file.js .

Normally, I use semicolons writing JavaScript, but I'm following the book's style.

I came across a error while executing one of the code samples, and I can't figure out why it happens.

Executing:

var x = 2
var y = 3
(x == 2) && (y == 3)
(x > 3) || (y < 3)

Results in the error:

TypeError: 3 is not a function

If I add a ; after line 2, eg

var x = 2
var y = 3;
(x == 2) && (y == 3)
(x > 3) || (y < 3)

It results in the error:

TypeError: (y == 3) is not a function

However, if I place a ; after the third line as well, eg

var x = 2
var y = 3;
(x == 2) && (y == 3);
(x > 3) || (y < 3)

Things work fine.

Or if I run each line (individually) in the Node.js command line, everything works fine.

It's probably just my misunderstanding of Node.js or JavaScript. But I couldn't find another similar situation online.

I'm using OS X 10.11.1 and Node.js v5.2.0 (installed through Homebrew).

This would happen in any JavaScript environment, not just node. There are specific rules as to when semi-colons can be omitted. This is why the majority if the community advocates against omitting semi-colons.

This is being executed as a single statement:

var y = 3
(x == 2) && (y == 3)
(x > 3) || (y < 3)

Statements are delineated by context (or semi-colon), not by whitespace or newlines.

var y = parseInt('10px');

is the same as

var y = parseInt
('10px');

is the same as

var y = parseInt             ('10px');

So when you try to execute var y = 3 (x == 2), the JIT is interpreting 3 as a function, due to the parenthesis that follow it.

If the next line starts with a '(' then the statement is not terminated by a new line. Therefore, you need a ';' or some other token to specify that the statement has ended.

You can read more about javascript and semicolons here and here .


Your first error is occurring because the code is being interrupted as:

var y = 3(x == 2)

The second error if from the code being interrupted as:

(y == 3)(x > 3)

These are invalid.


Adding the semicolons changes your code to

var y = 3;(x == 2)

and

(y == 3);(x > 3)

These are valid.


Javascript uses the semicolon and not newline to denote the end of a statement and the possible beginning of another. So, when you tried to execute:

var x = 2
var y = 3
(x == 2) && (y == 3)
(x > 3) || (y < 3)

It interpreted it as:

var x = 2 var y = 3(x==2) && (y==3)(x > 3) || (y<3)

Which seemed like you were trying to initialize y with the value of function 3(x=2) which is wrong syntax and semantics for a function declaration in javascript.

When you put a semicolon after the second line, it interpreted lines 1 and 2 as you meant them to be interpreted, but again a similar issue arose in lines 3 and 4, which were fixed once you added the semicolons.

You only need semicolons where javascript cannot tell the end of one statement and the beginning of another. You can omit them, but the general rule is something like this .

As you can see here ,

The source

a = b + c

(d + e).print()

is not transformed by automatic semicolon insertion, because the parenthesised expression that begins the second line can be interpreted as an argument list for a function call:

a = b +c(d + e).print()

In the circumstance that an assignment statement must begin with a left parenthesis, it is a good idea for the programmer to provide an explicit semicolon at the end of the preceding statement rather than to rely on automatic semicolon insertion.

It's a well known pitfall when coding without semicolons in JavaScript and that also behaves the same for Node.js.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM