8 Types
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.
8.1 The Undefined Type
The Undefined type has exactly one value, called
undefined. Any variable that has not been assigned a value
has the value
undefined.
8.2 The Null Type
The Null type has exactly one value, called
null.
8.3 The Boolean Type
The Boolean type represents a logical entity having two values, called
true and
false.
8.4 The String Type
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 normalized 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 Normalized Form C before the running program
© Ecma International 200928
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
Normalized Form C, string literals are guaranteed to be normalized (if source text is guaranteed to be normalized), as long
as they do not contain any Unicode escape sequences.
8.5 The Number Type
The Number type has exactly 18437736874454810627 (that is, 2
64−2
53+3) values, representing the doubleprecision
64-bit format IEEE 754 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic,
except that the 9007199254740990 (that is, 2
53−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, 2
64−2
53) 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, 2
64−2
53−2) finite nonzero values are of two kinds:
18428729675200069632 (that is, 2
64−2
54) of them are normalized, having the form
s × m × 2e
where s is +1 or −1,
m is a positive integer less than 2
53 but not less than 2
52, and
e is an integer ranging from
−1074 to 971, inclusive.
The remaining 9007199254740990 (that is, 2
53−2) values are denormalized, having the form
s × m × 2e
where s is +1 or −1,
m is a positive integer less than 2
52, and
e is −1074.
Note that all the positive and negative integers whose magnitude is no greater than 2
53 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 2
1024
(which is +1
× 2
53 ×
2
971) and −2
1024 (which is −1
× 2
53 × 2
971).
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 2
1024 and −2
1024 are considered to have even significands. Finally, if 2
1024 was chosen, replace it
with +
∞; if −2
1024 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.)
© Ecma International 200929

Some ECMAScript operators deal only with integers in the range −2
31 through 2
31−1, inclusive, or in the range
0 through 2
32−1, inclusive. These operators accept any value of the Number type but first convert each such
value to one of 2
32 integer values. See the descriptions of the ToInt32 and ToUint32 operators in 9.5 and 9.6,
respectively.
8.6 The Object Type
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.
8.6.1 Property Attributes
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
Table 5 — Attributes of a Named Data Property
| 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.
© Ecma International 200930
Table 6 — Attributes of a Named Accessor Property
| Attribute Name | Default Value | 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 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. |
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.
Table 7 — Default Attribute Values
| Attribute Name | Default Value |
| [[Value]] | Undefined |
| [[Get]] | Undefined |
| [[Set]] | Undefined |
| [[Writable]] | false |
| [[Enumerable]] | false |
| [[Configurable]] | false |
8.6.2 Object Internal Properties and Methods
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.
Table 8 summarizes the internal properties used by this specification that are applicable to all
ECMAScript objects. Table 9 summarizes 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
© Ecma International 200931

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.
Table 8 — Internal Properties Common to All Objects
| 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) → Undefined or Property Descriptor |
Returns the Property Descriptor of the named own property of this object, or undefined if absent. |
| [[GetProperty]] | SpecOp (propertyName) → Undefined or 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.
© Ecma International 200932
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.
© Ecma International 200933
Table 9 — Internal Properties Only Defined for Some Objects
| 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]] | SpecOp(a List of
any) → Object |
Creates an object. Invoked via the new operator. The arguments to the SpecOp are the arguments passed to the
new operator. Objects that implement this internal method are called constructors. |
| [[Call]] | SpecOp(any, a List
of any) → any or
Reference |
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]] | Lexical Environment | 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. |
8.7 The Reference Specification Type
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
© Ecma International 200934

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 userdefined
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:
8.7.1 GetValue (V)
- If Type(V) is not Reference, return V.
- 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.
8.7.2 PutValue (V, W)
1. If Type(V) is not Reference, throw a ReferenceError exception.
© Ecma International 200935
- 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.
8.8 The List Specification Type
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.
8.9 The Completion Specification Type
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.
© Ecma International 200936
8.10 The Property Descriptor and Property Identifier Specification Types
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:
8.10.1 IsAccessorDescriptor ( Desc )
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.
8.10.2 IsDataDescriptor ( Desc )
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.
8.10.3 IsGenericDescriptor ( Desc )
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.
© Ecma International 200937
8.10.4 FromPropertyDescriptor ( Desc )
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.
8.10.5 ToPropertyDescriptor ( 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.
© Ecma International 200938
8.11 The Lexical Environment and Environment Record Specification Types
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.
8.12 Algorithms for Object Internal Methods
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.
8.12.1 [[GetOwnProperty]] (P)
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.
8.12.2 [[GetProperty]] (P)
When the [[GetProperty]] internal method of
O is called with property name
P, the following steps are taken:
1. Let prop be the result of calling the [[GetOwnProperty]] internal method of O with property name P.
2. If prop is not undefined, return prop.
3. Let proto be the value of the [[Prototype]] internal property of O.
4. If proto is null, return undefined.
5. Return the result of calling the [[GetProperty]] internal method of proto with argument P.
8.12.3 [[Get]] (P)
When the [[Get]] internal method of O is called with property name P, the following steps are taken:
8. Let desc be the result of calling the [[GetProperty]] internal method of O with property name P.
9. If desc is undefined, return undefined.
10. If IsDataDescriptor(desc) is true, return desc.[[Value]].
11. Otherwise, IsAccessorDescriptor(desc) must be true so, let getter be desc.[[Get]].
12. If getter is undefined, return undefined.
13. Return the result calling the [[Call]] internal method of getter providing O as the this value and providing no
arguments.
8.12.4 [[CanPut]] (P)
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
© Ecma International 200939
-
-
- 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.
8.12.5 [[Put]] ( P, V, Throw )
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.
8.12.6 [[HasProperty]] (P)
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.
8.12.7 [[Delete]] (P, Throw)
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.
© Ecma International 200940
- Return true.
- Else if Throw, then throw a TypeError exception.
- Return false.
8.12.8 [[DefaultValue]] (hint)
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.
8.12.9 [[DefineOwnProperty]] (P, Desc, Throw)
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.
© Ecma International 200941
-
- 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
- Reject, if the [[Configurable]] field of Desc is true.
- Reject, if the [[Enumerable]] field of Desc is present and the [[Enumerable]] fields of current and
Desc are the Boolean negation of each other.
- 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
- Reject, if the [[Writable]] field of current is false and the [[Writable]] field of Desc is true.
- If the [[Writable]] field of current is false, then
- Reject, if the [[Value]] field of Desc is present and SameValue(Desc.[[Value]],
current.[[Value]]) is false.
- else, the [[Configurable]] field of current is true, so any change is acceptable.
- Else, IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc) are both true so,
- If the [[Configurable]] field of current is false, then
- Reject, if the [[Set]] field of Desc is present and SameValue(Desc.[[Set]], current.[[Set]]) is
false.
- Reject, if the [[Get]] field of Desc is present and SameValue(Desc.[[Get]], current.[[Get]])
is false.
- 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.
© Ecma International 200942