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]]内部方法被调用时,会执行以下步骤:
- return OrdinaryGetPrototypeOf(O)
9.1.1.1 OrdinaryGetPrototypeOf (O)
当OrdinaryGetPrototypeOf这个抽象操作以对象 O 调用时,会执行以下步骤:
- return O.[[Prototype]]
9.1.2 [[SetPrototypeOf]] (V)
当 O 的[[SetPrototypeOf]]内部方法以 V 为参数调用时,会执行以下步骤:
- return OrdinarySetPrototypeOf(O, V)
9.1.2.1 OrdinarySetPrototypeOf(O, V)
当OrdinarySetPrototypeOf这个抽象操作以对象 O 和 V 值调用时,会执行以下步骤:
- 断言:Type(V) === Object or Null
- extensible = O.[[Extensible]]
- current = O.[[Prototype]]
- if (SameValue(V, current) === true) return true
- if (extensible === false) return false
- p = V
- done = false
- 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]]
- O.[[Prototype]] = V
- return true
9.1.3 [[IsExtensible]] ( )
当 O 的[[IsExtensible]]内部方法被调用时,会执行以下步骤:
- return OrdinaryIsExtensible(O)
9.1.3.1 OrdinaryIsExtensible (O)
当 OrdinaryIsExtensible 这个抽象操作以对象 O 调用时,会执行以下步骤:
- return O.[[Extensible]]
9.1.4[[PreventExtensions]] ( )
当 O 的[[PreventExtensions]]内部方法被调用时,会执行以下步骤:
- Return OrdinaryPreventExtensions(O).
9.1.4.1 OrdinaryPreventExtensions (O)
当 OrdinaryPreventExtensions 这个抽象操作以对象 O 调用时,会执行以下步骤:
- O.[[Extensible]] = false.
- Return true.
9.1.5 [[GetOwnProperty]] (P)
当 O 的[[GetOwnProperty]]内部方法被以属性键名P为参数调用时,会执行以下步骤:
- Return OrdinaryGetOwnProperty(O, P).
9.1.5.1 OrdinaryGetOwnProperty (O, P)
当 OrdinaryGetOwnProperty 这个抽象操作以对象 O 调用时,会执行以下步骤:
Assert: IsPropertyKey(P) is true.
If O does not have an own property with key P, return undefined.
Let D be a newly created Property Descriptor with no fields.
Let X be O's own property whose key is P.
If X is a data property, then
Set D.[[Value]] to the value of X's [[Value]] attribute.
Set D.[[Writable]] to the value of X's [[Writable]] attribute.
Else X is an accessor property, so
Set D.[[Get]] to the value of X's [[Get]] attribute.
Set D.[[Set]] to the value of X's [[Set]] attribute.
Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute.
Set D.[[Configurable]] to the value of X's [[Configurable]] attribute.
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:
Let current be ? O.[[GetOwnProperty]](P).
Let extensible be the value of the [[Extensible]] internal slot of O.
Return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current).