1

I've just noticed a strange error when using Javascript destructuring assignment, which took me some guesswork to resolve. I'm posting here so I can show what I learned. (I accept that the question about Javascript semicolon insertion is answered by What are the rules for JavaScript's automatic semicolon insertion (ASI)?, but my problem was about how to diagnose a strange error when ASI works differently than I was expecting; it's an answer that I would have hoped to find when searching for "array destructuring error" or similar.)

The following code:

let next_col_time_step = head_steps.reduce(
    choose_next_step, [-1, -1, null]
    )
[next_step_col, next_step_time, next_step] = next_col_time_step

When run generates an very confusing error:

ReferenceError: can't access lexical declaration 'next_col_time_step' before initialization

Despite (apparently) having been just initialized before the error line.

Or, if I try to see what value has been assigned, thus:

let next_col_time_step = head_steps.reduce(
    choose_next_step, [-1, -1, null]
    )
console.log("next_col_time_step %s", next_col_time_step)
[next_step_col, next_step_time, next_step] = next_col_time_step

I see the expected value displayed and a different error:

next_col_time_step 2,52,[object Object] 
TypeError: console.log(...) is undefined

I.e., console.log(...) apparently works as expected, then is reported as undefined. What's going on here?

Graham Klyne
  • 816
  • 10
  • 16
  • read your code like the JS interpreter would read it: `let next_col_time_step = (head_steps.reduce(choose_next_step, [-1, -1, null])[next_step] = next_col_time_step);` – Thomas Jul 12 '19 at 12:02
  • @CertainPerformance I accept that the question about Javascript semicolon insertion is answered elsewhere, hence is a relevant reference, but my problem was about how to diagnose a strange error when ASI worked differently than I was expecting. – Graham Klyne Jul 12 '19 at 12:10
  • See also: https://meta.stackexchange.com/questions/74080/close-as-duplicate-what-if-only-the-answer-is-a-duplicate – Graham Klyne Jul 12 '19 at 13:07

1 Answers1

1

The problem here is a confusing ambiguity in Javascript syntax.

Notice that I wasn't using ; statement terminators?

It appears that the array destructuring assignment is being parsed as an array indexing operation applied to the previous statement.

Quick fix: add ; after the preceding statement (though this unfortunately forces an inconsistent style if these are generally omitted):

let next_col_time_step = head_steps.reduce(
    choose_next_step, [-1, -1, null]
    );
[next_step_col, next_step_time, next_step] = next_col_time_step

And, voila!, all is well :)

Graham Klyne
  • 816
  • 10
  • 16
  • 1
    One of the many reasons why it's good style to always use semicolons . – baao Jul 12 '19 at 12:02
  • @chris p bacon: Yeah, I guess. I used to use semicolons until quite recently, but started switching because it seemed a common style not to do so in some recent ES6 code I was working with. – Graham Klyne Jul 12 '19 at 12:18