问题

如何理解 let x = x 报错之后,再次 let x 依然会报错?

回答
咱们来聊聊 JavaScript 里 `let` 声明的那点事儿。你遇到的情况,其实是 `let` 声明在作用域内存在“暂时性死区”(Temporal Dead Zone, TDZ)的典型表现。

想象一下,当你第一次写 `let x = x` 的时候,JavaScript 引擎在执行这行代码之前,就已经知道了在当前这个作用域里,有一个叫做 `x` 的变量即将被声明。但是,关键在于,它虽然知道“有这么个东西要出来”,但此刻它还处于一个“未初始化”的状态。

好比你要进一个房间,你知道里面会有一张桌子,但是你还没把桌子搬进去,它还在门外。你现在就想跟这张桌子说“桌子,请递给我你旁边的那个东西”,但这张桌子压根还没进门,更别说它手里有没有拿什么东西了。所以,当你尝试去访问 `x`(也就是等号右边的那个 `x`)的时候,虽然你心里知道 `x` 是要声明的,但它还没走到“可以使用”的那一步。

JavaScript 引擎就觉得:“喂,你在这儿要用 `x`,可 `x` 还没准备好呢!”于是它就给你抛出了一个错误,告诉你“Cannot access 'x' before initialization”。这就像你试图去够一个还没到你面前的东西。

现在,更有趣的地方来了。你遇到了错误,可能觉得:“好吧,那我不碰它了,我重新声明一次 `let x` 看看。” 结果,你又报错了!

这是为什么呢?因为 `let` 声明的这个“知道但未初始化”的状态,在它被声明的那个作用域里,是持续存在的,直到它被真正地赋值。你第一次 `let x = x` 尝试访问的是一个未初始化的 `x`,触发了 TDZ 错误。

当你第二次 `let x` 的时候,JavaScript 引擎又回来了。它看到在当前作用域里,你已经声明过(虽然是失败地尝试初始化)一个 `x` 了。它不会认为这是一个全新的、可以重新声明的变量。对于 `let` 来说,同一个作用域内,同一个变量名是不能被重复声明的。

这就像你打开了那扇门,看到桌子还没进来,然后关上了门,说“不对,这不行。” 接着你又推开了那扇门,但里面的情况并没有改变——桌子还是没进来。你不能因为你又“推了推门”就认为这扇门里的东西是可以随便拿来用的了。

你第二次 `let x` 仍然是在 TDZ 内部进行的。你并没有完成第一次 `let x = x` 想要做的“初始化”这个动作。你只是再次尝试在这个“桌子还没进来”的状态下,又一次声明了“要进来一张桌子”。但是,因为 `x` 已经被“标记”为在这个作用域内被声明了,并且还在 TDZ 之中,所以第二次声明 `let x` 依然会被引擎视为对一个尚未被初始化的变量的重复声明,这同样是不被允许的。

简单来说,第一次 `let x = x` 让你直接栽在了 TDZ 里,因为它还没初始化你就想用它。而第二次 `let x` 则是试图在同一个作用域内,对一个已经被宣告过(尽管是失败的)但仍处于 TDZ 状态的变量进行重复声明,而 `let` 的规则是禁止重复声明的。所以,无论如何,只要 `x` 还没有被成功地初始化(也就是被赋予一个值),你在同一个作用域内再次 `let x`,或者在它被初始化之前尝试访问它,都会导致错误。

网友意见

user avatar

let x = x 扔出的错误乃右边的表达式求值时产生运行时错误,但是 let x 本身是有效的。

实际上如果不是在console里一句一句执行,还没等扔运行时错误(ReferenceError)第二个let x语句就首先产生了早期错误(SyntaxError)。


【补充】

@萧井陌 的答案提到 console 特殊环境,确实,这里与 console 的 repl 实现有一定的关系,下面 @余博伦 答案也指出 edge 的 console 下结果就不同。不过 edge 的问题其实是在 repl 下每次执行代码中的 let 定义只对当次的代码有效,即其每次执行实际上是在一个单独 scope 里。这是 edge devtools 的一个缺陷。

但是注意,这个例子并不是“不存在的粪坑”。

通常,let 所在的 block 一旦发生错误,你是没办法重新继续执行该 block 内 let 语句之后的语句的。你也许想用 try catch,但 try 自己就形成了一个 block,所以此路不通。

但是有一个例外,那就是浏览器里的 global script 代码,其 let 定义是跨 script 块有效的。(node.js 因为每个模块本质上是包装过的函数,所以是无法实现的。)并且一个 script 块报错后面的 script 块会继续执行。

代码如下:

       <!doctype html> <script> function throws() { throw '!' } let x = throws() </script> <script> console.log(typeof x) </script> <script> let x </script>     

