Exposed Object.getOwnPropertyDescriptor()
Original algorithm
The algorithm is specified in E5 Section 15.2.3.3:
- If
Type(O)
is notObject
throw aTypeError
exception. - Let
name
beToString(P)
. (Note: this may have a side effect.) - Let
desc
be the result of calling the[[GetOwnProperty]]
internal method ofO
with argumentname
. - Return the result of calling
FromPropertyDescriptor(desc)
(E5 Section 8.10.4).
FromPropertyDescriptor
The FromPropertyDescriptor()
algorithm in E5 Section 8.10.4 is as follows:
- If
Desc
isundefined
, then returnundefined
. - Let
obj
be the result of creating a new object as if by the expressionnew Object()
whereObject
is the standard built-in constructor with that name. - If
IsDataDescriptor(Desc)
istrue
, then a. Call the[[DefineOwnProperty]]
internal method ofobj
with arguments"value"
, Property Descriptor {[[Value]]: Desc.[[Value]], [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, andfalse
. b. Call the[[DefineOwnProperty]]
internal method ofobj
with arguments"writable"
, Property Descriptor {[[Value]]: Desc.[[Writable]], [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, andfalse
. - Else,
IsAccessorDescriptor(Desc)
must betrue
, so a. Call the[[DefineOwnProperty]]
internal method ofobj
with arguments"get"
, Property Descriptor {[[Value]]: Desc.[[Get]], [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, andfalse
. b. Call the[[DefineOwnProperty]]
internal method ofobj
with arguments"set"
, Property Descriptor {[[Value]]: Desc.[[Set]], [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, andfalse
. - Call the
[[DefineOwnProperty]]
internal method ofobj
with arguments"enumerable"
, Property Descriptor {[[Value]]: Desc.[[Enumerable]], [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, andfalse
. - Call the
[[DefineOwnProperty]]
internal method ofobj
with arguments"configurable"
, Property Descriptor {[[Value]]: Desc.[[Configurable]], [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, andfalse
. - Return
obj
.
Notes:
- Since all the
[[DefineOwnProperty]]
calls create new property values, and the property attributes match the defaults for[[Put]]
, we can simply use[[Put]]
instead. TheThrow
flag does not matter as the[[Put]]
operations cannot fail (except for some internal reason, which is thrown unconditionally without regard forThrow
anyway). - The order of settings properties to
obj
matters since it will affect the enumeration order ofobj
.
Changing [[DefineOwnProperty]]
to [[Put]]
and renaming Desc
to desc
(for compatibility with Object.getOwnPropertyDescriptor()
algorithm):
- If
desc
isundefined
, then returnundefined
. - Let
obj
be the result of creating a new object as if by the expressionnew Object()
whereObject
is the standard built-in constructor with that name. - If
IsDataDescriptor(desc)
istrue
, then a. Callobj.[[Put]]
with arguments"value"
,desc.[[Value]]
, andfalse
. b. Callobj.[[Put]]
with arguments"writable"
,desc.[[Writable]]
, andfalse
. - Else,
IsAccessorDescriptor(Desc)
must betrue
, so a. Callobj.[[Put]]
with arguments"get"
,desc.[[Get]]
, andfalse
. (Note:desc.[[Get]]
may beundefined
.) b. Callobj.[[Put]]
with arguments"set"
,desc.[[Set]]
, andfalse
. (Note:desc.[[Set]]
may beundefined
.) - Call
obj.[[Put]]
with arguments"enumerable"
,desc.[[Enumerable]]
, andfalse
. - Call
obj.[[Put]]
with arguments"configurable"
,desc.[[Configurable]]
, andfalse
. - Return
obj
.
Inlining FromPropertyDescriptor
- If
Type(O)
is notObject
throw aTypeError
exception. - Let
name
beToString(P)
. (Note: this may have a side effect.) - Let
desc
be the result of calling the[[GetOwnProperty]]
internal method ofO
with argumentname
. - If
desc
isundefined
, then returnundefined
. - Let
obj
be the result of creating a new object as if by the expressionnew Object()
whereObject
is the standard built-in constructor with that name. - If
IsDataDescriptor(desc)
istrue
, then a. Callobj.[[Put]]
with arguments"value"
,desc.[[Value]]
, andfalse
. b. Callobj.[[Put]]
with arguments"writable"
,desc.[[Writable]]
, andfalse
. - Else,
IsAccessorDescriptor(Desc)
must betrue
, so a. Callobj.[[Put]]
with arguments"get"
,desc.[[Get]]
, andfalse
. (Note:desc.[[Get]]
may beundefined
.) b. Callobj.[[Put]]
with arguments"set"
,desc.[[Set]]
, andfalse
. (Note:desc.[[Set]]
may beundefined
.) - Call
obj.[[Put]]
with arguments"enumerable"
,desc.[[Enumerable]]
, andfalse
. - Call
obj.[[Put]]
with arguments"configurable"
,desc.[[Configurable]]
, andfalse
. - Return
obj
.