‟Ex igne vita”
Algorithms within this specification manipulate values each of which has an associated type. The possible value types are exactly those defined in this clause. Types are further subclassified into ECMAScript language types and specification types.
An ECMAScript language type corresponds to values that are directly manipulated by an ECMAScript programmer using the ECMAScript language. The ECMAScript language types are Undefined, Null, Boolean, String, Number, and Object.
A specification type corresponds to meta-values that are used within algorithms to describe the semantics of ECMAScript language constructs and ECMAScript language types. The specification types are Reference, List, Completion, Property Descriptor, Property Identifier, Lexical Environment, and Environment Record. Specification type values are specification artefacts that do not necessarily correspond to any specific entity within an ECMAScript implementation. Specification type values may be used to describe intermediate results of ECMAScript expression evaluation but such values cannot be stored as properties of objects or values of ECMAScript language variables.
Within this specification, the notation “Type(x)” is used as shorthand for “the type of x” where “type” refers to the ECMAScript language and specification types defined in this clause.
The Undefined type has exactly one value, called undefined. Any variable that has not been assigned a value has the value undefined.
The Null type has exactly one value, called null.
The Boolean type represents a logical entity having two values, called true and false.
The String type is the set of all finite ordered sequences of zero or more 16-bit unsigned integer values (“elements”). The String type is generally used to represent textual data in a running ECMAScript program, in which case each element in the String is treated as a code unit value (see Clause 6). Each element is regarded as occupying a position within the sequence. These positions are indexed with nonnegative integers. The first element (if any) is at position 0, the next element (if any) at position 1, and so on. The length of a String is the number of elements (i.e., 16-bit values) within it. The empty String has length zero and therefore contains no elements.
When a String contains actual textual data, each element is considered to be a single UTF-16 code unit. Whether or not this is the actual storage format of a String, the characters within a String are numbered by their initial code unit element position as though they were represented using UTF-16. All operations on Strings (except as otherwise stated) treat them as sequences of undifferentiated 16-bit unsigned integers; they do not ensure the resulting String is in normalised form, nor do they ensure language-sensitive results.
NOTE The rationale behind this design was to keep the implementation of Strings as simple and high-performing as possible. The intent is that textual data coming into the execution environment from outside (e.g., user input, text read from a file or received over the network, etc.) be converted to Unicode Normalised Form C before the running program sees it. Usually this would occur at the same time incoming text is converted from its original character encoding to Unicode (and would impose no additional overhead). Since it is recommended that ECMAScript source code be in Normalised Form C, string literals are guaranteed to be normalised (if source text is guaranteed to be normalised), as long as they do not contain any Unicode escape sequences.
The
Number type has exactly 18437736874454810627
(that is, 264−253+3)
values, representing the double-precision 64-bit format IEEE 754
values as specified in the IEEE Standard for Binary Floating-Point
Arithmetic, except that the 9007199254740990
(that is, 253−2)
distinct “Not-a-Number” values of the IEEE Standard are
represented in ECMAScript as a single special NaN value.
(Note that the NaN value is produced by the program
expression NaN
.)
In some implementations, external code might be able to detect a
difference between various Not-a-Number values, but such behaviour
is implementation-dependent; to ECMAScript code, all NaN values are
indistinguishable from each other.
There
are two other special values, called positive Infinity and
negative Infinity. For brevity, these values are also
referred to for expository purposes by the symbols +∞
and −∞, respectively.
(Note that these two infinite Number values are produced by the
program expressions +Infinity
(or simply Infinity
)
and -Infinity
.)
The other 18437736874454810624 (that is, 264−253) values are called the finite numbers. Half of these are positive numbers and half are negative numbers; for every finite positive Number value there is a corresponding negative value having the same magnitude.
Note
that there is both a positive zero and a negative zero.
For brevity, these values are also referred to for expository
purposes by the symbols +0
and −0,
respectively. (Note that these two different zero Number values are
produced by the program expressions +0
(or simply 0
) and
-0
.)
The 18437736874454810622 (that is, 264−253−2) finite nonzero values are of two kinds:
18428729675200069632 (that is, 264−254) of them are normalised, having the form
s × m × 2e
where s is +1 or −1, m is a positive integer less than 253 but not less than 252, and e is an integer ranging from −1074 to 971, inclusive.
The remaining 9007199254740990 (that is, 253−2) values are denormalised, having the form
s × m × 2e
where s is +1 or −1, m is a positive integer less than 252, and e is −1074.
Note
that all the positive and negative integers whose magnitude is no
greater than 253
are representable in the Number type (indeed, the integer 0
has two representations, +0
and -0
).
A finite number has an odd significand if it is nonzero and the integer m used to express it (in one of the two forms shown above) is odd. Otherwise, it has an even significand.
In this specification, the phrase “the Number value for x” where x represents an exact nonzero real mathematical quantity (which might even be an irrational number such as π) means a Number value chosen in the following manner. Consider the set of all finite values of the Number type, with −0 removed and with two additional values added to it that are not representable in the Number type, namely 21024 (which is +1 × 253× 2971) and −21024 (which is −1 × 253× 2971). Choose the member of this set that is closest in value to x. If two values of the set are equally close, then the one with an even significand is chosen; for this purpose, the two extra values 21024 and −21024 are considered to have even significands. Finally, if 21024 was chosen, replace it with +∞; if −21024 was chosen, replace it with −∞; if +0 was chosen, replace it with −0 if and only if x is less than zero; any other chosen value is used unchanged. The result is the Number value for x. (This procedure corresponds exactly to the behaviour of the IEEE 754 “round to nearest” mode.)
Some ECMAScript operators deal only with integers in the range −231 through 231−1, inclusive, or in the range 0 through 232−1, inclusive. These operators accept any value of the Number type but first convert each such value to one of 232 integer values. See the descriptions of the ToInt32 and ToUint32 operators in 9.5 and 9.6, respectively.
An Object is a collection of properties. Each property is either a named data property, a named accessor property, or an internal property:
A named data property associates a name with an ECMAScript language value and a set of Boolean attributes.
A named accessor property associates a name with one or two accessor functions, and a set of Boolean attributes. The accessor functions are used to store or retrieve an ECMAScript language value that is associated with the property.
An internal property has no name and is not directly accessible via ECMAScript language operators. Internal properties exist purely for specification purposes.
There are two kinds of access for named (non-internal) properties: get and put, corresponding to retrieval and assignment, respectively.
Attributes are used in this specification to define and explain the state of named properties. A named data property associates a name with the attributes listed in Table 5
Attribute Name |
Value Domain |
Description |
[[Value]] |
Any ECMAScript language type |
The value retrieved by reading the property. |
[[Writable]] |
Boolean |
If false, attempts by ECMAScript code to change the property’s [[Value]] attribute using [[Put]] will not succeed. |
[[Enumerable]] |
Boolean |
If true, the property will be enumerated by a for-in enumeration (see 12.6.4). Otherwise, the property is said to be non-enumerable. |
[[Configurable]] |
Boolean |
If false, attempts to delete the property, change the property to be an accessor property, or change its attributes (other than [[Value]]) will fail. |
A named accessor property associates a name with the attributes listed in Table 6.
Attribute Name |
Value Domain |
Description |
[[Get]] |
Object or Undefined |
If the value is an Object it must be a function Object. The function’s [[Call]] internal method (8.6.2) is called with an empty arguments list to return the property value each time a get access of the property is performed. |
[[Set]] |
Object or Undefined |
If the value is an Object it must be a function Object. The function’s [[Call]] internal method (8.6.2) is called with an arguments list containing the assigned value as its sole argument each time a set access of the property is performed. The effect of a property's [[Set]] internal method may, but is not required to, have an effect on the value returned by subsequent calls to the property's [[Get]] internal method. |
[[Enumerable]] |
Boolean |
If true, the property is to be enumerated by a for-in enumeration (see 12.6.4). Otherwise, the property is said to be non-enumerable. |
[[Configurable]] |
Boolean |
If false, attempts to delete the property, change the property to be a data property, or change its attributes will fail. |
If the value of an attribute is not explicitly specified by this specification for a named property, the default value defined in Table 7 is used.
Attribute Name |
Default Value |
[[Value]] |
undefined |
[[Get]] |
undefined |
[[Set]] |
undefined |
[[Writable]] |
false |
[[Enumerable]] |
false |
[[Configurable]] |
false |
This specification uses various internal properties to define the semantics of object values. These internal properties are not part of the ECMAScript language. They are defined by this specification purely for expository purposes. An implementation of ECMAScript must behave as if it produced and operated upon internal properties in the manner described here. The names of internal properties are enclosed in double square brackets [[ ]]. When an algorithm uses an internal property of an object and the object does not implement the indicated internal property, a TypeError exception is thrown.
The Table 8 summarises the internal properties used by this specification that are applicable to all ECMAScript objects. The Table 9 summarises the internal properties used by this specification that are only applicable to some ECMAScript objects. The descriptions in these tables indicates their behaviour for native ECMAScript objects, unless stated otherwise in this document for particular kinds of native ECMAScript objects. Host objects may support these internal properties with any implementation-dependent behaviour as long as it is consistent with the specific host object restrictions stated in this document.
The “Value Type Domain” columns of the following tables define the types of values associated with internal properties. The type names refer to the types defined in Clause 8 augmented by the following additional names. “any” means the value may be any ECMAScript language type. “primitive” means Undefined, Null, Boolean, String, or Number. “SpecOp” means the internal property is an internal method, an implementation provided procedure defined by an abstract operation specification. “SpecOp” is followed by a list of descriptive parameter names. If a parameter name is the same as a type name then the name describes the type of the parameter. If a “SpecOp” returns a value, its parameter list is followed by the symbol “→” and the type of the returned value.
Internal Property |
Value Type Domain |
Description |
[[Prototype]] |
Object or Null |
The prototype of this object. |
[[Class]] |
String |
A String value indicating a specification defined classification of objects. |
[[Extensible]] |
Boolean |
If true, own properties may be added to the object. |
[[Get]] |
SpecOp(propertyName) → any |
Returns the value of the named property. |
[[GetOwnProperty]] |
SpecOp (propertyName) → Undefinedor Property Descriptor |
Returns the Property Descriptor of the named own property of this object, or undefined if absent. |
[[GetProperty]] |
SpecOp (propertyName) → Undefinedor Property Descriptor |
Returns the fully populated Property Descriptor of the named property of this object, or undefined if absent. |
[[Put]] |
SpecOp (propertyName, any, Boolean) |
Sets the specified named property to the value of the second parameter. The flag controls failure handling. |
[[CanPut]] |
SpecOp (propertyName) → Boolean |
Returns a Boolean value indicating whether a [[Put]] operation with PropertyName can be performed. |
[[HasProperty]] |
SpecOp (propertyName) → Boolean |
Returns a Boolean value indicating whether the object already has a property with the given name. |
[[Delete]] |
SpecOp (propertyName, Boolean) → Boolean |
Removes the specified named own property from the object. The flag controls failure handling. |
[[DefaultValue]] |
SpecOp (Hint) → primitive |
Hint is a String. Returns a default value for the object. |
[[DefineOwnProperty]] |
SpecOp (propertyName, PropertyDescriptor, Boolean) → Boolean |
Creates or alters the named own property to have the state described by a Property Descriptor. The flag controls failure handling. |
Every object (including host objects) must implement all of the internal properties listed in Table 8. However, the [[DefaultValue]] internal method may, for some objects, simply throw a TypeError exception.
All objects have an internal property called [[Prototype]]. The value of this property is either null or an object and is used for implementing inheritance. Whether or not a native object can have a host object as its [[Prototype]] depends on the implementation. Every [[Prototype]] chain must have finite length (that is, starting from any object, recursively accessing the [[Prototype]] internal property must eventually lead to a null value). Named data properties of the [[Prototype]] object are inherited (are visible as properties of the child object) for the purposes of get access, but not for put access. Named accessor properties are inherited for both get access and put access.
Every ECMAScript object has a Boolean-valued [[Extensible]] internal property that controls whether or not named properties may be added to the object. If the value of the [[Extensible]] internal property is false then additional named properties may not be added to the object. In addition, if [[Extensible]] is false the value of the [[Class]] and [[Prototype]] internal properties of the object may not be modified. Once the value of an [[Extensible]] internal property has been set to false it may not be subsequently changed to true.
NOTE This specification defines no ECMAScript language operators or built-in functions that permit a program to modify an object’s [[Class]] or [[Prototype]] internal properties or to change the value of [[Extensible]] from false to true. Implementation specific extensions that modify [[Class]], [[Prototype]] or [[Extensible]] must not violate the invariants defined in the preceding paragraph.
The
value of the [[Class]] internal property is defined by this
specification for every kind of built-in object. The value of the
[[Class]] internal property of a host object may be any String value
except one of "Arguments"
,
"Array"
,
"Boolean"
,
"Date"
,
"Error"
,
"Function"
,
"JSON"
,
"Math"
,
"Number"
,
"Object"
,
"RegExp"
,
and "String"
.
The value of a [[Class]] internal property is used internally to
distinguish different kinds of objects. Note that this specification
does not provide any means for a program to access that value except
through Object.prototype.toString
(see 15.2.4.2).
Unless otherwise specified, the common internal methods of native ECMAScript objects behave as described in 8.12. Array objects have a slightly different implementation of the [[DefineOwnProperty]] internal method (see 15.4.5.1) and String objects have a slightly different implementation of the [[GetOwnProperty]] internal method (see 15.5.5.2). Arguments objects (10.6) have different implementations of [[Get]], [[GetOwnProperty]], [[DefineOwnProperty]], and [[Delete]]. Function objects (15.3) have a different implementation of [[Get]].
Host objects may implement these internal methods in any manner unless specified otherwise; for example, one possibility is that [[Get]] and [[Put]] for a particular host object indeed fetch and store property values but [[HasProperty]] always generates false. However, if any specified manipulation of a host object's internal properties is not supported by an implementation, that manipulation must throw a TypeError exception when attempted.
The [[GetOwnProperty]] internal method of a host object must conform to the following invariants for each property of the host object:
If a property is described as a data property and it may return different values over time, then either or both of the [[Writable]] and [[Configurable] attributes must be true even if no mechanism to change the value is exposed via the other internal methods.
If a property is described as a data property and its [[Writable]] and [[Configurable]] are both false, then the SameValue (according to 9.12) must be returned for the [[Value]] attribute of the property on all calls to [[GetOwnProperty]].
If the attributes other than [[Writable]] may change over time or if the property might disappear, then the [[Configurable]] attribute must be true.
If the [[Writable]] attribute may change from false to true, then the [[Configurable]] attribute must be true.
If the value of the host object’s [[Extensible]] internal property is has been observed by ECMAScript code to be false, then if a call to [[GetOwnProperty]] describes a property as non-existent all subsequent calls must also describe that property as non-existent.
The [[DefineOwnProperty]] internal method of a host object must not permit the addition of a new property to a host object if the [[Extensible]] internal property of that host object has been observed by ECMAScript code to be false.
If the [[Extensible]] internal property of that host object has been observed by ECMAScript code to be false then it must not subsequently become true.
Internal Property |
Value Type Domain |
Description |
[[PrimitiveValue]] |
primitive |
Internal state information associated with this object. Of the standard built-in ECMAScript objects, only Boolean, Date, Number, and String objects implement [[PrimitiveValue]]. |
[[Construct]] |
Creates
an object. Invoked via the |
|
[[Call]] |
Executes code associated with the object. Invoked via a function call expression. The arguments to the SpecOp are a this object and a list containing the arguments passed to the function call expression. Objects that implement this internal method are callable. Only callable objects that are host objects may return Reference values. |
|
[[HasInstance]] |
SpecOp(any) → Boolean |
Returns a Boolean value indicating whether the argument is likely an Object that was constructed by this object. Of the standard built-in ECMAScript objects, only Function objects implement [[HasInstance]]. |
[[Scope]] |
A lexical environment that defines the environment in which a Function object is executed. Of the standard built-in ECMAScript objects, only Function objects implement [[Scope]]. |
|
[[FormalParameters]] |
List of Strings |
A possibly empty List containing the identifier Strings of a Function’s FormalParameterList. Of the standard built-in ECMAScript objects, only Function objects implement [[FormalParameterList]]. |
[[Code]] |
ECMAScript code |
The ECMAScript code of a function. Of the standard built-in ECMAScript objects, only Function objects implement [[Code]]. |
[[TargetFunction]] |
Object |
The target function of a function object created using the standard built-in Function.prototype.bind method. Only ECMAScript objects created using Function.prototype.bind have a [[TargetFunction]] internal property. |
[[BoundThis]] |
any |
The pre-bound this value of a function Object created using the standard built-in Function.prototype.bind method. Only ECMAScript objects created using Function.prototype.bind have a [[BoundThis]] internal property. |
[[BoundArguments]] |
List of any |
The pre-bound argument values of a function Object created using the standard built-in Function.prototype.bind method. Only ECMAScript objects created using Function.prototype.bind have a [[BoundArguments]] internal property. |
[[Match]] |
SpecOp(String, index) → MatchResult |
Tests for a regular expression match and returns a MatchResult value (see 15.10.2.1). Of the standard built-in ECMAScript objects, only RegExp objects implement [[Match]]. |
[[ParameterMap]] |
Object |
Provides a mapping between the properties of an arguments object (see 10.6) and the formal parameters of the associated function. Only ECMAScript objects that are arguments objects have a [[ParameterMap]] internal property. |
The
Reference type is used to explain the behaviour of such operators as
delete
, typeof
,
and the assignment operators. For example, the left-hand operand of
an assignment is expected to produce a reference. The behaviour of
assignment could, instead, be explained entirely in terms of a case
analysis on the syntactic form of the left-hand operand of an
assignment operator, but for one difficulty: function calls are
permitted to return references. This possibility is admitted purely
for the sake of host objects. No built-in ECMAScript function
defined by this specification returns a reference and there is no
provision for a user-defined function to return a reference.
(Another reason not to use a syntactic case analysis is that it
would be lengthy and awkward, affecting many parts of the
specification.)
A Reference is a resolved name binding. A Reference consists of three components, the base value, the referenced name and the Boolean valued strict reference flag. The base value is either undefined, an Object, a Boolean, a String, a Number, or an environment record (10.2.1). A base value of undefined indicates that the reference could not be resolved to a binding. The referenced name is a String.
The following abstract operations are used in this specification to access the components of references:
GetBase(V). Returns the base value component of the reference V.
GetReferencedName(V). Returns the referenced name component of the reference V.
IsStrictReference(V). Returns the strict reference component of the reference V.
HasPrimitiveBase(V). Returns true if the base value is a Boolean, String, or Number.
IsPropertyReference(V). Returns true if either the base value is an object or HasPrimitiveBase(V) is true; otherwise returns false.
IsUnresolvableReference(V). Returns true if the base value is undefined and false otherwise.
The following abstract operations are used in this specification to operate on references:
Let base be the result of calling GetBase(V).
If IsUnresolvableReference(V), throw a ReferenceError exception.
If IsPropertyReference(V), then
If HasPrimitiveBase(V) is false, then let get be the [[Get]] internal method of base, otherwise let get be the special [[Get]] internal method defined below.
Return the result of calling the get internal method using base as its this value, and passing GetReferencedName(V) for the argument.
Else, base must be an environment record.
Return the result of calling the GetBindingValue (see 10.2.1) concrete method of base passing GetReferencedName(V) and IsStrictReference(V) as arguments.
The following [[Get]] internal method is used by GetValue when V is a property reference with a primitive base value. It is called using base as its this value and with property P as its argument. The following steps are taken:
Let O be ToObject(base).
Let desc be the result of calling the [[GetProperty]] internal method of O with property name P.
If desc is undefined, return undefined.
If IsDataDescriptor(desc) is true, return desc.[[Value]].
Otherwise, IsAccessorDescriptor(desc) must be true so, let getter be desc.[[Get]].
If getter is undefined, return undefined.
Return the result calling the [[Call]] internal method of getter providing base as the this value and providing no arguments.
NOTE The object that may be created in step 1 is not accessible outside of the above method. An implementation might choose to avoid the actual creation of the object. The only situation where such an actual property access that uses this internal method can have visible effect is when it invokes an accessor function.
If Type(V) is not Reference, throw a ReferenceError exception.
Let base be the result of calling GetBase(V).
If IsUnresolvableReference(V), then
If IsStrictReference(V) is true, then
Throw ReferenceError exception.
Call the [[Put]] internal method of the global object, passing GetReferencedName(V) for the property name, W for the value, and false for the Throw flag.
Else if IsPropertyReference(V), then
If HasPrimitiveBase(V) is false, then let put be the [[Put]] internal method of base, otherwise let put be the special [[Put]] internal method defined below.
Call the put internal method using base as its this value, and passing GetReferencedName(V) for the property name, W for the value, and IsStrictReference(V) for the Throw flag.
Else base must be a reference whose base is an environment record. So,
Call the SetMutableBinding (10.2.1) concrete method of base, passing GetReferencedName(V), W, and IsStrictReference(V) as arguments.
Return.
The following [[Put]] internal method is used by PutValue when V is a property reference with a primitive base value. It is called using base as its this value and with property P, value W, and Boolean flag Throw as arguments. The following steps are taken:
Let O be ToObject(base).
If the result of calling the [[CanPut]] internal method of O with argument P is false, then
If Throw is true, then throw a TypeError exception.
Else return.
Let ownDesc be the result of calling the [[GetOwnProperty]] internal method of O with argument P.
If IsDataDescriptor(ownDesc) is true, then
If Throw is true, then throw a TypeError exception.
Else Return.
Let desc be the result of calling the [[GetProperty]] internal method of O with argument P. This may be either an own or inherited accessor property descriptor or an inherited data property descriptor.
If IsAccessorDescriptor(desc) is true, then
Let setter be desc.[[Set]] which cannot be undefined.
Call the [[Call]] internal method of setter providing base as the this value and an argument list containing only W.
Else, this is a request to create an own property on the transient object O
If Throw is true, then throw a TypeError exception.
Return.
NOTE The object that may be created in step 1 is not accessible outside of the above method. An implementation might choose to avoid the actual creation of that transient object. The only situations where such an actual property assignment that uses this internal method can have visible effect are when it either invokes an accessor function or is in violation of a Throw predicated error check. When Throw is true any property assignment that would create a new property on the transient object throws an error.
The
List type is used to explain the evaluation of argument lists (see
11.2.4) in new
expressions, in function calls, and in other algorithms where a
simple list of values is needed. Values of the List type are simply
ordered sequences of values. These sequences may be of any length.
The
Completion type is used to explain the behaviour of statements
(break
, continue
,
return
and throw
)
that perform nonlocal transfers of control. Values of the Completion
type are triples of the form (type, value, target),
where type is one of normal, break, continue,
return, or throw, value is any ECMAScript
language value or empty, and target is any ECMAScript
identifier or empty.
The term “abrupt completion” refers to any completion with a type other than normal.
The Property Descriptor type is used to explain the manipulation and reification of named property attributes. Values of the Property Descriptor type are records composed of named fields where each field’s name is an attribute name and its value is a corresponding attribute value as specified in 8.6.1. In addition, any field may be present or absent.
Property Descriptor values may be further classified as data property descriptors and accessor property descriptors based upon the existence or use of certain fields. A data property descriptor is one that includes any fields named either [[Value]] or [[Writable]]. An accessor property descriptor is one that includes any fields named either [[Get]] or [[Set]]. Any property descriptor may have fields named [[Enumerable]] and [[Configurable]]. A Property Descriptor value may not be both a data property descriptor and an accessor property descriptor; however, it may be neither. A generic property descriptor is a Property Descriptor value that is neither a data property descriptor nor an accessor property descriptor. A fully populated property descriptor is one that is either an accessor property descriptor or a data property descriptor and that has all of the fields that correspond to the property attributes defined in either 8.6.1 Table 5 or Table 6.
For notational convenience within this specification, an object literal-like syntax can be used to define a property descriptor value. For example, Property Descriptor {[[Value]]: 42, [[Writable]]: false, [[Configurable]]: true} defines a data property descriptor. Field name order is not significant. Any fields that are not explicitly listed are considered to be absent.
In specification text and algorithms, dot notation may be used to refer to a specific field of a Property Descriptor. For example, if D is a property descriptor then D.[[Value]] is shorthand for “the field of D named [[Value]]”.
The Property Identifier type is used to associate a property name with a Property Descriptor. Values of the Property Identifier type are pairs of the form (name, descriptor), where name is a String and descriptor is a Property Descriptor value.
The following abstract operations are used in this specification to operate upon Property Descriptor values:
When the abstract operation IsAccessorDescriptor is called with property descriptor Desc, the following steps are taken:
If Desc is undefined, then return false.
If both Desc.[[Get]] and Desc.[[Set]] are absent, then return false.
Return true.
When the abstract operation IsDataDescriptor is called with property descriptor Desc, the following steps are taken:
If Desc is undefined, then return false.
If both Desc.[[Value]] and Desc.[[Writable]] are absent, then return false.
Return true.
When the abstract operation IsGenericDescriptor is called with property descriptor Desc, the following steps are taken:
If Desc is undefined, then return false.
If IsAccessorDescriptor(Desc) and IsDataDescriptor(Desc) are both false, then return true.
Return false.
When the abstract operation FromPropertyDescriptor is called with property descriptor Desc, the following steps are taken:
The following algorithm assumes that Desc is a fully populated Property Descriptor, such as that returned from [[GetOwnProperty]] (see 8.12.1).
If Desc is undefined, then return undefined.
Let obj be the result of creating a new object as if by the expression new Object() where Object is the standard built-in constructor with that name.
If IsDataDescriptor(Desc) is true, then
Call
the [[DefineOwnProperty]] internal method of obj
with arguments "value
",
Property Descriptor {[[Value]]: Desc.[[Value]],
[[Writable]]: true,
[[Enumerable]]: true,
[[Configurable]]: true},
and false.
Call
the [[DefineOwnProperty]] internal method of obj
with arguments "writable
",
Property Descriptor {[[Value]]: Desc.[[Writable]],
[[Writable]]: true,
[[Enumerable]]: true,
[[Configurable]]: true},
and false.
Else, IsAccessorDescriptor(Desc) must be true, so
Call
the [[DefineOwnProperty]] internal method of obj
with arguments "get"
,
Property Descriptor {[[Value]]: Desc.[[Get]],
[[Writable]]: true,
[[Enumerable]]: true,
[[Configurable]]: true},
and false.
Call
the [[DefineOwnProperty]] internal method of obj
with arguments "set
",
Property Descriptor {[[Value]]: Desc.[[Set]],
[[Writable]]: true,
[[Enumerable]]: true,
[[Configurable]]: true},
and false.
Call
the [[DefineOwnProperty]] internal method of obj
with arguments "enumerable
",
Property Descriptor {[[Value]]: Desc.[[Enumerable]],
[[Writable]]: true,
[[Enumerable]]: true,
[[Configurable]]: true},
and false.
Call
the [[DefineOwnProperty]] internal method of obj
with arguments "configurable
",
Property Descriptor {[[Value]]: Desc.[[Configurable]],
[[Writable]]: true,
[[Enumerable]]: true,
[[Configurable]]: true},
and false.
Return obj.
When the abstract operation ToPropertyDescriptor is called with object Desc, the following steps are taken:
If Type(Obj) is not Object throw a TypeError exception.
Let desc be the result of creating a new Property Descriptor that initially has no fields.
If
the result of calling the [[HasProperty]] internal method of Obj
with argument "enumerable
"
is true, then
Let
enum be the result of calling the [[Get]] internal method
of Obj with "enumerable
".
Set the [[Enumerable]] field of desc to ToBoolean(enum).
If
the result of calling the [[HasProperty]] internal method of Obj
with argument "configurable
"
is true, then
Let
conf be the result of calling the [[Get]] internal method
of Obj with argument "configurable
".
Set the [[Configurable]] field of desc to ToBoolean(conf).
If
the result of calling the [[HasProperty]] internal method of Obj
with argument "value
"
is true, then
Let
value be the result of calling the [[Get]] internal method
of Obj with argument “value
”.
Set the [[Value]] field of desc to value.
If
the result of calling the [[HasProperty]] internal method of Obj
with argument "writable
"
is true, then
Let
writable be the result of calling the [[Get]] internal
method of Obj with argument "writable
".
Set the [[Writable]] field of desc to ToBoolean(writable).
If
the result of calling the [[HasProperty]] internal method of Obj
with argument "get
"
is true, then
Let
getter be the result of calling the [[Get]] internal method
of Obj with argument "get
".
If IsCallable(getter) is false and getter is not undefined, then throw a TypeError exception.
Set the [[Get]] field of desc to getter.
If
the result of calling the [[HasProperty]] internal method of Obj
with argument "set
"
is true, then
Let
setter be the result of calling the [[Get]] internal method
of Obj with argument "set
".
If IsCallable(setter) is false and setter is not undefined, then throw a TypeError exception.
Set the [[Set]] field of desc to setter.
If either desc.[[Get]] or desc.[[Set]] are present, then
If either desc.[[Value]] or desc.[[Writable]] are present, then throw a TypeError exception.
Return desc.
The Lexical Environment and Environment Record types are used to explain the behaviour of name resolution in nested functions and blocks. These types and the operations upon them are defined in Clause 10.
In the following algorithm descriptions, assume O is a native ECMAScript object, P is a String, Desc is a Property Description record, and Throw is a Boolean flag.
When the [[GetOwnProperty]] internal method of O is called with property name P, the following steps are taken:
If O doesn’t have an own property with name P, return undefined.
Let D be a newly created Property Descriptor with no fields.
Let X be O’s own property named 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.
However, if O is a String object it has a more elaborate [[GetOwnProperty]] internal method defined in 15.5.5.2.
When the [[GetProperty]] internal method of O is called with property name P, the following steps are taken:
Let prop be the result of calling the [[GetOwnProperty]] internal method of O with property name P.
If prop is not undefined, return prop.
Let proto be the value of the [[Prototype]] internal property of O.
If proto is null, return undefined.
Return the result of calling the [[GetProperty]] internal method of proto with argument P.
When the [[Get]] internal method of O is called with property name P, the following steps are taken:
Let desc be the result of calling the [[GetProperty]] internal method of O with property name P.
If desc is undefined, return undefined.
If IsDataDescriptor(desc) is true, return desc.[[Value]].
Otherwise, IsAccessorDescriptor(desc) must be true so, let getter be desc.[[Get]].
If getter is undefined, return undefined.
Return the result calling the [[Call]] internal method of getter providing O as the this value and providing no arguments.
When the [[CanPut]] internal method of O is called with property name P, the following steps are taken:
Let desc be the result of calling the [[GetOwnProperty]] internal method of O with argument P.
If desc is not undefined, then
If IsAccessorDescriptor(desc) is true, then
If desc.[[Set]] is undefined, then return false.
Else return true.
Else, desc must be a DataDescriptor so return the value of desc.[[Writable]].
Let proto be the [[Prototype]] internal property of O.
If proto is null, then return the value of the [[Extensible]] internal property of O.
Let inherited be the result of calling the [[GetProperty]] internal method of proto with property name P.
If inherited is undefined, return the value of the [[Extensible]] internal property of O.
If IsAccessorDescriptor(inherited) is true, then
If inherited.[[Set]] is undefined, then return false.
Else return true.
Else, inherited must be a DataDescriptor
If the [[Extensible]] internal property of O is false, return false.
Else return the value of inherited.[[Writable]].
Host objects may define additional constraints upon [[Put]] operations. If possible, host objects should not allow [[Put]] operations in situations where this definition of [[CanPut]] returns false.
When the [[Put]] internal method of O is called with property P, value V, and Boolean flag Throw, the following steps are taken:
If the result of calling the [[CanPut]] internal method of O with argument P is false, then
If Throw is true, then throw a TypeError exception.
Else return.
Let ownDesc be the result of calling the [[GetOwnProperty]] internal method of O with argument P.
If IsDataDescriptor(ownDesc) is true, then
Let valueDesc be the Property Descriptor {[[Value]]: V}.
Call the [[DefineOwnProperty]] internal method of O passing P, valueDesc, and Throw as arguments.
Return.
Let desc be the result of calling the [[GetProperty]] internal method of O with argument P. This may be either an own or inherited accessor property descriptor or an inherited data property descriptor.
If IsAccessorDescriptor(desc) is true, then
Let setter be desc.[[Set]] which cannot be undefined.
Call the [[Call]] internal method of setter providing O as the this value and providing V as the sole argument.
Else, create a named data property named P on object O as follows
Let
newDesc be the Property Descriptor
{[[Value]]: V,
[[Writable]]: true, [[Enumerable]]: true,
[[Configurable]]: true}.
Call the [[DefineOwnProperty]] internal method of O passing P, newDesc, and Throw as arguments.
Return.
When the [[HasProperty]] internal method of O is called with property name P, the following steps are taken:
Let desc be the result of calling the [[GetProperty]] internal method of O with property name P.
If desc is undefined, then return false.
Else return true.
When the [[Delete]] internal method of O is called with property name P and the Boolean flag Throw, the following steps are taken:
Let desc be the result of calling the [[GetOwnProperty]] internal method of O with property name P.
If desc is undefined, then return true.
If desc.[[Configurable]] is true, then
Remove the own property with name P from O.
Return true.
Else if Throw, then throw a TypeError exception.
Return false.
When the [[DefaultValue]] internal method of O is called with hint String, the following steps are taken:
Let
toString be the result of calling the [[Get]] internal
method of object O with argument "toString
".
If IsCallable(toString) is true then,
Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list.
If str is a primitive value, return str.
Let
valueOf be the result of calling the [[Get]] internal method
of object O with argument "valueOf
".
If IsCallable(valueOf) is true then,
Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list.
If val is a primitive value, return val.
Throw a TypeError exception.
When the [[DefaultValue]] internal method of O is called with hint Number, the following steps are taken:
Let
valueOf be the result of calling the [[Get]] internal method
of object O with argument "valueOf
".
If IsCallable(valueOf) is true then,
Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list.
If val is a primitive value, return val.
Let
toString be the result of calling the [[Get]] internal
method of object O with argument "toString
".
If IsCallable(toString) is true then,
Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list.
If str is a primitive value, return str.
Throw a TypeError exception.
When the [[DefaultValue]] internal method of O is called with no hint, then it behaves as if the hint were Number, unless O is a Date object (see 15.9.6), in which case it behaves as if the hint were String.
The above specification of [[DefaultValue]] for native objects can return only primitive values. If a host object implements its own [[DefaultValue]] internal method, it must ensure that its [[DefaultValue]] internal method can return only primitive values.
In the following algorithm, the term “Reject” means “If Throw is true, then throw a TypeError exception, otherwise return false”. The algorithm contains steps that test various fields of the Property Descriptor Desc for specific values. The fields that are tested in this manner need not actually exist in Desc. If a field is absent then its value is considered to be false.
When the [[DefineOwnProperty]] internal method of O is called with property name P, property descriptor Desc, and Boolean flag Throw, the following steps are taken:
Let current be the result of calling the [[GetOwnProperty]] internal method of O with property name P.
Let extensible be the value of the [[Extensible]] internal property of O.
If current is undefined and extensible is false, then Reject.
If current is undefined and extensible is true, then
If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then
Create an own data property named P of object O whose [[Value]], [[Writable]], [[Enumerable]] and [[Configurable]] attribute values are described by Desc. If the value of an attribute field of Desc is absent, the attribute of the newly created property is set to its default value.
Else, Desc must be an accessor Property Descriptor so,
Create an own accessor property named P of object O whose [[Get]], [[Set]], [[Enumerable]] and [[Configurable]] attribute values are described by Desc. If the value of an attribute field of Desc is absent, the attribute of the newly created property is set to its default value.
Return true.
Return true, if every field in Desc is absent.
Return true, if every field in Desc also occurs in current and the value of every field in Desc is the same value as the corresponding field in current when compared using the SameValue algorithm (9.12).
If the [[Configurable]] field of current is false then
If IsGenericDescriptor(Desc) is true, then no further validation is required.
Else, if IsDataDescriptor(current) and IsDataDescriptor(Desc) have different results, then
Reject, if the [[Configurable]] field of current is false.
If IsDataDescriptor(current) is true, then
Convert the property named P of object O from a data property to an accessor property. Preserve the existing values of the converted property’s [[Configurable]] and [[Enumerable]] attributes and set the rest of the property’s attributes to their default values.
Else,
Convert the property named P of object O from an accessor property to a data property. Preserve the existing values of the converted property’s [[Configurable]] and [[Enumerable]] attributes and set the rest of the property’s attributes to their default values.
Else, if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both true, then
If the [[Configurable]] field of current is false, then
else, the [[Configurable]] field of current is true, so any change is acceptable.
Else, IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc) are both true so,
For each attribute field of Desc that is present, set the correspondingly named attribute of the property named P of object O to the value of the field.
Return true.
However, if O is an Array object, it has a more elaborate [[DefineOwnProperty]] internal method defined in 15.4.5.1.
NOTE Step 10.b allows any field of Desc to be different from the corresponding field of current if current’s [[Configurable]] field is true. This even permits changing the [[Value]] of a property whose [[Writable]] attribute is false. This is allowed because a true [[Configurable]] attribute would permit an equivalent sequence of calls where [[Writable]] is first set to true, a new [[Value]] is set, and then [[Writable]] is set to false.