这里我用 let x = throws() 代替了 let x = x,是因为这里只需要扔出运行异常,而不必是引用自身这种特例。

第一个script跑完之后,x 虽然已经存在了,但是处于未初始化的状态,即类似TDZ的情况。之后即使使用 typeof x 也会报错(通常未声明变量会返回 'undefined')。

chrome里报错如下:

test.html:3 Uncaught !
test.html:7 Uncaught ReferenceError: x is not defined
test.html:9 Uncaught SyntaxError: Identifier 'x' has already been declared

edge里报错如下:

!
Use before declaration
Let/Const redeclaration

(注意:edge貌似会并行parse不同的script块,因为第三条是early error,而第二条是运行时错误,所以有时候你会看到后两条报错的顺序是相反的。)

ff里报错如下:

uncaught exception: !
ReferenceError: can't access lexical declaration `x' before initialization test.html:7:13
SyntaxError: redeclaration of let x test.html:9:1

看起来,还是ff的错误信息一如既往的最清楚。

顺便,我发现其实这个问题之前已经有人提过了:js中用let声明变量出错时,变量依然被声明且无法再赋值是什么原理? 并且下面的答案也都比较准确的回答了,所以大家还是要善用搜索。

类似的话题

  • 回答
    咱们来聊聊 JavaScript 里 `let` 声明的那点事儿。你遇到的情况,其实是 `let` 声明在作用域内存在“暂时性死区”(Temporal Dead Zone, TDZ)的典型表现。想象一下,当你第一次写 `let x = x` 的时候,JavaScript 引擎在执行这行代码之前,就已.............
  • 回答
    这句话“文官的衣服上绣的是禽,武官的衣服上绣的是兽。披上了这身皮,我们哪一个不是衣冠禽兽”融合了历史、文化、隐喻和讽刺,需要从多个层面进行解析: 一、历史背景与服饰象征1. 古代官服制度 在中国历史上,官服的纹饰(如禽鸟、兽类)是等级制度和身份象征的重要标志。 文官:常以“禽”为纹.............
  • 回答
    “自称迪士尼在逃公主”的现象在网络上出现后,引发了广泛讨论。这一说法通常指一些女性在社交媒体、论坛或网络社区中自称是“迪士尼公主”,并可能涉及身份扮演、文化认同、心理需求等多重层面。以下从多个角度详细分析这一现象的可能内涵和背景: 一、文化符号的再诠释:迪士尼公主的象征意义1. 迪士尼公主的原始形象.............
  • 回答
    自由主义和新自由主义是两种重要的思想体系,它们在政治哲学、经济学和社会政策等领域具有深远的影响。以下是对这两个概念的详细解析: 一、自由主义的定义与核心特征自由主义(Liberalism)是一种以个人自由、法治、民主和理性为价值基础的政治哲学思想体系,其核心在于保障个体权利和限制国家权力。自由主义的.............
  • 回答
    无政府主义(Anarchism)是一种深刻批判国家权力、追求个体自由与社会平等的政治哲学和实践运动。它并非主张“混乱”或“无序”,而是反对一切形式的强制性权威,尤其是国家对个人生活的控制。以下从多个维度深入解析这一复杂的思想体系: 一、核心定义与本质特征1. 对国家的彻底否定 无政府主义者认.............
  • 回答
    “爱国家不等于爱朝廷”这句话在理解中国古代政治和文化时非常重要。它揭示了国家与政权(即朝廷)之间的区别,以及臣民对这两者的情感和责任的不同层面。要理解这句话,我们需要先拆解其中的概念: 国家(Guó Jiā): 在古代,我们通常将其理解为国家的疆土、人民、文化、民族认同和长期的历史延续。它是根植.............
  • 回答
    理解中国人民银行工作论文中提到的“东南亚国家掉入中等收入陷阱的原因之一是‘文科生太多’”这一论断,需要从多个层面进行深入分析,因为这是一个相对复杂且具有争议性的议题。下面我将尽量详细地解释其背后的逻辑和可能含义:一、 背景:中等收入陷阱首先,我们需要理解什么是“中等收入陷阱”。 定义: 中等收入.............
  • 回答
    郭主席对房地产的表述“不希望房地产剧烈波动”可以从多个层面来理解,这背后反映了他对中国经济稳定和健康发展的深切关切。要详细理解这一点,我们需要从房地产在中国经济中的地位、波动可能带来的影响、以及“不剧烈波动”的具体含义等角度进行分析。一、 房地产在中国经济中的特殊地位:首先,理解为什么房地产会引起如.............
  • 回答
    如何理解科幻小说《时间的二分法》? 详细解读科幻小说《时间的二分法》(英文原名:The Time Machine),由英国著名作家赫伯特·乔治·威尔斯(H.G. Wells)于1895年创作,是科幻文学史上的经典之作。这部小说不仅为我们描绘了一个令人着迷的未来世界,更通过其深刻的社会寓言和哲学思考,.............
  • 回答
    尹建莉老师关于“延迟满足是鬼话,孩子要及时满足”的观点,确实在教育界引发了不少讨论。要理解她的观点,我们需要深入探讨她为什么会提出这样的论断,以及她所强调的“及时满足”的真正含义。首先,我们来拆解一下“延迟满足”这个概念及其传统理解。传统理解的“延迟满足”:延迟满足(Delayed Gratific.............
  • 回答
    理解外交部发言人陆慷的说法,即“《中英联合声明》作为一个历史文件,不再具有任何现实意义”,需要从几个关键角度来解读:1. 历史文件的定义与性质: 历史文件是过去的产物: 陆慷的表述首先强调了《中英联合声明》的“历史文件”属性。这意味着它是在特定历史时期、基于当时国际政治格局和两国关系背景下签署的.............
  • 回答
    杨振宁先生作为一位享誉世界的物理学家,他关于中美教育的评论引起了广泛关注和讨论。理解他的话需要从多个角度进行深入剖析,包括他所处的时代背景、他对教育本质的理解、以及他观察到的中美教育体系的差异。一、 杨振宁先生评论的时代背景与个人经历:首先,要理解杨振宁先生的话,必须考虑到他所处的时代背景和他的个人.............
  • 回答
    “中国是发达国家的粉碎机”这个说法,虽然带有一定的情绪化和夸张色彩,但其核心要表达的是:中国凭借其独特的经济模式、庞大的市场规模、强大的制造能力和不断进步的科技创新,对传统发达国家在经济和产业领域构成了前所未有的挑战,并在一定程度上“粉碎”了它们原有的竞争优势和发展路径。为了详细理解这一说法,我们可.............
  • 回答
    “爱国主义是流氓的最后一块遮羞布”这句话,最早出自塞缪尔·约翰逊(Samuel Johnson),一位杰出的18世纪英国作家和评论家。这句话的含义深刻且复杂,通常被用来讽刺和批评那些打着爱国旗号,但实际上在追求个人利益、制造分裂或煽动仇恨的人。要理解这句话,我们可以从以下几个层面来深入剖析:1. 字.............
  • 回答
    “Control is Dead”这句话的含义非常丰富且具有多层次的解读,它不是一个简单的字面陈述,而是对当前社会、技术、政治、经济等领域中一种普遍的失控感、权力分散化、个体自主性增强以及传统权威式微的深刻反映。要理解这句话,我们需要从不同的角度去剖析:一、 字面含义与引申含义: 字面含义: 最.............
  • 回答
    “小孩子才分对错,成年人只看利弊”这句话,乍一听可能有些功利甚至冷酷,但深入剖析,它揭示了一种关于成长、认知和处世态度的深刻变化。这句话并不是说成年人完全泯灭了道德感,而是强调在复杂的社会现实中,判断的侧重点会发生微妙而重要的转移。我们来详细地理解这句话的各个层面:一、 “小孩子才分对错”:儿童的认.............
  • 回答
    这句话以一种诗意且深刻的方式,阐述了科学与宗教(在此特指佛学)在追求真理和理解宇宙本质上可能存在的殊途同归。要理解它,我们可以从几个层面进行剖析:一、 表象的理解:科学探索的艰难与佛学智慧的超前 科学探索的“爬山”隐喻: 科学研究是一个漫长、艰辛、充满挑战的过程。科学家们如同登山者,需要克服无数.............
  • 回答
    “Don't judge”(别评判)这句简单的话语,却蕴含着深刻的道理,它不仅仅是一个简单的行为准则,更是一种生活态度和哲学。要理解它,需要从多个层面去深入剖析。核心含义:停止对他人进行预设的、带有偏见的、负面判断。“评判”(judge)这个词在中文里可以有几种理解: 审判(legal cont.............
  • 回答
    这句话, "对他们的伟大人物忘恩负义,这是伟大民族的标志",是一句富有争议且深刻的论断。要理解它,我们需要从多个层面进行剖析,包括字面含义、潜在的哲学思想、历史现实以及它可能带来的积极或消极影响。核心解读:反思与进步的动力从最核心的角度来看,这句话并非在鼓吹忘恩负义的行为本身是值得赞扬的,而是指向了.............
  • 回答
    「看山是山,看山不是山,看山还是山」,这句禅语,通常被称为“禅宗三境界”或者“悟道三阶段”,意境深远,历久弥新。它并非指代实际的山,而是用“山”这个意象来比喻一个人对事物、对真理、对自我的认知过程。理解这三层境界,能帮助我们更深刻地认识自己,认识世界。下面我将详细阐述这三层境界的含义:第一层境界:看.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有