Let realmF be the value of F’s [[Realm]] internal slot.
Let **scope** be realmF.[[GlobalEnv]].
Perform **FunctionInitialize**(F, Normal, parameters, body, **scope**).
它们是什么意思呢?
规范约定需要从函数对象所在的“域(即引擎的一个实例)”中取出全局环境,然后将它作为“父级的作用域(scope)”,传入`FunctionInitialize()`来初始化函数`F`。也就是说,所有的“动态函数”的父级作用域将指向全局!
你绝不可能在“当前上下文(环境/作用域)”中动态创建动态函数。和间接调用模式下的`eval()`一样,所有动态函数都将创建在全局!
一说到跟“间接调用eval()”存有的相似之处,可能你立即会反应过来:这种情况下,`eval()`不仅仅是在全局执行,而且将突破“全局的严格模式”,代码将执行在非严格模式中!那么,是不是说,“动态函数”既然与它有相似之处,是不是也有类似性质呢?
>
NOTE:关于间接调用`eval()`,请参见《[第21讲](https://time.geekbang.org/column/article/184589)》。
答案是:的确!
出于与“间接调用eval()”相同的原因——即,在动态执行过程中无法有效地(通过上下文和对应的环境)检测全局的严格模式状态,所以动态函数在创建时只检测代码文本中的第一行代码是否为`use strict`指示字,而忽略它“外部scope”是否处于严格模式中。
因此,即使你在严格模式的全局环境中创建动态函数,它也是执行在非严格模式中的。它与“间接调用eval()”的唯一差异,仅在于“多封装了一层函数”。
例如:
```
# 让NodeJS在启动严格模式的全局
> node --use-strict
# (在上例启动的NodeJS环境中测试)
> x = "Hi"
ReferenceError: x is not defined
# 执行在全局,没有异常
> new Function('x = "Hi"')()
undefined
# `x`被创建
> x
'Hi'
# 使用间接调用的`eval`来创建`y`
> (0, eval)('y = "Hello"')
> y
'Hello'
```
## 结尾
所以,回到今天这一讲的标题上来。标题中的代码,事实与上一讲中提到的“间接调用eval()”的效果一致,同样也会因为在全局中“向未声明变量赋值”而导致创建一个新的变量名`x`。并且,这一效果同样不受所谓的“严格模式”的影响。
在JavaScript的执行系统中出现这两个语法效果的根本原因,在于执行系统试图从语法环境中独立出来。如果考虑具体环境的差异性,那么执行引擎的性能将会较差,且不易优化;如果不考虑这种差异性,那么“严格模式”这样的性质就不能作为(执行引擎理解的)环境属性。
在这个两难中,ECMAScript帮助我们做出了选择:牺牲一致性,换取性能。
>
NOTE:关于间接调用`eval()`对环境的使用,以及环境相关的执行引擎组件的设计与限制,请参见《[第20讲](https://time.geekbang.org/column/article/183440)》。
当然这也带来了另外一些好处。例如终于有了`window.execScript()`的替代实现,以及通过`new Function`这样来得到的、动态创建的函数,就可以“安全地”应用于并发环境。
至于现在,《JavaScript核心原理解析》一共22讲内容就全部结束了。
在这个专栏中,我为你讲述了JavaScript的静态语言设计、面向对象语言的基本特性,以及动态语言中的类型与执行系统。这看起来是一些零碎的、基本的,以及应用性不强的JavaScript特性,但是事实上,它们是你理解“更加深入的核心原理”的基础。
如果不先掌握这些内容,那么更深入的,例如多线程、并行语言特性等等都是空中楼阁,就算你勉强学来,也不过是花架子,是理解不到真正的“核心”的。
而这也是我像现在这样设计《JavaScript核心原理解析》22讲框架的原因。我希望你能在这些方面打个基础,先理解一下ECMAScript作为“语言设计者”这个角色的职责和关注点,先尝试一下深入探索JavaScript核心原理的乐趣(与艰难)。然后,希望我们还有机会在新的课程中再见!
[](https://jinshuju.net/f/TmdBMP)
多谢你的收听,最后邀请你填写这个专栏的[调查问卷](https://jinshuju.net/f/TmdBMP),我也想听听你的意见和建议,我将继续答疑解惑、查漏补缺,与你回顾这一路行来的苦乐。
再见。
>
NOTE:编辑同学说还有一个“结束语”,我真不知道怎么写。不过,如果你觉得意犹未尽的话,到时候请打开听听吧(或许还有好货叱)。
by aimingoo.