【发布时间】:2017-09-11 17:37:48
【问题描述】:
阅读 Kyle Simpson 的 You Don't Know JS: Scopes & Closures,他认为你应该远离 eval() 函数和 with 关键字,因为每当编译器看到这两个(我在解释) ,它不执行一些与词法范围相关的优化并存储标识符的位置,因为这些关键字可能会修改词法范围,因此使编译器的优化有点不正确(我假设优化类似于编译器存储每个标识符的位置,因此它可以在运行时请求时提供标识符的值而无需搜索它)。
现在我明白了为什么在您使用 eval() 关键字时会发生这种情况:您的 eval 可能正在评估用户输入,而该用户输入可能是一个新变量的声明,它会影响您稍后访问的另一个变量假设正在执行的函数,如果编译器存储了静态位置,则访问将返回错误标识符的值(因为访问应该返回由 eval() 声明的标识符的值,但它返回编译器为优化查找而存储的变量的值)。所以我只是假设这就是编译器在你的代码中发现eval() 时不执行其范围相关查找的原因。
但是为什么编译器对 with 关键字做同样的事情呢?这本书说这样做是因为with 在运行时创建了一个新的词法范围,并且它使用作为参数传递给with 的对象的属性来声明一些新的标识符。我真的不知道这意味着什么,我很难想象这一切,因为本书中所有与编译器相关的东西都是理论。
我知道我可能走错了路,在这种情况下,请纠正我所有的误解:)
【问题讨论】:
-
@Bergi 我不是在问它为什么有害,而是在问“如果代码中存在
with,为什么编译器不执行与范围相关的优化”。这篇文章回答了哪些问题? -
在 2017 年不使用
with的原因不是为了优化,而是因为我们正在编写严格模式代码或 ES6,它甚至不合法。 -
@torazaburo 很好,作者认为尽管对
with提出了所有负面观点,但他们都忽略了最重要的一点:with会损害性能。我只是在问为什么。
标签: javascript v8 spidermonkey lexical-scope