百科问答小站 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 不能绕过后端代码直接调数据库,有哪些后端处理的逻辑,JS 不能写? 
  老师要求我只能使用C++、C或者Java写算法,如何看这种做法? 
  大一新生如何自学JavaScript? 
  es,js,ts三者有什么关系? 
  怎样学习才能拥有所谓“高并发”的经验? 
  文本格式(txt、doc)的HTML,有什么办法快速读取出特定的标签及里面的内容? 
  有哪些新手程序员不知道的小技巧? 
  王垠的《谈谈Parser》是在回应 winter 吗? 
  作为前端开发者,不了解flash,可耻吗? 
  浏览器自身为什么不集成js,jQuery文件?反正每个网站基本都会用到? 

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





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