为什么这个未分配的 let 变量不会导致引用错误?
Why does this un-assigned let variable not cause a Reference Error?
为什么在此代码段中尝试访问 bar
不会导致引用错误?我读过试图解释 let
和 var
之间差异的问题/答案,但 none 似乎解释了顶部和底部示例的行为差异。
var foo;
let bar;
if( foo ) ()=>{}; // I expected this to be fine
if( bar ) ()=>{}; // I expected this to throw a reference error
console.log('finished');
(请随意回答这个问题,我的人生故事以及我在下面问的原因)
我一直在努力改掉过度使用 var
的坏习惯。在编写一些新代码时,我遇到了一个以前从未见过的问题:使用 if( myValue ) { ... }
会引发未定义 myValue 的引用错误。 "Well, duh, I'm trying to see if it is defined!"
我会声明 myValue
,并且在函数的整个过程中,我 可以 给它赋值。在函数的末尾,我检查它是否有值,如果有,将执行一些额外的操作。
我记得在阅读 let
与 var
时,var
基本上就像您在范围顶部为您的值创建了容器一样,而让,我认为它会在您声明它时这样做,但似乎在您分配它时会这样做。所以,我可以使用 var myValue;
、let myValue = undefined
或 if( typeof myValue !== 'undefined' ) { .. }
。我知道最后一个是确保此类事情不再发生的最佳选择,即使它很丑陋。
之后,我写了上面的小片段来向同事解释这个错误......它奏效了?!?我试图找出我可能错过的到底发生了什么,因为我想确切地了解出了什么问题并从中吸取教训。但我现在真的很抓耳挠腮,如果我不是更早的话,因为我认为我不仅找到了问题,而且修复了它......只是发现它可能只是与切线相关的其他东西。
附带说明:我的代码确实用一个 let
声明了多个变量,在它们之间使用逗号。这可能是一个因素吗?我确实多次重读了这些声明,它们的格式都正确:
let value1 = 3,
value2,
value3 = 982,
// ...
myValue; // Add ` = undefined` to stop the Reference Error
// ...
if( myValue ) { /* ... */ } // Reference Error thrown here
let 绑定在包含声明的(块)范围的顶部创建,通常称为 "hoisting"。与以 undefined 值开始的 var 声明的变量不同,let 变量在其定义被评估之前不会被初始化。在初始化之前访问变量会导致 ReferenceError。从块的开始到处理初始化,变量都在 "temporal dead zone" 中。
更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
未分配并不意味着未初始化。 let bar;
语句与 let bar = undefined;
的作用相同 - 它以 undefined
作为默认值初始化,除非您在变量声明中提供显式初始化程序 ("right hand side")。
用 let
声明的变量在初始化之前访问它们时会抛出引用错误,当它们的声明语句被评估时:
let bar; // = undefined;
if (bar) {} // this is fine
console.log('finished');
if (bar) {} // this throws a reference error
let bar; // = undefined;
console.log('finished');
有关时间死区的详细信息,请参阅。
为什么在此代码段中尝试访问 bar
不会导致引用错误?我读过试图解释 let
和 var
之间差异的问题/答案,但 none 似乎解释了顶部和底部示例的行为差异。
var foo;
let bar;
if( foo ) ()=>{}; // I expected this to be fine
if( bar ) ()=>{}; // I expected this to throw a reference error
console.log('finished');
(请随意回答这个问题,我的人生故事以及我在下面问的原因)
我一直在努力改掉过度使用 var
的坏习惯。在编写一些新代码时,我遇到了一个以前从未见过的问题:使用 if( myValue ) { ... }
会引发未定义 myValue 的引用错误。 "Well, duh, I'm trying to see if it is defined!"
我会声明 myValue
,并且在函数的整个过程中,我 可以 给它赋值。在函数的末尾,我检查它是否有值,如果有,将执行一些额外的操作。
我记得在阅读 let
与 var
时,var
基本上就像您在范围顶部为您的值创建了容器一样,而让,我认为它会在您声明它时这样做,但似乎在您分配它时会这样做。所以,我可以使用 var myValue;
、let myValue = undefined
或 if( typeof myValue !== 'undefined' ) { .. }
。我知道最后一个是确保此类事情不再发生的最佳选择,即使它很丑陋。
之后,我写了上面的小片段来向同事解释这个错误......它奏效了?!?我试图找出我可能错过的到底发生了什么,因为我想确切地了解出了什么问题并从中吸取教训。但我现在真的很抓耳挠腮,如果我不是更早的话,因为我认为我不仅找到了问题,而且修复了它......只是发现它可能只是与切线相关的其他东西。
附带说明:我的代码确实用一个 let
声明了多个变量,在它们之间使用逗号。这可能是一个因素吗?我确实多次重读了这些声明,它们的格式都正确:
let value1 = 3,
value2,
value3 = 982,
// ...
myValue; // Add ` = undefined` to stop the Reference Error
// ...
if( myValue ) { /* ... */ } // Reference Error thrown here
let 绑定在包含声明的(块)范围的顶部创建,通常称为 "hoisting"。与以 undefined 值开始的 var 声明的变量不同,let 变量在其定义被评估之前不会被初始化。在初始化之前访问变量会导致 ReferenceError。从块的开始到处理初始化,变量都在 "temporal dead zone" 中。
更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
未分配并不意味着未初始化。 let bar;
语句与 let bar = undefined;
的作用相同 - 它以 undefined
作为默认值初始化,除非您在变量声明中提供显式初始化程序 ("right hand side")。
用 let
声明的变量在初始化之前访问它们时会抛出引用错误,当它们的声明语句被评估时:
let bar; // = undefined;
if (bar) {} // this is fine
console.log('finished');
if (bar) {} // this throws a reference error
let bar; // = undefined;
console.log('finished');
有关时间死区的详细信息,请参阅