【问题标题】:Is there any difference between declared and defined variableIs there any difference between declared and defined variable
【发布时间】:2020-02-28 09:36:58
【问题描述】:

I try writing the following lines in the console one by one

let x = y //throws error "Uncaught ReferenceError: y is not defined"
console.log(x) //throws error "ReferenceError: x is not defined"
let x = 3; //gives error "Uncaught SyntaxError: Identifier 'x' has already been declared"
x = 3 //ReferenceError: x is not defined

Now problem is that how can be a variablenot definedandhas been declaredat the same time. Is there any difference between both.

【问题讨论】:

  • It's a poor use of language by the browser consoles. Those ReferenceErrors should really say the variable is not "declared", but afaik it's always been thus.
  • From link:When there's assignment, the right-hand side is parsed first; if the right-hand side throws an error, it never gets to the left-hand side, and the variable declared with let never gets properly initialized; it'll stay in the demilitarized zone / temporal dead zone forever(and you can't re-declare a variable that's already been declared, even though the attempted assignment during initialization threw an error).
  • There's a big difference betweendeclarationandinitialization. In your first line x = y, you declared xand tried to assign y to it, which is undefined, so xis declared and will be initialized with undefined as value. That's why you got x is already declared.
  • @MaheerAli let x = 3; will throw error as you have already declared it. But x=3 should not throw error, unless you define it as const
  • Being declared doesn't mean it will be initialized to undefined. Are variables declared with let or const not hoisted in ES6?

标签: javascript variables


【解决方案1】:

A let or const variable can only bedeclaredonce - that is, when you have let <variableName> in a scope, you have declared <variableName> in that scope, and cannot declare it again in that scope.

From the previously linked question:

When there's assignment, the right-hand side is parsed first; if the right-hand side throws an error, it never gets to the left-hand side, and the variable declared with let never gets properly initialized; it'll stay in the demilitarized zone / temporal dead zone forever

You can't re-declare a variable that's already been declared, even though the attempted assignment during initialization threw an error.

But on line 4, x=3 should do a proper assignment and it should remove x from TDZ. But that also fails. I fail to understand that

After a variable has beeninitialized(for example, the let x runs), it can be assigned to. But just like you can't assign to a variablebeforeits let initialization, you also can't assign to a variable later, when its initialization did not complete successfully:

x = 'foo';
let x = 'bar';

Error:

Uncaught ReferenceError: x is not defined

Which is the same sort of thing that happens in the console when you try:

let x = y
// Uncaught ReferenceError: y is not defined
// x has not been initialized, so the next line throws:
x = 'foo'
// Uncaught ReferenceError: x is not defined

x still has not been initialized, so the error is the same.

Encountering this sort of thing ispretty odd, though - you only see it in the console. In normal scripts, a thrown error will prevent further execution, and the fact that a variable name remains uninitialized forever is not something to worry about.


The above was an issue in earlier Chrome versions. But in Chrome 80+, re-declarations of let are now permitted, so the error

Uncaught SyntaxError: Identifier 'x' has already been declared

should no longer occur, regardless of whether the previous initialization of the variable succeeded or not:

【讨论】:

  • I'd like to point out that in Firefox's console let x = y does initialize x and x = "foo" doesn't throw. However doing the same out of the console, it throws correctly.
猜你喜欢
  • 2022-11-20
  • 2022-12-15
  • 2022-12-01
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
  • 2022-12-27
相关资源
最近更新 更多