28 反射

28.1 Reflect 对象

Reflect 对象:

  • %Reflect%
  • 是全局对象 "Reflect" 属性的初始值。
  • 是一个普通对象
  • 具有其值为 %Object.prototype%[[Prototype]] 内部槽。
  • 不是函数对象
  • 没有 [[Construct]] 内部方法;无法通过 new 运算符作为构造函数使用。
  • 没有 [[Call]] 内部方法;无法作为函数调用。

28.1.1 Reflect.apply ( target, thisArgument, argumentsList )

该函数被调用时执行以下步骤:

  1. 如果 IsCallable(target) 是 false,抛出 TypeError 异常。
  2. args 为 ? CreateListFromArrayLike(argumentsList)。
  3. 执行 PrepareForTailCall()。
  4. 返回 ? Call(target, thisArgument, args)。

28.1.2 Reflect.construct ( target, argumentsList [ , newTarget ] )

该函数被调用时执行以下步骤:

  1. 如果 IsConstructor(target) 是 false,抛出 TypeError 异常。
  2. 如果 newTarget 不存在,则设 newTargettarget
  3. 否则如果 IsConstructor(newTarget) 是 false,抛出 TypeError 异常。
  4. args 为 ? CreateListFromArrayLike(argumentsList)。
  5. 返回 ? Construct(target, args, newTarget)。

28.1.3 Reflect.defineProperty ( target, propertyKey, attributes )

该函数被调用时执行以下步骤:

  1. 如果 target 不是对象,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. desc 为 ? ToPropertyDescriptor(attributes)。
  4. 返回 ? target.[[DefineOwnProperty]](key, desc)

28.1.4 Reflect.deleteProperty ( target, propertyKey )

该函数被调用时执行以下步骤:

  1. 如果 target 不是对象,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. 返回 ? target.[[Delete]](key)

28.1.5 Reflect.get ( target, propertyKey [ , receiver ] )

该函数被调用时执行以下步骤:

  1. 如果 target 不是对象,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. 如果 receiver 不存在,则
    1. receivertarget
  4. 返回 ? target.[[Get]](key, receiver)

28.1.6 Reflect.getOwnPropertyDescriptor ( target, propertyKey )

该函数被调用时执行以下步骤:

  1. 如果 target 不是对象,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. desc 为 ? target.[[GetOwnProperty]](key)
  4. 返回 FromPropertyDescriptor(desc)。

28.1.7 Reflect.getPrototypeOf ( target )

该函数被调用时执行以下步骤:

  1. 如果 target 不是对象,抛出 TypeError 异常。
  2. 返回 ? target.[[GetPrototypeOf]]()

28.1.8 Reflect.has ( target, propertyKey )

该函数被调用时执行以下步骤:

  1. 如果 target 不是对象,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. 返回 ? target.[[HasProperty]](key)

28.1.9 Reflect.isExtensible ( target )

该函数被调用时执行以下步骤:

  1. 如果 target 不是对象,抛出 TypeError 异常。
  2. 返回 ? target.[[IsExtensible]]()

28.1.10 Reflect.ownKeys ( target )

该函数被调用时执行以下步骤:

  1. 如果 target 不是对象,抛出 TypeError 异常。
  2. keys 为 ? target.[[OwnPropertyKeys]]()
  3. 返回 CreateArrayFromList(keys)。

28.1.11 Reflect.preventExtensions ( target )

该函数被调用时执行以下步骤:

  1. 如果 target 不是对象,抛出 TypeError 异常。
  2. 返回 ? target.[[PreventExtensions]]()

28.1.12 Reflect.set ( target, propertyKey, V [ , receiver ] )

该函数被调用时执行以下步骤:

  1. 如果 target 不是对象,抛出 TypeError 异常。
  2. key 为 ? ToPropertyKey(propertyKey)。
  3. 如果 receiver 不存在,则
    1. receivertarget
  4. 返回 ? target.[[Set]](key, V, receiver)

28.1.13 Reflect.setPrototypeOf ( target, proto )

该函数被调用时执行以下步骤:

  1. 如果 target 不是对象,抛出 TypeError 异常。
  2. 如果 proto 不是对象且也不是 null,抛出 TypeError 异常。
  3. 返回 ? target.[[SetPrototypeOf]](proto)

28.1.14 Reflect [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 属性的初始值为字符串 "Reflect"

该属性的特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

28.2 代理对象

28.2.1 Proxy 构造函数

Proxy 构造函数

  • %Proxy%
  • 是全局对象 "Proxy" 属性的初始值。
  • 作为构造函数调用时创建并初始化一个新的 Proxy 对象。
  • 不应作为函数调用,若以该方式调用将抛出异常。

28.2.1.1 Proxy ( target, handler )

该函数被调用时执行以下步骤:

  1. 如果 NewTarget 为 undefined,抛出 TypeError 异常。
  2. 返回 ? ProxyCreate(target, handler)。

28.2.2 Proxy 构造函数的属性

Proxy 构造函数

  • 具有其值为 %Function.prototype%[[Prototype]] 内部槽。
  • 没有 "prototype" 属性,因为 Proxy 对象不需要初始化 [[Prototype]] 内部槽。
  • 具有以下属性:

28.2.2.1 Proxy.revocable ( target, handler )

该函数创建一个可撤销的 Proxy 对象。

被调用时执行以下步骤:

  1. proxy 为 ? ProxyCreate(target, handler)。
  2. revokerClosure 为一个无参数、无捕获的新抽象闭包,被调用时执行以下步骤:
    1. F 为活动函数对象
    2. pF.[[RevocableProxy]]
    3. 如果 pnull,返回 NormalCompletion(undefined)。
    4. 设置 F.[[RevocableProxy]]null
    5. 断言:p 是 Proxy 异常对象。
    6. 设置 p.[[ProxyTarget]]null
    7. 设置 p.[[ProxyHandler]]null
    8. 返回 NormalCompletion(undefined)。
  3. revokerCreateBuiltinFunction(revokerClosure, 0, "", « [[RevocableProxy]] »)。
  4. 设置 revoker.[[RevocableProxy]]proxy
  5. resultOrdinaryObjectCreate(%Object.prototype%)。
  6. 执行 ! CreateDataPropertyOrThrow(result, "proxy", proxy)。
  7. 执行 ! CreateDataPropertyOrThrow(result, "revoke", revoker)。
  8. 返回 result

28.3 模块命名空间对象

模块命名空间对象是一个模块命名空间异构对象,为模块的导出绑定提供基于属性的运行时访问。没有模块命名空间对象的构造函数。相反,对于每个被 ImportDeclaration 并且包含 NameSpaceImport 导入的模块,都创建这样的对象。

除了 10.4.6 中指定的属性外,每个模块命名空间对象还有如下自有属性:

28.3.1 %Symbol.toStringTag%

%Symbol.toStringTag% 属性的初始值为字符串 "Module"

该属性的特性为 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。