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




  

相关话题

  不太理解预防csrf攻击中的“双提交cookie”是什么意思? 
  公司拖欠后端工资逼急了可以删库跑路,逼急了前端该如何何去何从? 
  Stack Overflow 2016 年度报告中有哪些有趣的事实? 
  中国大学里有和前端设计相关的专业吗? 
  前端技术岗,阿里 P7、百度 T6、腾讯 T3.1 的要求是怎样的? 
  Javascript 初学者如何思考才可以把脑中的东西转换成代码写出来? 
  现在整个 Web 前端是「屎山」吗? 
  初期学习前端有合适的电脑推荐么? 
  如何看待 TS 团队发起的 「JS 类型标注」提案 Types as Comments? 
  独立开发先写前端还是先写后端? 

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





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