9.1 普通对象内置方法和内置属性

所有的普通对象都有内置属性[[Prototype]]。其值为null或者一个object,这个属性是用来实现继承的。[[Prototype]]的数据类特性是可继承的(在子对象中作为属性可见),但只在get操作中可以,set不行。访问器特性在get和set操作中都可以被继承。

任何普通对象独有一个布尔值的[[Extensible]]内部属性,用来控制改对象能否添加属性。如果为false,那么额外的属性可能讲不能添加到该对象,并且,为false后,[[Prototype]]值讲不能修改了。一旦值变为false,以后就再也没法修改为true了。

在接下来的算法描述中,假设 O 为普通对象, P 为属性的键值, V 为任何ECMAScript语言类型值, Desc 为属性描述符记录。

每个普通对象的内部属性都代理到一个类似名称的抽象操作,如果这样的一个抽象操作依赖另一个内部方法,那么这个内部方法是在 O 上调用,而不是直接调用这个内部方法。这样的语法就保证了当普通对象的方法作用于外来对象时,其拥有的内部方法可以覆盖。

9.1.1 [[GetPrototypeOf]] ()

当 O 的[[GetPrototypeOf]]内部方法被调用时,会执行以下步骤:

  1. return OrdinaryGetPrototypeOf(O)

9.1.1.1 OrdinaryGetPrototypeOf (O)

当OrdinaryGetPrototypeOf这个抽象操作以对象 O 调用时,会执行以下步骤:

  1. return O.[[Prototype]]

9.1.2 [[SetPrototypeOf]] (V)

当 O 的[[SetPrototypeOf]]内部方法以 V 为参数调用时,会执行以下步骤:

  1. return OrdinarySetPrototypeOf(O, V)

9.1.2.1 OrdinarySetPrototypeOf(O, V)

当OrdinarySetPrototypeOf这个抽象操作以对象 O 和 V 值调用时,会执行以下步骤:

  1. 断言:Type(V) === Object or Null
  2. extensible = O.[[Extensible]]
  3. current = O.[[Prototype]]
  4. if (SameValue(V, current) === true) return true
  5. if (extensible === false) return false
  6. p = V
  7. done = false
  8. while(!done):
    • if(p === null) done = true
    • else if (SameValue(p, O) === true) return false
    • else
      • if p.[[GetPrototypeOf]] 不是在9.1.1中定义的,done = true
      • else p = p.[[Prototype]]
  9. O.[[Prototype]] = V
  10. return true

9.1.3 [[IsExtensible]] ( )

当 O 的[[IsExtensible]]内部方法被调用时,会执行以下步骤:

  1. return OrdinaryIsExtensible(O)

9.1.3.1 OrdinaryIsExtensible (O)

当 OrdinaryIsExtensible 这个抽象操作以对象 O 调用时,会执行以下步骤:

  1. return O.[[Extensible]]

9.1.4[[PreventExtensions]] ( )

当 O 的[[PreventExtensions]]内部方法被调用时,会执行以下步骤:

  1. Return OrdinaryPreventExtensions(O).

9.1.4.1 OrdinaryPreventExtensions (O)

当 OrdinaryPreventExtensions 这个抽象操作以对象 O 调用时,会执行以下步骤:

  1. O.[[Extensible]] = false.
  2. Return true.

9.1.5 [[GetOwnProperty]] (P)

当 O 的[[GetOwnProperty]]内部方法被以属性键名P为参数调用时,会执行以下步骤:

  1. Return OrdinaryGetOwnProperty(O, P).

9.1.5.1 OrdinaryGetOwnProperty (O, P)

当 OrdinaryGetOwnProperty 这个抽象操作以对象 O 调用时,会执行以下步骤:

  1. Assert: IsPropertyKey(P) is true.
  2. If O does not have an own property with key P, return undefined.
  3. Let D be a newly created Property Descriptor with no fields.
  4. Let X be O's own property whose key is P.
  5. If X is a data property, then
  6. Set D.[[Value]] to the value of X's [[Value]] attribute.
  7. Set D.[[Writable]] to the value of X's [[Writable]] attribute.
  8. Else X is an accessor property, so
  9. Set D.[[Get]] to the value of X's [[Get]] attribute.
  10. Set D.[[Set]] to the value of X's [[Set]] attribute.
  11. Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute.
  12. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute.
  13. Return D.

9.1.6 [[DefineOwnProperty]] (P, Desc)

When the [[DefineOwnProperty]] internal method of O is called with property key P and Property Descriptor Desc, the following steps are taken:

Return ? OrdinaryDefineOwnProperty(O, P, Desc).

9.1.6.1 OrdinaryDefineOwnProperty (O, P, Desc)

When the abstract operation OrdinaryDefineOwnProperty is called with Object O, property key P, and Property Descriptor Desc, the following steps are taken:

  1. Let current be ? O.[[GetOwnProperty]]($9-P).
  2. Let extensible be the value of the [[Extensible]] internal slot of O.
  3. Return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current).