Skip to main content

18 动态执行

eval 执行什么

在代码eval(x)中,x必须是一个字符串,不能是其他任何类型的值,也不能是一个字符串对象。如果尝试在 x 中传入其他的值,那么 eval() 将直接以该值为返回值。

eval 在哪儿执行

eval 总是将代码执行在当前上下文的“当前位置”。这里的所谓的“当前上下文”并不是它字面意思中的“代码文本上下文”,而是指“(与执行环境相关的)执行上下文”。

环境

JavaScript 中,环境可以细分为四种,并由两个类别的基础环境组件构成。

四种环境是:

  • 全局(Global)
  • 函数(Function)
  • 模块(Module)
  • Eval 环境;

两个基础组件的类别分别是:

  • 声明环境(Declarative Environment)
  • 对象环境(Object Environment)

上述四种环境,本质上只是为 JavaScript 中的每一个“可以执行的语法块”创建了一个名字表的影射。

执行上下文

JavaScript 的执行系统由一个执行栈和一个执行队列构成。

在执行队列中保存的是待执行的任务,称为 Job。在创建这个执行任务时的一些关联信息,正式执行时可以参考它;正式的执行发生在将一个新的上下文被 push 执行栈的时候。

每一个执行上下文都需要关联到一个对照表。这个对照表就称为“词法环境(Lexical Environment)”。

管理

全局上下文(例如 Global Context)中词法环境和变量环境其实都指向同一个 global。全局的特性就是“var 变量”和“词法变量”共用一个名字表,因此你声明了“var 变量”,那么就不能声明“同名的 let/const 变量”。

不用于执行的环境

环境在本质上是“作用域的映射”。作用域如果不需要被上下文管理,那么它(所对应的环境)也就不需要关联到上下文。

eval() 的环境

Eval 环境”是唯一一个将“变量环境”指向了与它自有的“词法环境”不同位置的环境。

在全局环境中的 eval

除了初始化,eval()无法在全局执行。