Search code examples
node.jstypeerrorstrict

JavaScript and semicolon


'use strict'
[1,2,3,4].find(x => x > 1)

When the above code is executed with Node.js 5.0.0, it gives the following error:

TypeError: "use strict"[(((1 , 2) , 3) , 4)].find is not a function
at Object.<anonymous> (C:\src\nodejs\ecma6.js:2:11)
at Module._compile (module.js:425:26)
at Object.Module._extensions..js (module.js:432:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)
at Function.Module.runMain (module.js:457:10)
at startup (node.js:136:18)
at node.js:972:3

The error goes away if I add a semicolon after 'use strict'.

This looks like a bug... Or is there anything deeper - meaning whether there is a list of exceptional cases in the language specification, in which a semicolon is required.

The language specification does list exceptional cases, in which explicit semicolons are required.


Solution

  • This is one reason why it is always advised to use semicolons in javascript. The reason it doesn't work is because the code is interpreted as:

    "use strict"[1,2,3,4] ...
    

    In other words it's interpreted as:

    "use strict"[4] ...
    

    because of the comma operator. This evaluates to the string "s".

    Now, the rest of the code is trying to do:

    "s".find()
    

    but strings don't have the find method.

    To avoid all this, make sure you tell the interpreter that the two lines are separate statements - use a semicolon.


    Additional note:

    This behavior is required by the ECMAScript standards (at least ES5). In section 7.9.1 part 1 the rules governing this case is defined:

    When, as the program is parsed from left to right, a token (called the offending token) is encountered that is not allowed by any production of the grammar, then a semicolon is automatically inserted before the offending token if one or more of the following conditions is true:

    1. The offending token is separated from the previous token by at least one LineTerminator.

    2. The offending token is }.

    In this case, the "use strict" and [1,2,3,4]... is parsed. The compiler looks at the resulting statement:

    "use strict"[1,2,3,4]...
    

    and notes that this is valid javascript. Therefore a semicolon is not inserted since no "offending token" is found in the statement.