百科问答小站 logo
百科问答小站 font logo



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

  

user avatar   he-shi-jun 网友的相关建议: 
      

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声明变量出错时,变量依然被声明且无法再赋值是什么原理? 并且下面的答案也都比较准确的回答了,所以大家还是要善用搜索。




  

相关话题

  网上常能见到的一段 JS 随机数生成算法如下,为什么用 9301, 49297, 233280 这三个数字做基数? 
  JS和Scheme对闭包变量的绑定能力差异,哪种更合理? 
  前后端分离项目,接口返回 200 但是里面返回 500 合理吗? 
  以下 CSS 栅格布局除了用 table 以外,有什么其他的方法吗? 
  请问各位程序员,是我的思维方式有错误吗? 
  如果说 Rust/WASM 会逐渐蚕食 JavaScript 生态,那将以怎样的路径进行? 
  如何评价 Typescript 的运行时类型检测工具io-ts? 
  2018年一个合格的前端应该是什么样的? 
  为什么程序都要用英文写,中文不行吗? 
  计算机专业的学生如何系统的学习前端技术? 

前一个讨论
「电荷量」的定义是否有逻辑问题?
下一个讨论
有没有基于Microsoft Word/Excel内容的版本管理工具?就像SVN、Git这样。





© 2024-11-12 - tinynew.org. All Rights Reserved.
© 2024-11-12 - tinynew.org. 保留所有权利