Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable cannot be declared or modified

I have a question about JavaScript. When I declarate new variable and assign to it new instance of class, if error is thrown variable is getting completely unusable.

Code below should throw an error

class MyClass {


    constructor (config) {

        this.someProperty = config.someProperty || '';

    }


}

let myClassInstance = new MyClass();

If I try to assign something to it, JavaScript will throw an error.

myClassInstance = '123'

Uncaught ReferenceError: myClassInstance is not defined

Then I tried to define variable

let myClassInstance = '123'

Uncaught SyntaxError: Identifier 'myClassInstance' has already been declared

Variable also cannot be deleted. Is there anything that we can do with that issue? I'm just curious, of course I will handle passing undefined as config to constructor.

EDIT: I also tried using var, I can then reuse myClassInstance. I wonder why if I use let that variable cannot be deleted, declarated or new value cannot be reassigned.

EDIT 2: I can handle passing undefined or pass empty object. Just pure curiosity what happens in JS console with that variable, also code will not execute if you paste everything at once

like image 442
Alan Mroczek Avatar asked Mar 15 '17 12:03

Alan Mroczek


1 Answers

Running code in the interactive console creates a contrived situation that couldn't happen in typical code execution.

Firstly, what you're seeing isn't specific to errors thrown in class constructors. You can observe the same behavior if you execute any let statement where the RHS throws an error:

let myVariable = "".boom();

The documentation on MDN talks about a "temporal deadzone" where a variable declared with let exists, but is treated as not existing until the let statement has successfully executed.

From the ES6 spec:

The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated.

In simple terms, the variable has been created, but cannot be accessed because its "LexicalBinding" has not been evaluated.

Using the console, you have created a situation where:

  • The let statement has not successfully executed (so it is a ReferenceError to try to access its variable).
  • You have two lets for the same variable name within the same scope (so the second one creates a syntax error). (n.b. Simply having two lets in the same scope would cause the code to fail at the compilation stage, before the first one even had a chance to try to execute if you weren't entering the code a little bit at a time into the console).

This is a situation that could not occur in ordinary code.

Ordinarily, you would not be able to continue running statements in the scope where an error has been thrown, so the first bullet would be impossible. The console allows you to do that.

It would be further impossible under ordinary circumstances because the code would fail at the compilation stage, before the first let statement could even try to run.

So that's why you're getting an error in both cases.

like image 100
JLRishe Avatar answered Sep 19 '22 13:09

JLRishe