阅读(347) (0)

定义绑定初始化

2017-06-16 15:16:47 更新

每个执行环境都有一个关联的变量环境。当在一个执行环境下评估一段 ECMA 脚本时,变量和函数定义会以绑定的形式添加到这个变量环境的 环境记录 中。对于函数 函数代码,参数也同样会以绑定的形式添加到这个变量环境的 环境记录 中。

 选择使用哪一个、哪一类型的 环境记录 来绑定定义,是由执行环境下执行的 ECMA 脚本的类型决定的,而其它部分的逻辑是相同的。当进入一个执行环境时,会按以下步骤在变量环境上创建绑定,其中使用到调用者提供的代码设为 code,如果执行的是 函数代码 ,则设 参数列表 为 args:

  1. 令 env 为当前运行的执行环境的环境变量的 环境记录 。
  2. 如果 code 是 eval 代码 ,则令 configurableBindings 为 true,否则令 configurableBindings 为 false。
  3. 如果代码是 严格模式下的代码 ,则令 strict 为 true,否则令 strict 为 false。
  4. 如果代码为 函数代码 ,则:令 func 为通过 [[Call]] 内部属性初始化 code 的执行的函数对象。令 names 为 func 的 [[FormalParameters]] 内部属性。令 argCount 为 args 中元素的数量。令 n 为数字类型,其值为 0。按列表顺序遍历 names,对于每一个字符串 argName:令 n 的值为 n 当前值加 1。如果 n 大于 argCount,则令 v 为 undefined,否则令 v 为 args 中的第 n 个元素。以 argName 为参数,调用 env 的 HasBinding 具体方法,并令 argAlreadyDeclared 为调用的结果。如果 argAlreadyDeclared 的值为 false,以 argName 为参数调用 env 的 CreateMutableBinding 具体方法。以 argName、v 和 strict 为参数,调用 env 的 SetMutableBinding 具体方法。
  5. 按源码顺序遍历 code,对于每一个 FunctionDeclaration 表达式 f:令 fn 为 FunctionDeclaration 表达式 f 中的 标识符 。按 第 13 章 中所述的步骤初始化 FunctionDeclaration 表达式 ,并令 fo 为初始化的结果。以 fn 为参数,调用 env 的 HasBinding 具体方法,并令 argAlreadyDeclared 为调用的结果。如果 argAlreadyDeclared 的值为 false,以 fn 和 configurableBindings 为参数调用 env 的 CreateMutableBinding 具体方法。否则如果 env 是全局环境的 环境记录 对象,则:令 go 为全局对象。以 fn 为参数,调用 go 和 [[GetProperty]] 内部方法,并令 existingProp 为调用的结果。如果 existingProp.[[Configurable]] 的值为 true,则:以 fn、由 {[[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: configurableBindings } 组成的 属性描述符 和 true 为参数,调用go 的 [[DefineOwnProperty]] 内部方法。否则如果 IsAccessorDescrptor(existingProp) 的结果为真,或 existingProp 的特性中没有 {[[Writable]]: true, [[Enumerable]]: true},则:抛出一个 TypeError 异常。以 fn、fo 和 strict 为参数,调用 env 的 SetMutableBinding 具体方法。
  6. 以 arguments 为参数,调用 env 的 HasBinding 具体方法,并令 argumentsAlreadyDeclared 为调用的结果。
  7. 如果 code 是 函数代码 ,并且 argumentsAlreadyDeclared 为 false,则:以 fn、names、args、env 和 strict 为参数,调用 CreateArgumentsObject 抽象运算函数,并令 argsObj 为调用的结果。如果 strict 为 true,则:以字符串 "arguments" 为参数,调用 env 的 CreateImmutableBinding 具体方法。以字符串 "arguments" 和 argsObj 为参数,调用 env 的 InitializeImmutableBinding 具体函数。否则:以字符串 "arguments" 为参数,调用 env 的 CreateMutableBinding 具体方法。以字符串 "arguments"、argsObj 和 false 为参数,调用 env 的 SetMutableBinding 具体函数。
  8. 按源码顺序遍历 code,对于每一个 VariableDeclaration 和 VariableDeclarationNoIn 表达式:令 dn 为 d 中的标识符。以 dn 为参数,调用 env 的 HasBinding 具体方法,并令 varAlreadyDeclared 为调用的结果。如果 varAlreadyDeclared 为 false,则:以 dn 和 configurableBindings 为参数,调用 env 的 CreateMutableBinding 具体方法。以 dn、undefined 和 strict 为参数,调用 env 的 SetMutableBinding 具体方法。