ccxvii / mujs

An embeddable Javascript interpreter in C.
http://mujs.com/
ISC License
812 stars 98 forks source link

forEach instruction breaks: TypeError: cannot convert undefined to object #96

Closed yurivict closed 5 years ago

yurivict commented 5 years ago

Please run the testcase attached below.

When the p call is present, it breaks in forEach in the line 9:

$ mujs forEach.js 
TypeError: cannot convert undefined to object
    at fn (forEach.js:9)
    at forEach.js:17

Removing the p call eliminates the error message.

---begin testcase forEach.js---

function p(msg) {
}

function fn() {
  // Removing this call eliminates the failure
  p("--2--")

  // (***) This breaks:
  [1,2,3].forEach(function(a) {
  })

  // This works fine:
  //for (var a = 1; a <= 3; a++) {
  //}
}

fn()

---end testcase forEach.js---

ccxvii commented 5 years ago

Yes. This is as expected. Use semicolons or you will be surprised!

This is what you wrote:

p("--2--")[1,2,3].forEach(function(a){});

p() returns undefined, from which you're taking index 3 (1,2,3 is a comma expression).

yurivict commented 5 years ago

Why are semicolon rules different for forEach? For example, this works:

print('A')
print('B')

but this doesn't:

print('A') print('B')
SyntaxError: semi.js:2: unexpected token: (identifier) (expected ';')

Based on this example, semicolon is optional when the newline is present. Shouldn't it be the same for all instructions?

Also, see here: https://www.quora.com/Are-semicolons-required-in-JavaScript

Is there a paragraph in the JS standard that specifies such behavior?

ccxvii commented 5 years ago

The problem is not forEach, the problem is a function call followed by the array constructor.

Javascript generally requires semicolons, but it automatically inserts semicolons before newlines, if the parse would otherwise fail.

http://www.ecma-international.org/ecma-262/5.1/#sec-7.9