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




  

相关话题

  为什么form表单提交没有跨域问题,但ajax提交有跨域问题? 
  你见过哪些奇趣的代码注释? 
  如何去判断 JS 字符串中含某个字符串? 
  以前的 DHTML 如今是不是也算前端? 
  从事前端真的没有后端工资高? 
  请问各位程序员,是我的思维方式有错误吗? 
  为什么 Vue 的更新记录没有中文,中文文档也一直滞后? 
  前端因为像素还原设计稿而离职,这是个别现象吗? 
  接私活结果最后钱要不回来该怎么办? 
  网上都说操作真实 DOM 慢,但测试结果却比 React 更快,为什么? 

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





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