10.5 Proxy Object Internal Methods and Internal Slots
A Proxy object is an
An object is a Proxy exotic object if its essential internal methods (including [[Call]] and [[Construct]], if applicable) use the definitions in this section. These internal methods are installed in
Internal Method | Handler Method |
---|---|
[[GetPrototypeOf]] |
getPrototypeOf
|
[[SetPrototypeOf]] |
setPrototypeOf
|
[[IsExtensible]] |
isExtensible
|
[[PreventExtensions]] |
preventExtensions
|
[[GetOwnProperty]] |
getOwnPropertyDescriptor
|
[[DefineOwnProperty]] |
defineProperty
|
[[HasProperty]] |
has
|
[[Get]] |
get
|
[[Set]] |
set
|
[[Delete]] |
deleteProperty
|
[[OwnPropertyKeys]] |
ownKeys
|
[[Call]] |
apply
|
[[Construct]] |
construct
|
When a handler method is called to provide the implementation of a Proxy object internal method, the handler method is passed the proxy's target object as a parameter. A proxy's handler object does not necessarily have a method corresponding to every essential internal method. Invoking an internal method on the proxy results in the invocation of the corresponding internal method on the proxy's target object if the handler object does not have a method corresponding to the internal trap.
The [[ProxyHandler]] and [[ProxyTarget]] internal slots of a Proxy object are always initialized when the object is created and typically may not be modified. Some Proxy objects are created in a manner that permits them to be subsequently revoked. When a proxy is revoked, its [[ProxyHandler]] and [[ProxyTarget]] internal slots are set to
Because Proxy objects permit the implementation of internal methods to be provided by arbitrary ECMAScript code, it is possible to define a Proxy object whose handler methods violates the invariants defined in
In the following algorithm descriptions, assume O is an ECMAScript Proxy object, P is a
10.5.1 [[GetPrototypeOf]] ( )
The [[GetPrototypeOf]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"getPrototypeOf" ). - If trap is
undefined , then- Return ? target.[[GetPrototypeOf]]().
- Let handlerProto be ?
Call (trap, handler, « target »). - If handlerProto
is not an Object and handlerProto is notnull , throw aTypeError exception. - Let extensibleTarget be ?
IsExtensible (target). - If extensibleTarget is
true , return handlerProto. - Let targetProto be ? target.[[GetPrototypeOf]]().
- If
SameValue (handlerProto, targetProto) isfalse , throw aTypeError exception. - Return handlerProto.
[[GetPrototypeOf]] for Proxy objects enforces the following invariants:
-
The result of [[GetPrototypeOf]] must be either an Object or
null . - If the target object is not extensible, [[GetPrototypeOf]] applied to the Proxy object must return the same value as [[GetPrototypeOf]] applied to the Proxy object's target object.
10.5.2 [[SetPrototypeOf]] ( V )
The [[SetPrototypeOf]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"setPrototypeOf" ). - If trap is
undefined , then- Return ? target.[[SetPrototypeOf]](V).
- Let booleanTrapResult be
ToBoolean (?Call (trap, handler, « target, V »)). - If booleanTrapResult is
false , returnfalse . - Let extensibleTarget be ?
IsExtensible (target). - If extensibleTarget is
true , returntrue . - Let targetProto be ? target.[[GetPrototypeOf]]().
- If
SameValue (V, targetProto) isfalse , throw aTypeError exception. - Return
true .
[[SetPrototypeOf]] for Proxy objects enforces the following invariants:
-
The result of [[SetPrototypeOf]]
is a Boolean value. - If the target object is not extensible, the argument value must be the same as the result of [[GetPrototypeOf]] applied to target object.
10.5.3 [[IsExtensible]] ( )
The [[IsExtensible]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"isExtensible" ). - If trap is
undefined , then- Return ?
IsExtensible (target).
- Return ?
- Let booleanTrapResult be
ToBoolean (?Call (trap, handler, « target »)). - Let targetResult be ?
IsExtensible (target). - If booleanTrapResult is not targetResult, throw a
TypeError exception. - Return booleanTrapResult.
[[IsExtensible]] for Proxy objects enforces the following invariants:
-
The result of [[IsExtensible]]
is a Boolean value. - [[IsExtensible]] applied to the Proxy object must return the same value as [[IsExtensible]] applied to the Proxy object's target object with the same argument.
10.5.4 [[PreventExtensions]] ( )
The [[PreventExtensions]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"preventExtensions" ). - If trap is
undefined , then- Return ? target.[[PreventExtensions]]().
- Let booleanTrapResult be
ToBoolean (?Call (trap, handler, « target »)). - If booleanTrapResult is
true , then- Let extensibleTarget be ?
IsExtensible (target). - If extensibleTarget is
true , throw aTypeError exception.
- Let extensibleTarget be ?
- Return booleanTrapResult.
[[PreventExtensions]] for Proxy objects enforces the following invariants:
-
The result of [[PreventExtensions]]
is a Boolean value. -
[[PreventExtensions]] applied to the Proxy object only returns
true if [[IsExtensible]] applied to the Proxy object's target object isfalse .
10.5.5 [[GetOwnProperty]] ( P )
The [[GetOwnProperty]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"getOwnPropertyDescriptor" ). - If trap is
undefined , then- Return ? target.[[GetOwnProperty]](P).
- Let trapResultObj be ?
Call (trap, handler, « target, P »). - If trapResultObj
is not an Object and trapResultObj is notundefined , throw aTypeError exception. - Let targetDesc be ? target.[[GetOwnProperty]](P).
- If trapResultObj is
undefined , then- If targetDesc is
undefined , returnundefined . - If targetDesc.[[Configurable]] is
false , throw aTypeError exception. - Let extensibleTarget be ?
IsExtensible (target). - If extensibleTarget is
false , throw aTypeError exception. - Return
undefined .
- If targetDesc is
- Let extensibleTarget be ?
IsExtensible (target). - Let resultDesc be ?
ToPropertyDescriptor (trapResultObj). - Perform
CompletePropertyDescriptor (resultDesc). - Let valid be
IsCompatiblePropertyDescriptor (extensibleTarget, resultDesc, targetDesc). - If valid is
false , throw aTypeError exception. - If resultDesc.[[Configurable]] is
false , then- If targetDesc is
undefined or targetDesc.[[Configurable]] istrue , then- Throw a
TypeError exception.
- Throw a
- If resultDesc has a [[Writable]] field and resultDesc.[[Writable]] is
false , thenAssert : targetDesc has a [[Writable]] field.- If targetDesc.[[Writable]] is
true , throw aTypeError exception.
- If targetDesc is
- Return resultDesc.
[[GetOwnProperty]] for Proxy objects enforces the following invariants:
-
The result of [[GetOwnProperty]] must be either an Object or
undefined . - A property cannot be reported as non-existent, if it exists as a non-configurable own property of the target object.
- A property cannot be reported as non-existent, if it exists as an own property of a non-extensible target object.
- A property cannot be reported as existent, if it does not exist as an own property of the target object and the target object is not extensible.
- A property cannot be reported as non-configurable, unless it exists as a non-configurable own property of the target object.
- A property cannot be reported as both non-configurable and non-writable, unless it exists as a non-configurable, non-writable own property of the target object.
10.5.6 [[DefineOwnProperty]] ( P, Desc )
The [[DefineOwnProperty]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"defineProperty" ). - If trap is
undefined , then- Return ? target.[[DefineOwnProperty]](P, Desc).
- Let descObj be
FromPropertyDescriptor (Desc). - Let booleanTrapResult be
ToBoolean (?Call (trap, handler, « target, P, descObj »)). - If booleanTrapResult is
false , returnfalse . - Let targetDesc be ? target.[[GetOwnProperty]](P).
- Let extensibleTarget be ?
IsExtensible (target). - If Desc has a [[Configurable]] field and Desc.[[Configurable]] is
false , then- Let settingConfigFalse be
true .
- Let settingConfigFalse be
- Else,
- Let settingConfigFalse be
false .
- Let settingConfigFalse be
- If targetDesc is
undefined , then- If extensibleTarget is
false , throw aTypeError exception. - If settingConfigFalse is
true , throw aTypeError exception.
- If extensibleTarget is
- Else,
- If
IsCompatiblePropertyDescriptor (extensibleTarget, Desc, targetDesc) isfalse , throw aTypeError exception. - If settingConfigFalse is
true and targetDesc.[[Configurable]] istrue , throw aTypeError exception. - If
IsDataDescriptor (targetDesc) istrue , targetDesc.[[Configurable]] isfalse , and targetDesc.[[Writable]] istrue , then- If Desc has a [[Writable]] field and Desc.[[Writable]] is
false , throw aTypeError exception.
- If Desc has a [[Writable]] field and Desc.[[Writable]] is
- If
- Return
true .
[[DefineOwnProperty]] for Proxy objects enforces the following invariants:
-
The result of [[DefineOwnProperty]]
is a Boolean value. - A property cannot be added, if the target object is not extensible.
- A property cannot be non-configurable, unless there exists a corresponding non-configurable own property of the target object.
- A non-configurable property cannot be non-writable, unless there exists a corresponding non-configurable, non-writable own property of the target object.
-
If a property has a corresponding target object property then applying the
Property Descriptor of the property to the target object using [[DefineOwnProperty]] will not throw an exception.
10.5.7 [[HasProperty]] ( P )
The [[HasProperty]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"has" ). - If trap is
undefined , then- Return ? target.[[HasProperty]](P).
- Let booleanTrapResult be
ToBoolean (?Call (trap, handler, « target, P »)). - If booleanTrapResult is
false , then- Let targetDesc be ? target.[[GetOwnProperty]](P).
- If targetDesc is not
undefined , then- If targetDesc.[[Configurable]] is
false , throw aTypeError exception. - Let extensibleTarget be ?
IsExtensible (target). - If extensibleTarget is
false , throw aTypeError exception.
- If targetDesc.[[Configurable]] is
- Return booleanTrapResult.
[[HasProperty]] for Proxy objects enforces the following invariants:
-
The result of [[HasProperty]]
is a Boolean value. - A property cannot be reported as non-existent, if it exists as a non-configurable own property of the target object.
- A property cannot be reported as non-existent, if it exists as an own property of the target object and the target object is not extensible.
10.5.8 [[Get]] ( P, Receiver )
The [[Get]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"get" ). - If trap is
undefined , then- Return ? target.[[Get]](P, Receiver).
- Let trapResult be ?
Call (trap, handler, « target, P, Receiver »). - Let targetDesc be ? target.[[GetOwnProperty]](P).
- If targetDesc is not
undefined and targetDesc.[[Configurable]] isfalse , then- If
IsDataDescriptor (targetDesc) istrue and targetDesc.[[Writable]] isfalse , then- If
SameValue (trapResult, targetDesc.[[Value]]) isfalse , throw aTypeError exception.
- If
- If
IsAccessorDescriptor (targetDesc) istrue and targetDesc.[[Get]] isundefined , then- If trapResult is not
undefined , throw aTypeError exception.
- If trapResult is not
- If
- Return trapResult.
[[Get]] for Proxy objects enforces the following invariants:
-
The value reported for a property must be the same as the value of the corresponding target object property if the target object property is a non-writable, non-configurable own
data property . -
The value reported for a property must be
undefined if the corresponding target object property is a non-configurable ownaccessor property that hasundefined as its [[Get]] attribute.
10.5.9 [[Set]] ( P, V, Receiver )
The [[Set]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"set" ). - If trap is
undefined , then- Return ? target.[[Set]](P, V, Receiver).
- Let booleanTrapResult be
ToBoolean (?Call (trap, handler, « target, P, V, Receiver »)). - If booleanTrapResult is
false , returnfalse . - Let targetDesc be ? target.[[GetOwnProperty]](P).
- If targetDesc is not
undefined and targetDesc.[[Configurable]] isfalse , then- If
IsDataDescriptor (targetDesc) istrue and targetDesc.[[Writable]] isfalse , then- If
SameValue (V, targetDesc.[[Value]]) isfalse , throw aTypeError exception.
- If
- If
IsAccessorDescriptor (targetDesc) istrue , then- If targetDesc.[[Set]] is
undefined , throw aTypeError exception.
- If targetDesc.[[Set]] is
- If
- Return
true .
[[Set]] for Proxy objects enforces the following invariants:
-
The result of [[Set]]
is a Boolean value. -
Cannot change the value of a property to be different from the value of the corresponding target object property if the corresponding target object property is a non-writable, non-configurable own
data property . -
Cannot set the value of a property if the corresponding target object property is a non-configurable own
accessor property that hasundefined as its [[Set]] attribute.
10.5.10 [[Delete]] ( P )
The [[Delete]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"deleteProperty" ). - If trap is
undefined , then- Return ? target.[[Delete]](P).
- Let booleanTrapResult be
ToBoolean (?Call (trap, handler, « target, P »)). - If booleanTrapResult is
false , returnfalse . - Let targetDesc be ? target.[[GetOwnProperty]](P).
- If targetDesc is
undefined , returntrue . - If targetDesc.[[Configurable]] is
false , throw aTypeError exception. - Let extensibleTarget be ?
IsExtensible (target). - If extensibleTarget is
false , throw aTypeError exception. - Return
true .
[[Delete]] for Proxy objects enforces the following invariants:
-
The result of [[Delete]]
is a Boolean value. - A property cannot be reported as deleted, if it exists as a non-configurable own property of the target object.
- A property cannot be reported as deleted, if it exists as an own property of the target object and the target object is non-extensible.
10.5.11 [[OwnPropertyKeys]] ( )
The [[OwnPropertyKeys]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"ownKeys" ). - If trap is
undefined , then- Return ? target.[[OwnPropertyKeys]]().
- Let trapResultArray be ?
Call (trap, handler, « target »). - Let trapResult be ?
CreateListFromArrayLike (trapResultArray, « String, Symbol »). - If trapResult contains any duplicate entries, throw a
TypeError exception. - Let extensibleTarget be ?
IsExtensible (target). - Let targetKeys be ? target.[[OwnPropertyKeys]]().
Assert : targetKeys is aList ofproperty keys .Assert : targetKeys contains no duplicate entries.- Let targetConfigurableKeys be a new empty
List . - Let targetNonconfigurableKeys be a new empty
List . - For each element key of targetKeys, do
- Let desc be ? target.[[GetOwnProperty]](key).
- If desc is not
undefined and desc.[[Configurable]] isfalse , then- Append key to targetNonconfigurableKeys.
- Else,
- Append key to targetConfigurableKeys.
- If extensibleTarget is
true and targetNonconfigurableKeys is empty, then- Return trapResult.
- Let uncheckedResultKeys be a
List whose elements are the elements of trapResult. - For each element key of targetNonconfigurableKeys, do
- If uncheckedResultKeys does not contain key, throw a
TypeError exception. - Remove key from uncheckedResultKeys.
- If uncheckedResultKeys does not contain key, throw a
- If extensibleTarget is
true , return trapResult. - For each element key of targetConfigurableKeys, do
- If uncheckedResultKeys does not contain key, throw a
TypeError exception. - Remove key from uncheckedResultKeys.
- If uncheckedResultKeys does not contain key, throw a
- If uncheckedResultKeys is not empty, throw a
TypeError exception. - Return trapResult.
[[OwnPropertyKeys]] for Proxy objects enforces the following invariants:
-
The result of [[OwnPropertyKeys]] is a
List . -
The returned
List contains no duplicate entries. -
The Type of each result
List element is either String or Symbol. -
The result
List must contain the keys of all non-configurable own properties of the target object. -
If the target object is not extensible, then the result
List must contain all the keys of the own properties of the target object and no other values.
10.5.12 [[Call]] ( thisArgument, argumentsList )
The [[Call]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"apply" ). - If trap is
undefined , then- Return ?
Call (target, thisArgument, argumentsList).
- Return ?
- Let argArray be
CreateArrayFromList (argumentsList). - Return ?
Call (trap, handler, « target, thisArgument, argArray »).
A
10.5.13 [[Construct]] ( argumentsList, newTarget )
The [[Construct]] internal method of a
- Perform ?
ValidateNonRevokedProxy (O). - Let target be O.[[ProxyTarget]].
Assert :IsConstructor (target) istrue .- Let handler be O.[[ProxyHandler]].
Assert : handleris an Object .- Let trap be ?
GetMethod (handler,"construct" ). - If trap is
undefined , then- Return ?
Construct (target, argumentsList, newTarget).
- Return ?
- Let argArray be
CreateArrayFromList (argumentsList). - Let newObj be ?
Call (trap, handler, « target, argArray, newTarget »). - If newObj
is not an Object , throw aTypeError exception. - Return newObj.
A
[[Construct]] for Proxy objects enforces the following invariants:
- The result of [[Construct]] must be an Object.
10.5.14 ValidateNonRevokedProxy ( proxy )
The abstract operation ValidateNonRevokedProxy takes argument proxy (a
- If proxy.[[ProxyTarget]] is
null , throw aTypeError exception. Assert : proxy.[[ProxyHandler]] is notnull .- Return
unused .
10.5.15 ProxyCreate ( target, handler )
The abstract operation ProxyCreate takes arguments target (an
- If target
is not an Object , throw aTypeError exception. - If handler
is not an Object , throw aTypeError exception. - Let P be
MakeBasicObject (« [[ProxyHandler]], [[ProxyTarget]] »). - Set P's essential internal methods, except for [[Call]] and [[Construct]], to the definitions specified in
10.5 . - If
IsCallable (target) istrue , then- Set P.[[Call]] as specified in
10.5.12 . - If
IsConstructor (target) istrue , then- Set P.[[Construct]] as specified in
10.5.13 .
- Set P.[[Construct]] as specified in
- Set P.[[Call]] as specified in
- Set P.[[ProxyTarget]] to target.
- Set P.[[ProxyHandler]] to handler.
- Return P.