Dmitry Dmitriev
Dmitry Dmitriev

Reputation: 1059

Interesting error based on automatic semicolon insertion JS rules. Explanation required

Today I wrote code for some programming contest. When I run it I was surprised because of error. Cannot read property 'forEach' of undefined in a place where looks like "error free space".

sum = 0
            [-1,0,1].forEach(deltar =>{...});

When I add semicolon after sum variable value assignment code start to works.

sum = 0;
            [-1,0,1].forEach(deltar =>{...});

It's very curious about JS behavior what do interpreter mismatch here? how do JS mess with integer and array after it?

Here it is a full code of the function to make the complete picture of variables declaration.

function boxBlur(img) {
    let [h,w] = [img.length-1,img[0].length-1];
    let [answer,sum,tmp] = [[],0,[]]
    for(let row = 1; row < h; row += 1){
        tmp = []
        for(let clmn = 1; clmn < w; clmn += 1){
            sum = 0;
            [-1,0,1].forEach(deltar =>{
                [-1,0,1].forEach(deltac =>{
                    sum += img[row+deltar][clmn+deltac]
                });
            });
            tmp.push(parseInt(sum/9));
        }
        answer.push(tmp);
    }
    return answer;
}

Upvotes: 1

Views: 72

Answers (2)

Maheer Ali
Maheer Ali

Reputation: 36564

The problem is that when you don't put a semi-colon it doesn't automatically put ; instead

  • it tries to get the property 3 of a number.
  • Here [1,2,3] doesnot work as array but as Bracket Notation.
  • Due to Comma Operator the last operand 3.
  • So the 0[3] is undefined.undefined.forEach(){...} will obviously throw error.

let sum = 0
[1,2,3]
console.log(sum)

Upvotes: 2

Jaromanda X
Jaromanda X

Reputation: 1

1,2,3 === 3 

comma operator

so

[1,2,3] -> [3] i.e. is property named 3 

bracket notation

therefore

sum = 0[3] is undefined - 

since the Number(0) has no property called 3

to illustrate further

var sum = 0
[1,2,3,'constructor']

console.log(sum);

now the code is equivalent to

var sum = 0['constructor']

or

var sum = 0..constructor

which, as you see in the console is the Number object constructor

Upvotes: 3

Related Questions