Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 引用错误:can';t访问词汇声明'X';初始化前_Javascript_Variables_Let_Hoisting - Fatal编程技术网

Javascript 引用错误:can';t访问词汇声明'X';初始化前

Javascript 引用错误:can';t访问词汇声明'X';初始化前,javascript,variables,let,hoisting,Javascript,Variables,Let,Hoisting,有人能给我解释一下在尝试访问let声明之前的变量时,chrome和firefox中出现的奇怪错误消息:“let X”。如果我们写下如下内容: console.log(X); 设X; /* 在firefox中,它会报告如下错误: ReferenceError:在初始化之前无法访问词法声明“X” 在chrome中,它会报告以下错误: 未捕获引用错误:在初始化之前无法访问“X” */是的,它们“提升”,但作为不可接近的东西,在读写时总是抛出错误。它被称为“暂时死区” 进一步阅读: 例如,从概念上讲,

有人能给我解释一下在尝试访问let声明之前的
变量时,
chrome和firefox
中出现的奇怪错误消息:“let X”
。如果我们写下如下内容:

console.log(X);
设X;
/*
在firefox中,它会报告如下错误:
ReferenceError:在初始化之前无法访问词法声明“X”
在chrome中,它会报告以下错误:
未捕获引用错误:在初始化之前无法访问“X”
*/
是的,它们“提升”,但作为不可接近的东西,在读写时总是抛出错误。它被称为“暂时死区”

进一步阅读:

例如,从概念上讲,提升的严格定义表明变量和函数声明在物理上被移动到代码的顶部,但事实上并非如此。相反,变量和函数声明在编译阶段被放入内存中,但保持在代码中键入它们的位置。[冲洗]

[……]

对于大多数ES6特性(let、const、默认参数等),创建阶段的工作方式截然不同。它仍然会遍历代码并为变量分配空间,但初始值设定项使用一种称为TDZ(暂时死区)的特殊模式设置变量,这意味着变量存在,但只有在指定某个值后才能访问它们

你可以这样想象:

设X=TDZ;
console.log(X);//错误
X=未定义;//在你的代码中:让X;
…与正常托管行为相比:

var X=未定义;
console.log(X);//未定义
X=随便什么;//在您的代码中:var X=任意值;
当然,这不是100%正确,因为您也不能在
let
之前写入
X=123
,并且没有有效的JS来描述“不可写入变量”。但我想你明白了


在第13.3.1节中对此进行了如下描述(这里似乎没有使用“TDZ”一词,尽管我以前多次听说过这个名称,但在中也有使用):

13.3.1 Let和Const声明

让和const声明定义作用于正在运行的执行上下文的词典环境的变量。变量是在实例化其包含的环境记录时创建的,但在对变量的字典绑定求值之前,不能以任何方式访问变量。由带有初始值设定项的LexicalBinding定义的变量在计算LexicalBinding时,而不是在创建变量时,被分配其初始值设定项的AssignmentExpression的值。如果let声明中的LexicalBinding没有初始值设定项,则在计算LexicalBinding时,将为变量分配未定义的值


这意味着在块的开始,环境记录被实例化-变量“存在”,但在TDZ中。正如这里所说,它无法访问,因此出现了错误。执行
let
行后,将计算它的LexicalBinding,变量将从TDZ中出来,现在可以访问。既然您没有指定初始值设定项,它的值现在是未定义的

,为什么它不能提升?它是一个变量,就像一个变量。它只是有一个缩小的范围,所以为什么人们称它为
let variables
never
high
,它们的意思是在定义之前不能使用它们。正如您所看到的:尝试这样做会抛出一个错误。然而,一个恼人的副作用当然是,虽然它们以未分配的形式存在,但它们仍然可以从外部作用域对变量进行阴影处理。因此,在函数的最后一行添加
let location
,仍然可以破坏整个函数以前的代码,但至少它会以一种更有意义的方式实现。如果将
var-location
放在函数的最后一行,而第一行就完成了
location=http://yahoo.com“
,那么它就会悄悄地破坏代码,但是通过
让它以一种明显的方式来实现。我意识到实际上已经有了一个更好的答案:这在ECMAscript规范中提到了吗?顺便问一下,谢谢你保存了它并添加到我的答案中。非常感谢