Page 36 - 你不知道的JavaScript(上卷)
P. 36

但如果引擎在代码中发现了 eval(..) 或 with,它只能简单地假设关于标识符位置的判断
                 都是无效的,因为无法在词法分析阶段明确知道 eval(..) 会接收到什么代码,这些代码会
                 如何对作用域进行修改,也无法知道传递给 with 用来创建新词法作用域的对象的内容到底
                 是什么。

                 最悲观的情况是如果出现了 eval(..) 或 with,所有的优化可能都是无意义的,因此最简
                 单的做法就是完全不做任何优化。

                 如果代码中大量使用 eval(..) 或 with,那么运行起来一定会变得非常慢。无论引擎多聪
                 明,试图将这些悲观情况的副作用限制在最小范围内,也无法避免如果没有这些优化,代
                 码会运行得更慢这个事实。


                 2.3 小结


                 词法作用域意味着作用域是由书写代码时函数声明的位置来决定的。编译的词法分析阶段
                 基本能够知道全部标识符在哪里以及是如何声明的,从而能够预测在执行过程中如何对它
                 们进行查找。

                 JavaScript 中有两个机制可以“欺骗”词法作用域:eval(..) 和 with。前者可以对一段包
                 含一个或多个声明的“代码”字符串进行演算,并借此来修改已经存在的词法作用域(在
                 运行时)。后者本质上是通过将一个对象的引用当作作用域来处理,将对象的属性当作作
                 用域中的标识符来处理,从而创建了一个新的词法作用域(同样是在运行时)。

                 这两个机制的副作用是引擎无法在编译时对作用域查找进行优化,因为引擎只能谨慎地认
                 为这样的优化是无效的。使用这其中任何一个机制都将导致代码运行变慢。不要使用它们。



























                                                                            词法作用域   |   21
   31   32   33   34   35   36   37   38   39   40   41