为何let关键字与eval()配合使用时失效?结合代码实例咨询
为什么let关键字无法和eval()这样配合使用?
这问题抓得很准!本质是var和let/const在eval()执行时的作用域规则完全不同,咱们一点点拆解:
先看var能正常运行的原因
当你在eval()里用var b = 3;时,var遵循的是函数级作用域规则——哪怕它写在eval内部,只要eval是在foo函数里执行的,这个var声明的变量会被“提升”到包含eval的函数作用域中。
换句话说,eval("var b = 3;")执行后,b就相当于直接在foo函数里声明的变量,所以后面的console.log(a, b)能顺利拿到b=3,完全没问题。
再看let失效的核心原因
而let是块级作用域的声明关键字,更关键的是:在非严格模式下,eval()里用let声明的变量,会被严格限制在eval()自身的私有块级作用域里,根本不会泄露到外部的foo函数作用域中。
当eval("let b = 3;")执行完毕,这个b的作用域就直接结束了,foo函数的作用域里压根不存在b这个变量,所以后面的console.log去访问b时,自然会抛出ReferenceError: b is not defined的错误。
额外补充:严格模式下的小差异
如果给foo函数加上严格模式(开头加'use strict';),哪怕是var在eval里声明,也不会泄露到外部函数作用域里——这时候var和let的行为就一致了,都是eval内部私有作用域的变量。不过你的例子是非严格模式,所以重点还是前面的作用域差异。
内容的提问来源于stack exchange,提问作者Kenny Omega
相关产品推荐
相关产品推荐

