47
var funcs = []
[1, 2].forEach( (i) => funcs.push( () => i  ) )

Why does it produce the error below?

TypeError: Cannot read property 'forEach' of undefined
    at Object.<anonymous>

However, the error goes away if the semicolon ; is added to the end of the first line.

2
  • 3
    You should add the semicolon to your lines. The code is been seen as var funcs = [][1, 2].forEach... Commented Aug 12, 2016 at 0:55
  • 3
    You could use .map() instead of .forEach() at single line var funcs = [1, 2].map( (i) => () => i ) to avoid issue with semicolon Commented Aug 12, 2016 at 1:01

6 Answers 6

56

There is no semicolon at the end of the first line. So the two lines run together, and it is interpreted as setting the value of funcs to

[][1, 2].forEach( (i) => funcs.push( () => i  ) )

The expression 1, 2 becomes just 2 (comma operator), so you're trying to access index 2 of an empty array:

[][2] // undefined

And undefined has no forEach method. To fix this, always make sure you put a semicolon at the end of your lines (or if you don't, make sure you know what you're doing).

Sign up to request clarification or add additional context in comments.

5 Comments

"The expression 1, 2 becomes just 2", can you elaborate a bit?
@naveen When JavaScript sees an expression like a, b, c, it evaluates all of the sub-expressions in order, a, then b, then c and then returns the value of the last sub-expression (c). This is useful e.g. when the previous expressions are only used for their side effects in a situation where only expressions are allowed, like the first line of a for loop.
Such a classic example of why semicolons should be used, though there are many cases where they are not needed.
An even better example calls a method on an array literal after defining a multi-line object literal. In such a scenario, it takes a really sharp eye to spot the lack of a semicolon that would not be needed following the use of braces for block scoping. And even in projects where semicolons are used extensively, how commonly are they used after block scoping?
I know what I am doing because I know that before anonymous arrays must be semicolon;;;;)
5

we called the forEach method on an undefined value, we got the error.

    const myarr = undefined;

//  Initialize to empty array if falsy
const arr = myarr || [];

//  Using optional chaining
arr?.forEach(element => {
  console.log(element);
});

//  Check if truthy
if (arr) {
  arr.forEach(element => {
    console.log(element);
  });
}

//  Check if Array
if (Array.isArray(arr)) {
  arr.forEach(element => {
    console.log(element);
  });
}

Comments

4

Keep the semi-colon so the variable declaration of funcs does not include the anonymous array you instantiate as belonging to the variable and also, if you are simply trying to push all the elements of the array into 'funcs' then it should look like:

[1, 2].forEach( (i) => funcs.push(i) )

1 Comment

I think it's rather clear from the variable name used that the transformation of numbers into functions returning the numbers is quite intentional. Were that not the case, the obvious solution would simply be var funcs = [1, 2];
3

Whenever we are using an array to loop over bunch of events, it is required to put semicolon to the previous line.

After we query the element we should end the line with semicolon

const el = document.getElementById("giri");
['click', 'touchend'].forEach(event => console.log(event))

I got the above error because I didn't put semicolon before the anonymous array

const el = document.getElementById("giri")
['click', 'touchend'].forEach(event => console.log(event))

Comments

0

Another solution to this problem is to avoid using anonymous array. No semicolons needed.

var funcs = []
var arr = [1, 2]
arr.forEach( (i) => funcs.push( () => i  ) )

Comments

0

Add semi-colon in the of first line

var funcs = []; //<-- ; semi-colon added here
[1, 2].forEach( (i) => funcs.push( () => i  ) )

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.