Object.prototype.toString()

Object.prototype.toString()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The toString()
method of Object
instances returns a string representing this object. This method is meant to be overridden by derived objects for custom type coercion logic.
Try it
const map = new Map();
console.log(map.toString());
// Expected output: "[object Map]"
Syntax
toString()
Parameters
By default toString()
takes no parameters. However, objects that inherit from Object
may override it with their own implementations that do take parameters. For example, the Number.prototype.toString()
and BigInt.prototype.toString()
methods take an optional radix
parameter.
Return value
A string representing the object.
Description
JavaScript calls the toString
method to convert an object to a primitive value. You rarely need to invoke the toString
method yourself; JavaScript automatically invokes it when encountering an object where a primitive value is expected.
This method is called in priority by string conversion, but numeric conversion and primitive conversion call valueOf()
in priority. However, because the base valueOf()
method returns an object, the toString()
method is usually called in the end, unless the object overrides valueOf()
. For example, +[1]
returns 1
, because its toString()
method returns "1"
, which is then converted to a number.
All objects that inherit from Object.prototype
(that is, all except null
-prototype objects) inherit the toString()
method. When you create a custom object, you can override toString()
to call a custom method, so that your custom object can be converted to a string value. Alternatively, you can add a [Symbol.toPrimitive]()
method, which allows even more control over the conversion process, and will always be preferred over valueOf
or toString
for any type conversion.
To use the base Object.prototype.toString()
with an object that has it overridden (or to invoke it on null
or undefined
), you need to call Function.prototype.call()
or Function.prototype.apply()
on it, passing the object you want to inspect as the first parameter (called thisArg
).
const arr = [1, 2, 3];
arr.toString(); // "1,2,3"
Object.prototype.toString.call(arr); // "[object Array]"
Object.prototype.toString()
returns "[object Type]"
, where Type
is the object type. If the object has a Symbol.toStringTag
property whose value is a string, that value will be used as the Type
. Many built-in objects, including Map
and Symbol
, have a Symbol.toStringTag
. Some objects predating ES6 do not have Symbol.toStringTag
, but have a special tag nonetheless. They include (the tag is the same as the type name given below):
The arguments
object returns "[object Arguments]"
. Everything else, including user-defined classes, unless with a custom Symbol.toStringTag
, will return "[object Object]"
.
Object.prototype.toString()
invoked on null
and undefined
returns [object Null]
and [object Undefined]
, respectively.
Examples
Overriding toString for custom objects
You can create a function to be called in place of the default toString()
method. The toString()
function you create should return a string value. If it returns an object and the method is called implicitly during type conversion, then its result is ignored and the value of a related method, valueOf()
, is used instead, or a TypeError
is thrown if none of these methods return a primitive.
The following code defines a Dog
class.
class Dog {
constructor(name, breed, color, sex) {
this.name = name;
this.breed = breed;
this.color = color;
this.sex = sex;
}
}
If you call the toString()
method, either explicitly or implicitly, on an instance of Dog
, it returns the default value inherited from Object
:
const theDog = new Dog("Gabby", "Lab", "chocolate", "female");
theDog.toString(); // "[object Object]"
`${theDog}`; // "[object Object]"
The following code overrides the default toString()
method. This method generates a string containing the name
, breed
, color
, and sex
of the object.
class Dog {
constructor(name, breed, color, sex) {
this.name = name;
this.breed = breed;
this.color = color;
this.sex = sex;
}
toString() {
return `Dog ${this.name} is a ${this.sex} ${this.color} ${this.breed}`;
}
}
With the preceding code in place, any time an instance of Dog
is used in a string context, JavaScript automatically calls the toString()
method.
const theDog = new Dog("Gabby", "Lab", "chocolate", "female");
`${theDog}`; // "Dog Gabby is a female chocolate Lab"
Using toString() to detect object class
toString()
can be used with every object and (by default) allows you to get its class.
const toString = Object.prototype.toString;
toString.call(new Date()); // [object Date]
toString.call(new String()); // [object String]
// Math has its Symbol.toStringTag
toString.call(Math); // [object Math]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
Using toString()
in this way is unreliable; objects can change the behavior of Object.prototype.toString()
by defining a Symbol.toStringTag
property, leading to unexpected results. For example:
const myDate = new Date();
Object.prototype.toString.call(myDate); // [object Date]
myDate[Symbol.toStringTag] = "myDate";
Object.prototype.toString.call(myDate); // [object myDate]
Date.prototype[Symbol.toStringTag] = "prototype polluted";
Object.prototype.toString.call(new Date()); // [object prototype polluted]
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-object.prototype.tostring |


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/operators/object_initializer/index.md

# Original Wiki contributors
sharq
Muhammad_Ali
Anonymous
fscholz
wbamberg
jinbeomhong
Zearin_Galaurum
muhammadghazali
sideshowbarker
MadaraUchiha
lmcarreiro
JonathanPool
torazaburo
jameshkramer
martinczerwi
bergus
zbjornson
nmve
chrisjimallen
kdex
roryokane
rwaldron
stevemasta34
kayellpeee
bouzlibop
hovosanoyan
stevemao
Olson.dev
Llbe
jpmedley
Robg1
Philip Chee
Waldo
tschneidereit


Intl.ListFormat

Intl.ListFormat
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021.
The Intl.ListFormat
object enables language-sensitive list formatting.
Try it
const vehicles = ["Motorcycle", "Bus", "Car"];
const formatter = new Intl.ListFormat("en", {
style: "long",
type: "conjunction",
});
console.log(formatter.format(vehicles));
// Expected output: "Motorcycle, Bus, and Car"
const formatter2 = new Intl.ListFormat("de", {
style: "short",
type: "disjunction",
});
console.log(formatter2.format(vehicles));
// Expected output: "Motorcycle, Bus oder Car"
const formatter3 = new Intl.ListFormat("en", { style: "narrow", type: "unit" });
console.log(formatter3.format(vehicles));
// Expected output: "Motorcycle Bus Car"
Constructor
Intl.ListFormat()
-
Creates a new
Intl.ListFormat
object.
Static methods
Intl.ListFormat.supportedLocalesOf()
-
Returns an array containing those of the provided locales that are supported without having to fall back to the runtime's default locale.
Instance properties
These properties are defined on Intl.ListFormat.prototype
and shared by all Intl.ListFormat
instances.
Intl.ListFormat.prototype.constructor
-
The constructor function that created the instance object. For
Intl.ListFormat
instances, the initial value is theIntl.ListFormat
constructor. Intl.ListFormat.prototype[Symbol.toStringTag]
-
The initial value of the
[Symbol.toStringTag]
property is the string"Intl.ListFormat"
. This property is used inObject.prototype.toString()
.
Instance methods
Intl.ListFormat.prototype.format()
-
Returns a language-specific formatted string representing the elements of the list.
Intl.ListFormat.prototype.formatToParts()
-
Returns an array of objects representing the different components that can be used to format a list of values in a locale-aware fashion.
Intl.ListFormat.prototype.resolvedOptions()
-
Returns a new object with properties reflecting the locale and style formatting options computed during the construction of the current
Intl.ListFormat
object.
Examples
Using format
The following example shows how to create a List formatter using the English language.
const list = ["Motorcycle", "Bus", "Car"];
console.log(
new Intl.ListFormat("en-GB", { style: "long", type: "conjunction" }).format(
list,
),
);
// Motorcycle, Bus and Car
console.log(
new Intl.ListFormat("en-GB", { style: "short", type: "disjunction" }).format(
list,
),
);
// Motorcycle, Bus or Car
console.log(
new Intl.ListFormat("en-GB", { style: "narrow", type: "unit" }).format(list),
);
// Motorcycle Bus Car
Using formatToParts
The following example shows how to create a List formatter returning formatted parts
const list = ["Motorcycle", "Bus", "Car"];
console.log(
new Intl.ListFormat("en-GB", {
style: "long",
type: "conjunction",
}).formatToParts(list),
);
// [ { "type": "element", "value": "Motorcycle" },
// { "type": "literal", "value": ", " },
// { "type": "element", "value": "Bus" },
// { "type": "literal", "value": ", and " },
// { "type": "element", "value": "Car" } ];
Specifications
| Specification |
|---|
| ECMAScript® 2026 Internationalization API Specification # listformat-objects |


Temporal.Duration.prototype.minutes

Temporal.Duration.prototype.minutes
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
The minutes
accessor property of Temporal.Duration
instances returns an integer representing the number of minutes in the duration.
Unless the duration is balanced, you cannot assume the range of this value, but you can know its sign by checking the duration's sign
property. If it is balanced to a unit above minutes, the minutes
absolute value will be between 0 and 59, inclusive.
The set accessor of minutes
is undefined
. You cannot change this property directly. Use the with()
method to create a new Temporal.Duration
object with the desired new value.
Examples
Using minutes
js
const d1 = Temporal.Duration.from({ hours: 1, minutes: 30 });
const d2 = Temporal.Duration.from({ hours: -1, minutes: -30 });
const d3 = Temporal.Duration.from({ hours: 1 });
const d4 = Temporal.Duration.from({ minutes: 60 });
console.log(d1.minutes); // 1
console.log(d2.minutes); // -1
console.log(d3.minutes); // 0
console.log(d4.minutes); // 60
// Balance d4
const d4Balanced = d4.round({ largestUnit: "hours" });
console.log(d4Balanced.minutes); // 0
console.log(d4Balanced.hours); // 1
Specifications
| Specification |
|---|
| Temporal # sec-get-temporal.duration.prototype.minutes |
Browser compatibility
See also
Temporal.Duration
Temporal.Duration.prototype.years
Temporal.Duration.prototype.months
Temporal.Duration.prototype.weeks
Temporal.Duration.prototype.days
Temporal.Duration.prototype.hours
Temporal.Duration.prototype.seconds
Temporal.Duration.prototype.milliseconds
Temporal.Duration.prototype.microseconds
Temporal.Duration.prototype.nanoseconds


Strict equality (===)

Strict equality (===)
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The strict equality (===
) operator checks whether its two operands are
equal, returning a Boolean result. Unlike the equality operator,
the strict equality operator always considers operands of different types to be
different.
Try it
console.log(1 === 1);
// Expected output: true
console.log("hello" === "hello");
// Expected output: true
console.log("1" === 1);
// Expected output: false
console.log(0 === false);
// Expected output: false
Syntax
js
x === y
Description
The strict equality operators (===
and !==
) provide the IsStrictlyEqual semantic.
- If the operands are of different types, return
false
. - If both operands are objects, return
true
only if they refer to the same object. - If both operands are
null
or both operands areundefined
, returntrue
. - If either operand is
NaN
, returnfalse
. - Otherwise, compare the two operand's values:
- Numbers must have the same numeric values.
+0
and-0
are considered to be the same value. - Strings must have the same characters in the same order.
- Booleans must be both
true
or bothfalse
.
- Numbers must have the same numeric values.
The most notable difference between this operator and the equality
(==
) operator is that if the operands are of different types, the
==
operator attempts to convert them to the same type before comparing.
Examples
Comparing operands of the same type
js
"hello" === "hello"; // true
"hello" === "hola"; // false
3 === 3; // true
3 === 4; // false
true === true; // true
true === false; // false
null === null; // true
Comparing operands of different types
js
"3" === 3; // false
true === 1; // false
null === undefined; // false
3 === new Number(3); // false
Comparing objects
js
const object1 = {
key: "value",
};
const object2 = {
key: "value",
};
console.log(object1 === object2); // false
console.log(object1 === object1); // true
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-equality-operators |


Object.prototype.valueOf()

Object.prototype.valueOf()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The valueOf()
method of Object
instances converts the this
value to an object. This method is meant to be overridden by derived objects for custom type conversion logic.
Try it
function MyNumberType(n) {
this.number = n;
}
MyNumberType.prototype.valueOf = function () {
return this.number;
};
const object = new MyNumberType(4);
console.log(object + 3);
// Expected output: 7
Syntax
valueOf()
Parameters
None.
Return value
The this
value, converted to an object.
Note:
In order for valueOf
to be useful during type conversion, it must return a primitive. Because all primitive types have their own valueOf()
methods, calling primitiveValue.valueOf()
generally does not invoke Object.prototype.valueOf()
.
Description
JavaScript calls the valueOf
method to convert an object to a primitive value. You rarely need to invoke the valueOf
method yourself; JavaScript automatically invokes it when encountering an object where a primitive value is expected.
This method is called in priority by numeric conversion and primitive conversion, but string conversion calls toString()
in priority, and toString()
is very likely to return a string value (even for the Object.prototype.toString()
base implementation), so valueOf()
is usually not called in this case.
All objects that inherit from Object.prototype
(that is, all except null
-prototype objects) inherit the toString()
method. The Object.prototype.valueOf()
base implementation is deliberately useless: by returning an object, its return value will never be used by any primitive conversion algorithm. Many built-in objects override this method to return an appropriate primitive value. When you create a custom object, you can override valueOf()
to call a custom method, so that your custom object can be converted to a primitive value. Generally, valueOf()
is used to return a value that is most meaningful for the object — unlike toString()
, it does not need to be a string. Alternatively, you can add a [Symbol.toPrimitive]()
method, which allows even more control over the conversion process, and will always be preferred over valueOf
or toString
for any type conversion.
Examples
Using valueOf()
The base valueOf()
method returns the this
value itself, converted to an object if it isn't already. Therefore its return value will never be used by any primitive conversion algorithm.
const obj = { foo: 1 };
console.log(obj.valueOf() === obj); // true
console.log(Object.prototype.valueOf.call("primitive"));
// [String: 'primitive'] (a wrapper object)
Overriding valueOf for custom objects
You can create a function to be called in place of the default valueOf
method. Your function should take no arguments, since it won't be passed any when called during type conversion.
For example, you can add a valueOf
method to your custom class Box
.
class Box {
#value;
constructor(value) {
this.#value = value;
}
valueOf() {
return this.#value;
}
}
With the preceding code in place, any time an object of type Box
is used in a context where it is to be represented as a primitive value (but not specifically a string), JavaScript automatically calls the function defined in the preceding code.
const box = new Box(123);
console.log(box + 456); // 579
console.log(box == 123); // true
An object's valueOf
method is usually invoked by JavaScript, but you can invoke it yourself as follows:
box.valueOf();
Using unary plus on objects
Unary plus performs number coercion on its operand, which, for most objects without [Symbol.toPrimitive]()
, means calling its valueOf()
. However, if the object doesn't have a custom valueOf()
method, the base implementation will cause valueOf()
to be ignored and the return value of toString()
to be used instead.
+new Date(); // the current timestamp; same as new Date().getTime()
+{}; // NaN (toString() returns "[object Object]")
+[]; // 0 (toString() returns an empty string list)
+[1]; // 1 (toString() returns "1")
+[1, 2]; // NaN (toString() returns "1,2")
+new Set([1]); // NaN (toString() returns "[object Set]")
+{ valueOf: () => 42 }; // 42
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-object.prototype.valueof |


Temporal.Duration.prototype.months

Temporal.Duration.prototype.months
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
The months
accessor property of Temporal.Duration
instances returns an integer representing the number of months in the duration.
Unless the duration is balanced, you cannot assume the range of this value, but you can know its sign by checking the duration's sign
property. If it is balanced to a unit above months, the months
absolute value's range depends on the calendar (how many months are in a year).
The set accessor of months
is undefined
. You cannot change this property directly. Use the with()
method to create a new Temporal.Duration
object with the desired new value.
Examples
Using months
js
const d1 = Temporal.Duration.from({ years: 1, months: 1 });
const d2 = Temporal.Duration.from({ years: -1, months: -1 });
const d3 = Temporal.Duration.from({ years: 1 });
const d4 = Temporal.Duration.from({ months: 12 });
console.log(d1.months); // 1
console.log(d2.months); // -1
console.log(d3.months); // 0
console.log(d4.months); // 12
// Balance d4
const d4Balanced = d4.round({
largestUnit: "years",
relativeTo: Temporal.PlainDate.from("2021-01-01"), // ISO 8601 calendar
});
console.log(d4Balanced.months); // 0
console.log(d4Balanced.years); // 1
Specifications
| Specification |
|---|
| Temporal # sec-get-temporal.duration.prototype.months |
Browser compatibility
See also
Temporal.Duration
Temporal.Duration.prototype.years
Temporal.Duration.prototype.weeks
Temporal.Duration.prototype.days
Temporal.Duration.prototype.hours
Temporal.Duration.prototype.minutes
Temporal.Duration.prototype.seconds
Temporal.Duration.prototype.milliseconds
Temporal.Duration.prototype.microseconds
Temporal.Duration.prototype.nanoseconds


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/errors/malformed_uri/index.md

# Original Wiki contributors
fscholz
PatrickKettner
thornedlove


Temporal.Now

Temporal.Now
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
The Temporal.Now
namespace object contains static methods for getting the current time in various formats.
Description
Unlike most global objects, Temporal.Now
is not a constructor. You cannot use it with the new
operator or invoke the Temporal.Now
object as a function. All properties and methods of Temporal.Now
are static (just like the Math
object).
Most fundamentally, the system time is returned by the operating system as a time since the Unix epoch (usually millisecond-level precision, but might be nanosecond-level too). Temporal.Now.instant()
returns this time as a Temporal.Instant
object.
An instant can be interpreted in a time zone (which is the system time zone Temporal.Now.timeZoneId()
by default) in the same fashion as Temporal.Instant.prototype.toZonedDateTimeISO()
. To get a Temporal.ZonedDateTime
object, you can use Temporal.Now.zonedDateTimeISO()
. You can also get different parts of the date and time, using Temporal.Now.plainDateISO()
, Temporal.Now.plainTimeISO()
, and Temporal.Now.plainDateTimeISO()
.
For example, if the computer is set to the time zone "America/New_York", Temporal.Now.zonedDateTimeISO()
returns a zoned date-time like: 2021-08-01T10:40:12.345-04:00[America/New_York]
. In this case, Temporal.Now.plainTimeISO()
would return the time part of this zoned date-time: 10:40:12.345
. However, if you call Temporal.Now.plainTimeISO("UTC")
, it returns the time part of the zoned date-time in the UTC time zone: 14:40:12.345
. This is especially useful for cross-system communication where the other end may be expecting the time in a different time zone.
Reduced time precision
To offer protection against timing attacks and fingerprinting, the precision of the Temporal.Now
functions might get rounded depending on browser settings. In Firefox, the privacy.reduceTimerPrecision
preference is enabled by default and defaults to 2ms. You can also enable privacy.resistFingerprinting
, in which case the precision will be 100ms or the value of privacy.resistFingerprinting.reduceTimerPrecision.microseconds
, whichever is larger.
For example, with reduced time precision, the result of Temporal.Now.instant().epochMilliseconds
will always be a multiple of 2, or a multiple of 100 (or privacy.resistFingerprinting.reduceTimerPrecision.microseconds
) with privacy.resistFingerprinting
enabled.
// reduced time precision (2ms) in Firefox 60
Temporal.Now.instant().epochMilliseconds;
// Might be:
// 1519211809934
// 1519211810362
// 1519211811670
// …
// reduced time precision with `privacy.resistFingerprinting` enabled
Temporal.Now.instant().epochMilliseconds;
// Might be:
// 1519129853500
// 1519129858900
// 1519129864400
// …
Static properties
Temporal.Now[Symbol.toStringTag]
-
The initial value of the
[Symbol.toStringTag]
property is the string"Temporal.Now"
. This property is used inObject.prototype.toString()
.
Static methods
Temporal.Now.instant()
-
Returns the current time as a
Temporal.Instant
object. Temporal.Now.plainDateISO()
-
Returns the current date as a
Temporal.PlainDate
object, in the ISO 8601 calendar and the specified time zone. Temporal.Now.plainDateTimeISO()
-
Returns the current date and time as a
Temporal.PlainDateTime
object, in the ISO 8601 calendar and the specified time zone. Temporal.Now.plainTimeISO()
-
Returns the current time as a
Temporal.PlainTime
object, in the specified time zone. Temporal.Now.timeZoneId()
-
Returns a time zone identifier representing the system's current time zone.
Temporal.Now.zonedDateTimeISO()
-
Returns the current date and time as a
Temporal.ZonedDateTime
object, in the ISO 8601 calendar and the specified time zone.
Specifications
| Specification |
|---|
| Temporal # sec-temporal-now-object |


JSON.stringify()

JSON.stringify()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The JSON.stringify()
static method converts a JavaScript value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.
Try it
console.log(JSON.stringify({ x: 5, y: 6 }));
// Expected output: '{"x":5,"y":6}'
console.log(
JSON.stringify([new Number(3), new String("false"), new Boolean(false)]),
);
// Expected output: '[3,"false",false]'
console.log(JSON.stringify({ x: [10, undefined, function () {}, Symbol("")] }));
// Expected output: '{"x":[10,null,null,null]}'
console.log(JSON.stringify(new Date(2006, 0, 2, 15, 4, 5)));
// Expected output: '"2006-01-02T15:04:05.000Z"'
Syntax
JSON.stringify(value)
JSON.stringify(value, replacer)
JSON.stringify(value, replacer, space)
Parameters
value
-
The value to convert to a JSON string.
replacer
Optional-
A function that alters the behavior of the stringification process, or an array of strings and numbers that specifies properties of
value
to be included in the output. Ifreplacer
is an array, all elements in this array that are not strings or numbers (either primitives or wrapper objects), includingSymbol
values, are completely ignored. Ifreplacer
is anything other than a function or an array (e.g.,null
or not provided), all string-keyed properties of the object are included in the resulting JSON string. space
Optional-
A string or number that's used to insert white space (including indentation, line break characters, etc.) into the output JSON string for readability purposes.
If this is a number, it indicates the number of space characters to be used as indentation, clamped to 10 (that is, any number greater than
10
is treated as if it were10
). Values less than 1 indicate that no space should be used.If this is a string, the string (or the first 10 characters of the string, if it's longer than that) is inserted before every nested object or array.
If
space
is anything other than a string or number (can be either a primitive or a wrapper object) — for example, isnull
or not provided — no white space is used.
Return value
A JSON string representing the given value, or undefined.
Exceptions
Description
JSON.stringify()
converts a value to the JSON notation that the value represents. Values are stringified in the following manner:
Boolean
,Number
,String
, andBigInt
(obtainable viaObject()
) objects are converted to the corresponding primitive values during stringification, in accordance with the traditional conversion semantics.Symbol
objects (obtainable viaObject()
) are treated as plain objects.- Attempting to serialize
BigInt
values will throw. However, if the BigInt has atoJSON()
method (through monkey patching:BigInt.prototype.toJSON = ...
), that method can provide the serialization result. This constraint ensures that a proper serialization (and, very likely, its accompanying deserialization) behavior is always explicitly provided by the user. undefined
,Function
, andSymbol
values are not valid JSON values. If any such values are encountered during conversion, they are either omitted (when found in an object) or changed tonull
(when found in an array).JSON.stringify()
can returnundefined
when passing in "pure" values likeJSON.stringify(() => {})
orJSON.stringify(undefined)
.- The numbers
Infinity
andNaN
, as well as the valuenull
, are all considerednull
. (But unlike the values in the previous point, they would never be omitted.) - Arrays are serialized as arrays (enclosed by square brackets). Only array indices between 0 and
length - 1
(inclusive) are serialized; other properties are ignored. - The special raw JSON object created with
JSON.rawJSON()
is serialized as the raw JSON text it contains (by accessing itsrawJSON
property). - For other objects:
-
All
Symbol
-keyed properties will be completely ignored, even when using thereplacer
parameter. -
If the value has a
toJSON()
method, it's responsible to define what data will be serialized. Instead of the object being serialized, the value returned by thetoJSON()
method when called will be serialized.JSON.stringify()
callstoJSON
with one parameter, thekey
, which has the same semantic as thekey
parameter of thereplacer
function:- if this object is a property value, the property name
- if it is in an array, the index in the array, as a string
- if
JSON.stringify()
was directly called on this object, an empty string
All
Temporal
objects implement thetoJSON()
method, which returns a string (the same as callingtoString()
). Thus, they will be serialized as strings. Similarly,Date
objects implementtoJSON()
, which returns the same astoISOString()
. -
Only enumerable own properties are visited. This means
Map
,Set
, etc. will become"{}"
. You can use thereplacer
parameter to serialize them to something more useful.Properties are visited using the same algorithm as
Object.keys()
, which has a well-defined order and is stable across implementations. For example,JSON.stringify
on the same object will always produce the same string, andJSON.parse(JSON.stringify(obj))
would produce an object with the same key ordering as the original (assuming the object is completely JSON-serializable).
-
The replacer parameter
The replacer
parameter can be either a function or an array.
As an array, its elements indicate the names of the properties in the object that should be included in the resulting JSON string. Only string and number values are taken into account; symbol keys are ignored.
As a function, it takes two parameters: the key
and the value
being stringified. The object in which the key was found is provided as the replacer
's this
context.
The replacer
function is called for the initial object being stringified as well, in which case the key
is an empty string (""
). It is then called for each property on the object or array being stringified. Array indices will be provided in its string form as key
. The current property value will be replaced with the replacer
's return value for stringification. This means:
- If you return a number, string, boolean, or
null
, that value is directly serialized and used as the property's value. (Returning a BigInt will throw as well.) - If you return a
Function
,Symbol
, orundefined
, the property is not included in the output. - If you return any other object, the object is recursively stringified, calling the
replacer
function on each property.
Note:
When parsing JSON generated with replacer
functions, you would likely want to use the reviver
parameter to perform the reverse operation.
Typically, array elements' index would never shift (even when the element is an invalid value like a function, it will become null
instead of omitted). Using the replacer
function allows you to control the order of the array elements by returning a different array.
The space parameter
The space
parameter may be used to control spacing in the final string.
- If it is a number, successive levels in the stringification will each be indented by this many space characters.
- If it is a string, successive levels will be indented by this string.
Each level of indentation will never be longer than 10. Number values of space
are clamped to 10, and string values are truncated to 10 characters.
Examples
Using JSON.stringify
JSON.stringify({}); // '{}'
JSON.stringify(true); // 'true'
JSON.stringify("foo"); // '"foo"'
JSON.stringify([1, "false", false]); // '[1,"false",false]'
JSON.stringify([NaN, null, Infinity]); // '[null,null,null]'
JSON.stringify({ x: 5 }); // '{"x":5}'
JSON.stringify(new Date(1906, 0, 2, 15, 4, 5));
// '"1906-01-02T15:04:05.000Z"'
JSON.stringify({ x: 5, y: 6 });
// '{"x":5,"y":6}'
JSON.stringify([new Number(3), new String("false"), new Boolean(false)]);
// '[3,"false",false]'
// String-keyed array elements are not enumerable and make no sense in JSON
const a = ["foo", "bar"];
a["baz"] = "quux"; // a: [ 0: 'foo', 1: 'bar', baz: 'quux' ]
JSON.stringify(a);
// '["foo","bar"]'
JSON.stringify({ x: [10, undefined, function () {}, Symbol("")] });
// '{"x":[10,null,null,null]}'
// Standard data structures
JSON.stringify([
new Set([1]),
new Map([[1, 2]]),
new WeakSet([{ a: 1 }]),
new WeakMap([[{ a: 1 }, 2]]),
]);
// '[{},{},{},{}]'
// TypedArray
JSON.stringify([new Int8Array([1]), new Int16Array([1]), new Int32Array([1])]);
// '[{"0":1},{"0":1},{"0":1}]'
JSON.stringify([
new Uint8Array([1]),
new Uint8ClampedArray([1]),
new Uint16Array([1]),
new Uint32Array([1]),
]);
// '[{"0":1},{"0":1},{"0":1},{"0":1}]'
JSON.stringify([new Float32Array([1]), new Float64Array([1])]);
// '[{"0":1},{"0":1}]'
// toJSON()
JSON.stringify({
x: 5,
y: 6,
toJSON() {
return this.x + this.y;
},
});
// '11'
// Symbols:
JSON.stringify({ x: undefined, y: Object, z: Symbol("") });
// '{}'
JSON.stringify({ [Symbol("foo")]: "foo" });
// '{}'
JSON.stringify({ [Symbol.for("foo")]: "foo" }, [Symbol.for("foo")]);
// '{}'
JSON.stringify({ [Symbol.for("foo")]: "foo" }, (k, v) => {
if (typeof k === "symbol") {
return "a symbol";
}
});
// undefined
// Non-enumerable properties:
JSON.stringify(
Object.create(null, {
x: { value: "x", enumerable: false },
y: { value: "y", enumerable: true },
}),
);
// '{"y":"y"}'
// BigInt values throw
JSON.stringify({ x: 2n });
// TypeError: BigInt value can't be serialized in JSON
Using a function as replacer
function replacer(key, value) {
// Filtering out properties
if (typeof value === "string") {
return undefined;
}
return value;
}
const foo = {
foundation: "Mozilla",
model: "box",
week: 45,
transport: "car",
month: 7,
};
JSON.stringify(foo, replacer);
// '{"week":45,"month":7}'
If you wish the replacer
to distinguish an initial object from a key with an empty string property (since both would give the empty string as key and potentially an object as value), you will have to keep track of the iteration count (if it is beyond the first iteration, it is a genuine empty string key).
function makeReplacer() {
let isInitial = true;
return (key, value) => {
if (isInitial) {
isInitial = false;
return value;
}
if (key === "") {
// Omit all properties with name "" (except the initial object)
return undefined;
}
return value;
};
}
const replacer = makeReplacer();
console.log(JSON.stringify({ "": 1, b: 2 }, replacer)); // "{"b":2}"
Using an array as replacer
const foo = {
foundation: "Mozilla",
model: "box",
week: 45,
transport: "car",
month: 7,
};
JSON.stringify(foo, ["week", "month"]);
// '{"week":45,"month":7}', only keep "week" and "month" properties
Using the space parameter
Indent the output with one space:
console.log(JSON.stringify({ a: 2 }, null, " "));
/*
{
"a": 2
}
*/
Using a tab character mimics standard pretty-print appearance:
console.log(JSON.stringify({ uno: 1, dos: 2 }, null, "\t"));
/*
{
"uno": 1,
"dos": 2
}
*/
toJSON() behavior
Defining toJSON()
for an object allows overriding its serialization behavior.
const obj = {
data: "data",
toJSON(key) {
return key ? `Now I am a nested object under key '${key}'` : this;
},
};
JSON.stringify(obj);
// '{"data":"data"}'
JSON.stringify({ obj });
// '{"obj":"Now I am a nested object under key 'obj'"}'
JSON.stringify([obj]);
// '["Now I am a nested object under key '0'"]'
Issue with serializing circular references
Since the JSON format doesn't support object references (although an IETF draft exists), a TypeError
will be thrown if one attempts to encode an object with circular references.
const circularReference = {};
circularReference.myself = circularReference;
// Serializing circular references throws "TypeError: cyclic object value"
JSON.stringify(circularReference);
To serialize circular references, you can use a library that supports them (e.g., cycle.js by Douglas Crockford) or implement a solution yourself, which will require finding and replacing (or removing) the cyclic references by serializable values.
If you are using JSON.stringify()
to deep-copy an object, you may instead want to use structuredClone()
, which supports circular references. JavaScript engine APIs for binary serialization, such as v8.serialize()
, also support circular references.
Using JSON.stringify() with localStorage
In a case where you want to store an object created by your user and allow it to be restored even after the browser has been closed, the following example is a model for the applicability of JSON.stringify()
:
// Creating an example of JSON
const session = {
screens: [],
state: true,
};
session.screens.push({ name: "screenA", width: 450, height: 250 });
session.screens.push({ name: "screenB", width: 650, height: 350 });
session.screens.push({ name: "screenC", width: 750, height: 120 });
session.screens.push({ name: "screenD", width: 250, height: 60 });
session.screens.push({ name: "screenE", width: 390, height: 120 });
session.screens.push({ name: "screenF", width: 1240, height: 650 });
// Converting the JSON string with JSON.stringify()
// then saving with localStorage in the name of session
localStorage.setItem("session", JSON.stringify(session));
// Example of how to transform the String generated through
// JSON.stringify() and saved in localStorage in JSON object again
const restoredSession = JSON.parse(localStorage.getItem("session"));
// Now restoredSession variable contains the object that was saved
// in localStorage
console.log(restoredSession);
Well-formed JSON.stringify()
Engines implementing the well-formed JSON.stringify specification will stringify lone surrogates (any code point from U+D800 to U+DFFF) using Unicode escape sequences rather than literally (outputting lone surrogates). Before this change, such strings could not be encoded in valid UTF-8 or UTF-16:
JSON.stringify("\uD800"); // '"�"'
But with this change JSON.stringify()
represents lone surrogates using JSON escape sequences that can be encoded in valid UTF-8 or UTF-16:
JSON.stringify("\uD800"); // '"\\ud800"'
This change should be backwards-compatible as long as you pass the result of JSON.stringify()
to APIs such as JSON.parse()
that will accept any valid JSON text, because they will treat Unicode escapes of lone surrogates as identical to the lone surrogates themselves. Only if you are directly interpreting the result of JSON.stringify()
do you need to carefully handle JSON.stringify()
's two possible encodings of these code points.
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-json.stringify |


Object.prototype.propertyIsEnumerable()

Object.prototype.propertyIsEnumerable()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The propertyIsEnumerable()
method of Object
instances returns a boolean indicating whether the specified property is this object's enumerable own property.
Try it
const object = {};
const array = [];
object.foo = 42;
array[0] = 42;
console.log(object.propertyIsEnumerable("foo"));
// Expected output: true
console.log(array.propertyIsEnumerable(0));
// Expected output: true
console.log(array.propertyIsEnumerable("length"));
// Expected output: false
Syntax
propertyIsEnumerable(prop)
Parameters
Return value
A boolean value indicating whether the specified property is enumerable and is the object's own property.
Description
All objects that inherit from Object.prototype
(that is, all except null
-prototype objects) inherit the propertyIsEnumerable()
method. This method determines if the specified property, string or symbol, is an enumerable own property of the object. If the object does not have the specified property, this method returns false
.
This method is equivalent to Object.getOwnPropertyDescriptor(obj, prop)?.enumerable ?? false
.
Examples
Using propertyIsEnumerable()
The following example shows the use of propertyIsEnumerable()
on objects and arrays.
const o = {};
const a = [];
o.prop = "is enumerable";
a[0] = "is enumerable";
o.propertyIsEnumerable("prop"); // true
a.propertyIsEnumerable(0); // true
User-defined vs. built-in objects
Most built-in properties are non-enumerable by default, while user-created object properties are often enumerable, unless explicitly designated otherwise.
const a = ["is enumerable"];
a.propertyIsEnumerable(0); // true
a.propertyIsEnumerable("length"); // false
Math.propertyIsEnumerable("random"); // false
globalThis.propertyIsEnumerable("Math"); // false
Direct vs. inherited properties
Only enumerable own properties cause propertyIsEnumerable()
to return true
, although all enumerable properties, including inherited ones, are visited by the for...in
loop.
const o1 = {
enumerableInherited: "is enumerable",
};
Object.defineProperty(o1, "nonEnumerableInherited", {
value: "is non-enumerable",
enumerable: false,
});
const o2 = {
// o1 is the prototype of o2
__proto__: o1,
enumerableOwn: "is enumerable",
};
Object.defineProperty(o2, "nonEnumerableOwn", {
value: "is non-enumerable",
enumerable: false,
});
o2.propertyIsEnumerable("enumerableInherited"); // false
o2.propertyIsEnumerable("nonEnumerableInherited"); // false
o2.propertyIsEnumerable("enumerableOwn"); // true
o2.propertyIsEnumerable("nonEnumerableOwn"); // false
Testing symbol properties
Symbol
properties are also supported by propertyIsEnumerable()
. Note that most enumeration methods only visit string properties; enumerability of symbol properties is only useful when using Object.assign()
or spread syntax. For more information, see Enumerability and ownership of properties.
const sym = Symbol("enumerable");
const sym2 = Symbol("non-enumerable");
const o = {
[sym]: "is enumerable",
};
Object.defineProperty(o, sym2, {
value: "is non-enumerable",
enumerable: false,
});
o.propertyIsEnumerable(sym); // true
o.propertyIsEnumerable(sym2); // false
Usage with null-prototype objects
Because null
-prototype objects do not inherit from Object.prototype
, they do not inherit the propertyIsEnumerable()
method. You must call Object.prototype.propertyIsEnumerable
with the object as this
instead.
const o = {
__proto__: null,
enumerableOwn: "is enumerable",
};
o.propertyIsEnumerable("enumerableOwn"); // TypeError: o.propertyIsEnumerable is not a function
Object.prototype.propertyIsEnumerable.call(o, "enumerableOwn"); // true
Alternatively, you may use Object.getOwnPropertyDescriptor()
instead, which also helps to distinguish between non-existent properties and actually non-enumerable properties.
const o = {
__proto__: null,
enumerableOwn: "is enumerable",
};
Object.getOwnPropertyDescriptor(o, "enumerableOwn")?.enumerable; // true
Object.getOwnPropertyDescriptor(o, "nonExistent")?.enumerable; // undefined
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-object.prototype.propertyisenumerable |


TypeError: Iterator/AsyncIterator constructor can't be used directly
The JavaScript exception "Iterator constructor can't be used directly" or "AsyncIterator constructor can't be used directly" occurs when you try to use the Iterator()
or AsyncIterator()
constructors directly to create instances. These constructors are abstract classes and should only be inherited from.
Message
TypeError: Abstract class Iterator not directly constructable (V8-based) TypeError: Iterator constructor can't be used directly (Firefox) TypeError: Iterator cannot be constructed directly (Safari) TypeError: Abstract class AsyncIterator not directly constructable (V8-based) TypeError: AsyncIterator constructor can't be used directly (Firefox) TypeError: AsyncIterator cannot be constructed directly (Safari)
Error type
TypeError
What went wrong?
The Iterator
and AsyncIterator
constructors are abstract classes and should not be used directly. They check the value of new.target
and throw if it is the same as the constructor itself. The only way to use these constructors is to inherit from them in a subclass and call super()
in the subclass constructor. The subclass must also define a next()
method to be useful.
Examples
Invalid cases
js
new Iterator();
Valid cases
js
class MyIterator extends Iterator {
#step;
#end;
constructor(start, end) {
// Implicitly calls new Iterator(), but with a different `new.target`
super();
this.#step = start;
this.#end = end;
}
next() {
if (this.#step >= this.#end) {
return { done: true };
}
return { value: this.#step++, done: false };
}
}
new MyIterator();


String.prototype.valueOf()

String.prototype.valueOf()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The valueOf()
method of String
values returns this string value.
Try it
const stringObj = new String("foo");
console.log(stringObj);
// Expected output: String { "foo" }
console.log(stringObj.valueOf());
// Expected output: "foo"
Syntax
js
valueOf()
Parameters
None.
Return value
A string representing the primitive value of a given String
object.
Description
The valueOf()
method of String
returns the primitive value
of a String
object as a string data type. This value is equivalent to
String.prototype.toString()
.
This method is usually called internally by JavaScript and not explicitly in code.
Examples
Using valueOf()
js
const x = new String("Hello world");
console.log(x.valueOf()); // 'Hello world'
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-string.prototype.valueof |


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/intl/durationformat/resolvedoptions/index.md


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/intl/listformat/index.md

# Original Wiki contributors
longlho
mfuji09
Chris Chittleborough
wbamberg
fscholz
nakhodkiin
sideshowbarker
cbejensen
senna
SphinxKnight
facm0b
spectranaut
stof
Autapomorph
romulocintra


Spread syntax (...)

Spread syntax (...)
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2015.
The spread (...
) syntax allows an iterable, such as an array or string, to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected. In an object literal, the spread syntax enumerates the properties of an object and adds the key-value pairs to the object being created.
Spread syntax looks exactly like rest syntax. In a way, spread syntax is the opposite of rest syntax. Spread syntax "expands" an array into its elements, while rest syntax collects multiple elements and "condenses" them into a single element. See rest parameters and rest property.
Try it
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers));
// Expected output: 6
console.log(sum.apply(null, numbers));
// Expected output: 6
Syntax
myFunction(a, ...iterableObj, b)
[1, ...iterableObj, '4', 'five', 6]
{ ...obj, key: 'value' }
Description
Spread syntax can be used when all elements from an object or array need to be included in a new array or object, or should be applied one-by-one in a function call's arguments list. There are three distinct places that accept the spread syntax:
- Function arguments list (
myFunction(a, ...iterableObj, b)
) - Array literals (
[1, ...iterableObj, '4', 'five', 6]
) - Object literals (
{ ...obj, key: 'value' }
)
Although the syntax looks the same, they come with slightly different semantics.
Only iterable values, like Array
and String
, can be spread in array literals and argument lists. Many objects are not iterable, including all plain objects that lack a Symbol.iterator
method:
const obj = { key1: "value1" };
const array = [...obj]; // TypeError: obj is not iterable
On the other hand, spreading in object literals enumerates the own properties of the value. For typical arrays, all indices are enumerable own properties, so arrays can be spread into objects.
const array = [1, 2, 3];
const obj = { ...array }; // { 0: 1, 1: 2, 2: 3 }
All primitives can be spread in objects. Only strings have enumerable own properties, and spreading anything else doesn't create properties on the new object.
const obj = { ...true, ..."test", ...10 };
// { '0': 't', '1': 'e', '2': 's', '3': 't' }
When using spread syntax for function calls, be aware of the possibility of exceeding the JavaScript engine's argument length limit. See Function.prototype.apply()
for more details.
Examples
Spread in function calls
Replace apply()
It is common to use Function.prototype.apply()
in cases where you want to
use the elements of an array as arguments to a function.
function myFunction(x, y, z) {}
const args = [0, 1, 2];
myFunction.apply(null, args);
With spread syntax the above can be written as:
function myFunction(x, y, z) {}
const args = [0, 1, 2];
myFunction(...args);
Any argument in the argument list can use spread syntax, and the spread syntax can be used multiple times.
function myFunction(v, w, x, y, z) {}
const args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);
Apply for new operator
When calling a constructor with new
, it's not possible to directly use an array and apply()
, because apply()
calls the target function instead of constructing it, which means, among other things, that new.target
will be undefined
. However, an array can be easily used with new
thanks to spread syntax:
const dateFields = [1970, 0, 1]; // 1 Jan 1970
const d = new Date(...dateFields);
Spread in array literals
A more powerful array literal
Without spread syntax, the array literal syntax is no longer sufficient to create a new array using an existing array as one part of it. Instead, imperative code must be used using a combination of methods, including push()
, splice()
, concat()
, etc. With spread syntax, this becomes much more succinct:
const parts = ["shoulders", "knees"];
const lyrics = ["head", ...parts, "and", "toes"];
// ["head", "shoulders", "knees", "and", "toes"]
Just like spread for argument lists, ...
can be used anywhere in the array literal, and may be used more than once.
Copying an array
You can use spread syntax to make a shallow copy of an array. Each array element retains its identity without getting copied.
const arr = [1, 2, 3];
const arr2 = [...arr]; // like arr.slice()
arr2.push(4);
// arr2 becomes [1, 2, 3, 4]
// arr remains unaffected
Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays. The same is true with Object.assign()
— no native operation in JavaScript does a deep clone. The web API method structuredClone()
allows deep copying values of certain supported types. See shallow copy for more details.
const a = [[1], [2], [3]];
const b = [...a];
b.shift().shift();
// 1
// Oh no! Now array 'a' is affected as well:
console.log(a);
// [[], [2], [3]]
A better way to concatenate arrays
Array.prototype.concat()
is often used to concatenate an array to the end of an existing array. Without spread syntax, this is done as:
let arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
// Append all items from arr2 onto arr1
arr1 = arr1.concat(arr2);
With spread syntax this becomes:
let arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2];
// arr1 is now [0, 1, 2, 3, 4, 5]
Array.prototype.unshift()
is often used to insert an array of values at the start of an existing array. Without spread syntax, this is done as:
const arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
// Prepend all items from arr2 onto arr1
Array.prototype.unshift.apply(arr1, arr2);
console.log(arr1); // [3, 4, 5, 0, 1, 2]
With spread syntax, this becomes:
let arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
arr1 = [...arr2, ...arr1];
console.log(arr1); // [3, 4, 5, 0, 1, 2]
Note:
Unlike unshift()
, this creates a new arr1
, instead of modifying the original arr1
array in-place.
Conditionally adding values to an array
You can make an element present or absent in an array literal, depending on a condition, using a conditional operator.
const isSummer = false;
const fruits = ["apple", "banana", ...(isSummer ? ["watermelon"] : [])];
// ['apple', 'banana']
When the condition is false
, we spread an empty array, so that nothing gets added to the final array. Note that this is different from the following:
const fruits = ["apple", "banana", isSummer ? "watermelon" : undefined];
// ['apple', 'banana', undefined]
In this case, an extra undefined
element is added when isSummer
is false
, and this element will be visited by methods such as Array.prototype.map()
.
Spread in object literals
Copying and merging objects
You can use spread syntax to merge multiple objects into one new object.
const obj1 = { foo: "bar", x: 42 };
const obj2 = { bar: "baz", y: 13 };
const mergedObj = { ...obj1, ...obj2 };
// { foo: "bar", x: 42, bar: "baz", y: 13 }
A single spread creates a shallow copy of the original object (but without non-enumerable properties and without copying the prototype), similar to copying an array.
const clonedObj = { ...obj1 };
// { foo: "bar", x: 42 }
Overriding properties
When one object is spread into another object, or when multiple objects are spread into one object, and properties with identical names are encountered, the property takes the last value assigned while remaining in the position it was originally set.
const obj1 = { foo: "bar", x: 42 };
const obj2 = { foo: "baz", y: 13 };
const mergedObj = { x: 41, ...obj1, ...obj2, y: 9 }; // { x: 42, foo: "baz", y: 9 }
Conditionally adding properties to an object
You can make an element present or absent in an object literal, depending on a condition, using a conditional operator.
const isSummer = false;
const fruits = {
apple: 10,
banana: 5,
...(isSummer ? { watermelon: 30 } : {}),
};
// { apple: 10, banana: 5 }
The case where the condition is false
is an empty object, so that nothing gets spread into the final object. Note that this is different from the following:
const fruits = {
apple: 10,
banana: 5,
watermelon: isSummer ? 30 : undefined,
};
// { apple: 10, banana: 5, watermelon: undefined }
In this case, the watermelon
property is always present and will be visited by methods such as Object.keys()
.
Because primitives can be spread into objects as well, and from the observation that all falsy values do not have enumerable properties, you can simply use a logical AND operator:
const isSummer = false;
const fruits = {
apple: 10,
banana: 5,
...(isSummer && { watermelon: 30 }),
};
In this case, if isSummer
is any falsy value, no property will be created on the fruits
object.
Comparing with Object.assign()
Note that Object.assign()
can be used to mutate an object, whereas spread syntax can't.
const obj1 = { foo: "bar", x: 42 };
Object.assign(obj1, { x: 1337 });
console.log(obj1); // { foo: "bar", x: 1337 }
In addition, Object.assign()
triggers setters on the target object, whereas spread syntax does not.
const objectAssign = Object.assign(
{
set foo(val) {
console.log(val);
},
},
{ foo: 1 },
);
// Logs "1"; objectAssign.foo is still the original setter
const spread = {
set foo(val) {
console.log(val);
},
...{ foo: 1 },
};
// Nothing is logged; spread.foo is 1
You cannot naively re-implement the Object.assign()
function through a single spreading:
const obj1 = { foo: "bar", x: 42 };
const obj2 = { foo: "baz", y: 13 };
const merge = (...objects) => ({ ...objects });
const mergedObj1 = merge(obj1, obj2);
// { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }
const mergedObj2 = merge({}, obj1, obj2);
// { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }
In the above example, the spread syntax does not work as one might expect: it spreads an array of arguments into the object literal, due to the rest parameter. Here is an implementation of merge
using the spread syntax, whose behavior is similar to Object.assign()
, except that it doesn't trigger setters, nor mutates any object:
const obj1 = { foo: "bar", x: 42 };
const obj2 = { foo: "baz", y: 13 };
const merge = (...objects) =>
objects.reduce((acc, cur) => ({ ...acc, ...cur }));
const mergedObj = merge(obj1, obj2);
// { foo: 'baz', x: 42, y: 13 }
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # prod-SpreadElement |
| ECMAScript® 2026 Language Specification # prod-ArgumentList |
| ECMAScript® 2026 Language Specification # prod-PropertyDefinition |


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/intl/relativetimeformat/index.md

# Original Wiki contributors
longlho
mfuji09
yairEO
fscholz
sideshowbarker
DmitryMakhnev
spadgos
romulocintra
evilpie
littledan
chrisdavidmills


Date.prototype.toTimeString()

Date.prototype.toTimeString()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The toTimeString()
method of Date
instances returns a string representing the time portion of this date interpreted in the local timezone.
Try it
const event = new Date("August 19, 1975 23:15:30");
console.log(event.toTimeString());
// Expected output: "23:15:30 GMT+0200 (CEST)"
// Note: your timezone may vary
Syntax
js
toTimeString()
Parameters
None.
Return value
A string representing the time portion of the given date (see description for the format). Returns "Invalid Date"
if the date is invalid.
Description
Date
instances refer to a specific point in time. toTimeString()
interprets the date in the local timezone and formats the time part in English. It always uses the format of HH:mm:ss GMT±xxxx (TZ)
, where:
| Format String | Description |
|---|---|
HH |
Hour, as two digits with leading zero if required |
mm |
Minute, as two digits with leading zero if required |
ss |
Seconds, as two digits with leading zero if required |
±xxxx |
The local timezone's offset — two digits for hours and two digits for minutes (e.g., -0500 , +0800 ) |
TZ |
The timezone's name (e.g., PDT , PST ) |
For example: "04:42:04 GMT+0000 (Coordinated Universal Time)".
- If you only want to get the date part, use
toDateString()
. - If you want to get both the date and time, use
toString()
. - If you want to make the date interpreted as UTC instead of local timezone, use
toUTCString()
. - If you want to format the date in a more user-friendly format (e.g., localization), use
toLocaleTimeString()
.
Examples
Using toTimeString()
js
const d = new Date(0);
console.log(d.toString()); // "Thu Jan 01 1970 00:00:00 GMT+0000 (Coordinated Universal Time)"
console.log(d.toTimeString()); // "00:00:00 GMT+0000 (Coordinated Universal Time)"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-date.prototype.totimestring |


Temporal.Duration.prototype.toLocaleString()
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
The toLocaleString()
method of Temporal.Duration
instances returns a string with a language-sensitive representation of this duration. In implementations with Intl.DurationFormat
API support, this method delegates to Intl.DurationFormat
.
Every time toLocaleString
is called, it has to perform a search in a big database of localization strings, which is potentially inefficient. When the method is called many times with the same arguments, it is better to create an Intl.DurationFormat
object and use its format()
method, because a DurationFormat
object remembers the arguments passed to it and may decide to cache a slice of the database, so future format
calls can search for localization strings within a more constrained context.
Syntax
toLocaleString()
toLocaleString(locales)
toLocaleString(locales, options)
Parameters
The locales
and options
parameters customize the behavior of the function and let applications specify the language whose formatting conventions should be used.
In implementations that support the Intl.DurationFormat
API, these parameters correspond exactly to the Intl.DurationFormat()
constructor's parameters. Implementations without Intl.DurationFormat
support return the exact same string as toString()
, ignoring both parameters.
locales
Optional-
A string with a BCP 47 language tag, or an array of such strings. Corresponds to the
locales
parameter of theIntl.DurationFormat()
constructor. options
Optional-
An object adjusting the output format. Corresponds to the
options
parameter of theIntl.DurationFormat()
constructor.
See the Intl.DurationFormat()
constructor for details on these parameters and how to use them.
Return value
A string representing the given duration according to language-specific conventions.
In implementations with Intl.DurationFormat
, this is equivalent to new Intl.DurationFormat(locales, options).format(duration)
.
Note:
Most of the time, the formatting returned by toLocaleString()
is consistent. However, the output may vary between implementations, even within the same locale — output variations are by design and allowed by the specification. It may also not be what you expect. For example, the string may use non-breaking spaces or be surrounded by bidirectional control characters. You should not compare the results of toLocaleString()
to hardcoded constants.
Examples
Using toLocaleString()
Basic use of this method without specifying a locale
returns a formatted string in the default locale and with default options.
const duration = Temporal.Duration.from({ hours: 1, minutes: 30, seconds: 15 });
console.log(duration.toLocaleString()); // 1 hr, 30 min, 15 sec
Specifications
| Specification |
|---|
| Temporal # sec-temporal.duration.prototype.tolocalestring |


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/number/positive_infinity/index.md

# Original Wiki contributors
mfuji09
fscholz
alattalatta
wbamberg
doubleOrt
jameshkramer
Mingun
AlexChao
Sheppy
evilpie
Sevenspade
Diablownik
Mgjbot
Potappo
Ptak82


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/errors/reduce_of_empty_array_with_no_initial_value/index.md

# Original Wiki contributors
fscholz
lmmfranco
om-ganesh
nbp


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/date/totimestring/index.md

# Original Wiki contributors
mfuji09
Robg1
wbamberg
fscholz
r-i-c-h
schalkneethling
jameshkramer
schlagi123
eduardoboucas
Mingun
kscarfone
Sheppy
ethertank
dtjm
evilpie
Dikrib
Sevenspade


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/object/constructor/index.md

# Original Wiki contributors
koroliov
mfuji09
hinell
fscholz
Audaciter
Zearin_Galaurum
Pointy
alattalatta
shuped
jonathan-stone
Robert-Wett
eLeontev
rivertam
dd-pardal
Congelli501
jameshkramer
sharanvkaur
astorm
olegpesok
Mingun
mbyrne
Airblader
Sheppy
GiviKDev
Paul-Dowsett
ethertank
evilpie
kalamay
Sevenspade
Nickolay
Ruakh
Andrea@3site.it
Mgjbot
Maian
Marcoos
Dria


Unary negation (-)

Unary negation (-)
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The unary negation (-
) operator precedes its operand and negates it.
Try it
const x = 4;
const y = -x;
console.log(y);
// Expected output: -4
const a = "4";
const b = -a;
console.log(b);
// Expected output: -4
Syntax
js
-x
Description
The -
operator is overloaded for two types of operands: number and BigInt. It first coerces the operand to a numeric value and tests the type of it. It performs BigInt negation if the operand becomes a BigInt; otherwise, it performs number negation.
Examples
Negating numbers
js
const x = 3;
const y = -x;
// y is -3; x is 3
Negating non-numbers
The unary negation operator can convert a non-number into a number.
js
const x = "4";
const y = -x;
// y is -4
BigInts can be negated using the unary negation operator.
js
const x = 4n;
const y = -x;
// y is -4n
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-unary-minus-operator |

const x = "4";
const y = -x;

// y is -4

const x = 4n;
const y = -x;

// y is -4n


Number.NEGATIVE_INFINITY

Number.NEGATIVE_INFINITY
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The Number.NEGATIVE_INFINITY
static data property represents the negative Infinity value.
Try it
function checkNumber(smallNumber) {
if (smallNumber === Number.NEGATIVE_INFINITY) {
return "Process number as -Infinity";
}
return smallNumber;
}
console.log(checkNumber(-Number.MAX_VALUE));
// Expected output: -1.7976931348623157e+308
console.log(checkNumber(-Number.MAX_VALUE * 2));
// Expected output: "Process number as -Infinity"
Value
The same as the negative value of the global Infinity
property.
Property attributes of Number.NEGATIVE_INFINITY | |
|---|---|
| Writable | no |
| Enumerable | no |
| Configurable | no |
Description
The Number.NEGATIVE_INFINITY
value behaves slightly differently than mathematical infinity:
- Any positive value, including
POSITIVE_INFINITY
, multiplied byNEGATIVE_INFINITY
isNEGATIVE_INFINITY
. - Any negative value, including
NEGATIVE_INFINITY
, multiplied byNEGATIVE_INFINITY
isPOSITIVE_INFINITY
. - Any positive value divided by
NEGATIVE_INFINITY
is negative zero (as defined in IEEE 754). - Any negative value divided by
NEGATIVE_INFINITY
is positive zero (as defined in IEEE 754). - Zero multiplied by
NEGATIVE_INFINITY
isNaN
. NaN
multiplied byNEGATIVE_INFINITY
isNaN
.NEGATIVE_INFINITY
, divided by any negative value exceptNEGATIVE_INFINITY
, isPOSITIVE_INFINITY
.NEGATIVE_INFINITY
, divided by any positive value exceptPOSITIVE_INFINITY
, isNEGATIVE_INFINITY
.NEGATIVE_INFINITY
, divided by eitherNEGATIVE_INFINITY
orPOSITIVE_INFINITY
, isNaN
.x > Number.NEGATIVE_INFINITY
is true for any number x that isn'tNEGATIVE_INFINITY
.
You might use the Number.NEGATIVE_INFINITY
property to indicate an error condition that returns a finite number in case of success. Note, however, that NaN
would be more appropriate in such a case.
Because NEGATIVE_INFINITY
is a static property of Number
, you always use it as Number.NEGATIVE_INFINITY
, rather than as a property of a number value.
Examples
Using NEGATIVE_INFINITY
In the following example, the variable smallNumber
is assigned a value that is smaller than the minimum value. When the if
statement executes, smallNumber
has the value -Infinity
, so smallNumber
is set to a more manageable value before continuing.
let smallNumber = -Number.MAX_VALUE * 2;
if (smallNumber === Number.NEGATIVE_INFINITY) {
smallNumber = returnFinite();
}
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-number.negative_infinity |


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/object/propertyisenumerable/index.md

# Original Wiki contributors
chrisdavidmills
vkweb
alextaghavi
mfuji09
wbamberg
fscholz
KinL
rileym7
jameshkramer
Sebastianz
eduardoboucas
Mingun
Sheppy
Brettz9
ethertank
evilpie
dofusion
Mgjbot
Sevenspade
Waldo


Number.prototype.valueOf()

Number.prototype.valueOf()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The valueOf()
method of Number
values returns the value of this number.
Try it
const numObj = new Number(42);
console.log(typeof numObj);
// Expected output: "object"
const num = numObj.valueOf();
console.log(num);
// Expected output: 42
console.log(typeof num);
// Expected output: "number"
Syntax
js
valueOf()
Parameters
None.
Return value
A number representing the primitive value of the specified Number
object.
Description
This method is usually called internally by JavaScript and not explicitly in web code.
Examples
Using valueOf
js
const numObj = new Number(10);
console.log(typeof numObj); // object
const num = numObj.valueOf();
console.log(num); // 10
console.log(typeof num); // number
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-number.prototype.valueof |


Array.prototype.toString()

Array.prototype.toString()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The toString()
method of Array
instances returns a string representing the
specified array and its elements.
Try it
const array = [1, 2, "a", "1a"];
console.log(array.toString());
// Expected output: "1,2,a,1a"
Syntax
toString()
Parameters
None.
Return value
A string representing the elements of the array.
Description
The Array
object overrides the toString
method of Object
. The toString
method of arrays calls join()
internally, which joins the array and returns one string containing each array element separated by commas. If the join
method is unavailable or is not a function, Object.prototype.toString
is used instead, returning [object Array]
.
const arr = [];
arr.join = 1; // re-assign `join` with a non-function
console.log(arr.toString()); // [object Array]
console.log(Array.prototype.toString.call({ join: () => 1 })); // 1
JavaScript calls the toString
method automatically when an array is to be represented as a text value or when an array is referred to in a string concatenation.
Array.prototype.toString
recursively converts each element, including other arrays, to strings. Because the string returned by Array.prototype.toString
does not have delimiters, nested arrays look like they are flattened.
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
];
console.log(matrix.toString()); // 1,2,3,4,5,6,7,8,9
When an array is cyclic (it contains an element that is itself), browsers avoid infinite recursion by ignoring the cyclic reference.
const arr = [];
arr.push(1, [3, arr, 4], 2);
console.log(arr.toString()); // 1,3,,4,2
Examples
Using toString()
const array = [1, 2, "a", "1a"];
console.log(array.toString()); // "1,2,a,1a"
Using toString() on sparse arrays
Following the behavior of join()
, toString()
treats empty slots the same as undefined
and produces an extra separator:
console.log([1, , 3].toString()); // '1,,3'
Calling toString() on non-array objects
toString()
is generic. It expects this
to have a join()
method; or, failing that, uses Object.prototype.toString()
instead.
console.log(Array.prototype.toString.call({ join: () => 1 }));
// 1; a number
console.log(Array.prototype.toString.call({ join: () => undefined }));
// undefined
console.log(Array.prototype.toString.call({ join: "not function" }));
// "[object Object]"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-array.prototype.tostring |


Right shift assignment (>>=)

Right shift assignment (>>=)
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
The right shift assignment (>>=
) operator performs right shift on the two operands and assigns the result to the left operand.
Try it
let a = 5; // 00000000000000000000000000000101
a >>= 2; // 00000000000000000000000000000001
console.log(a);
// Expected output: 1
let b = -5; // 11111111111111111111111111111011
b >>= 2; // 11111111111111111111111111111110
console.log(b);
// Expected output: -2
Syntax
js
x >>= y
Description
x >>= y
is equivalent to x = x >> y
, except that the expression x
is only evaluated once.
Examples
Using right shift assignment
js
let a = 5; // (00000000000000000000000000000101)
a >>= 2; // 1 (00000000000000000000000000000001)
let b = -5; // (-00000000000000000000000000000101)
b >>= 2; // -2 (-00000000000000000000000000000010)
let c = 5n;
c >>= 2n; // 1n
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-assignment-operators |


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/intl/datetimeformat/format/index.md

# Original Wiki contributors
mfuji09
fscholz
wbamberg
sideshowbarker
SphinxKnight
battaglr
chrisdavidmills
arai
David_Gilbertson
Mingun
Sheppy
Norbert


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/intl/numberformat/numberformat/index.md

# Original Wiki contributors
romulocintra
mfuji09
fscholz
acontreras89
wbamberg


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/errors/no_properties/index.md

# Original Wiki contributors
fscholz
PatrickKettner


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/intl/numberformat/resolvedoptions/index.md

# Original Wiki contributors
fscholz
sideshowbarker
bkardell
battaglr
wbamberg
arai
David_Gilbertson
eduardoboucas
Mingun
Sheppy
Norbert


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/execution_model/index.md

# Original Wiki contributors
fscholz
BoQsc
vegerot
wbamberg
PierBover
Zearin_Galaurum
Sheppy
divyanshu013
SphinxKnight
AnkitaSood
olegolegoleg
eyalChistik
metasean
MadEmperorYuri
harminho
Peiren
pirtleshell
antunmagdic
adrianosmond
doubleOrt
utkarshbhatt12
Jun711
aminoche
stephaniehobson
sautumn
sturmer
coolarun
perryjiang
broAhmed
roryokane
nmve
Martin-Ting
onurtemizkan
keshvari
jxjj
mprogers
nikjohn
raeesiqbal
masthandev
amilajack
inglor
hanu412
jswisher
PortableStick
suhajdab
kscarfone
chakkakuru
EddieFloresLive
dbruant


Symbol.toStringTag

Symbol.toStringTag
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2017.
The Symbol.toStringTag
static data property represents the well-known symbol Symbol.toStringTag
. Object.prototype.toString()
looks up this symbol on the this
value for the property containing a string that represents the type of the object.
Try it
class ValidatorClass {
get [Symbol.toStringTag]() {
return "Validator";
}
}
console.log(Object.prototype.toString.call(new ValidatorClass()));
// Expected output: "[object Validator]"
Value
The well-known symbol Symbol.toStringTag
.
Property attributes of Symbol.toStringTag | |
|---|---|
| Writable | no |
| Enumerable | no |
| Configurable | no |
Examples
Default tags
Some values do not have Symbol.toStringTag
, but have special toString()
representations. For a complete list, see Object.prototype.toString()
.
Object.prototype.toString.call("foo"); // "[object String]"
Object.prototype.toString.call([1, 2]); // "[object Array]"
Object.prototype.toString.call(3); // "[object Number]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"
// … and more
Built-in toStringTag symbols
Most built-in objects provide their own [Symbol.toStringTag]
property. Almost all built-in objects' [Symbol.toStringTag]
property is not writable, not enumerable, and configurable; the exception is Iterator
, which is writable for compatibility reasons.
For constructor objects like Promise
, the property is installed on Constructor.prototype
, so that all instances of the constructor inherit [Symbol.toStringTag]
and can be stringified. For non-constructor objects like Math
and JSON
, the property is installed as a static property, so that the namespace object itself can be stringified. Sometimes, the constructor also provides its own toString
method (for example, Intl.Locale
), in which case the [Symbol.toStringTag]
property is only used when you explicitly call Object.prototype.toString
on it.
Object.prototype.toString.call(new Map()); // "[object Map]"
Object.prototype.toString.call(function* () {}); // "[object GeneratorFunction]"
Object.prototype.toString.call(Promise.resolve()); // "[object Promise]"
// … and more
Custom tag with toStringTag
When creating your own class, JavaScript defaults to the "Object" tag:
class ValidatorClass {}
Object.prototype.toString.call(new ValidatorClass()); // "[object Object]"
Now, with the help of toStringTag
, you are able to set your own custom tag:
class ValidatorClass {
get [Symbol.toStringTag]() {
return "Validator";
}
}
Object.prototype.toString.call(new ValidatorClass()); // "[object Validator]"
toStringTag available on all DOM prototype objects
Due to a WebIDL spec change in mid-2020, browsers are adding a Symbol.toStringTag
property to all DOM prototype objects. For example, to access the Symbol.toStringTag
property on HTMLButtonElement
:
const test = document.createElement("button");
test.toString(); // "[object HTMLButtonElement]"
test[Symbol.toStringTag]; // "HTMLButtonElement"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-symbol.tostringtag |


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/temporal/duration/years/index.md


Intl.DurationFormat.prototype.formatToParts()
Baseline
2025
Newly available
Since March 2025, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
The formatToParts()
method of Intl.DurationFormat
instances returns an array of objects representing each part of the formatted string that would be returned by format()
. It is useful for building custom strings from the locale-specific tokens.
Syntax
formatToParts(duration)
Parameters
duration
Optional-
The duration object to be formatted. It should include some or all of the following properties:
years
,months
,weeks
,days
,hours
,minutes
,seconds
,milliseconds
,microseconds
,nanoseconds
. Each property's value should be an integer, and their signs should be consistent. This can be aTemporal.Duration
object; see theTemporal.Duration
documentation for more information about these properties.
Return value
An Array
of objects containing the formatted duration in parts. Each object has two or three properties, type
, value
, and optionally unit
, each containing a string. The string concatenation of value
, in the order provided, will result in the same string as format()
. The parts can be thought of as directly obtained from calling Intl.NumberFormat.prototype.formatToParts()
with the numeric value and their respective units. All tokens that are produced by the NumberFormat
have an additional unit
property, which is the singular form of the input unit
; this is for programmatic usage and is not localized. The localized unit is output as a separate unit
token as part of the NumberFormat
result. The parts from each duration unit are concatenated together in the same fashion as calling Intl.ListFormat.prototype.formatToParts()
with { type: "unit" }
, so additional literal tokens are inserted.
Examples
The formatToParts
method enables locale-aware formatting of strings produced by DurationFormat
formatters by providing you the string in parts:
const duration = {
hours: 7,
minutes: 8,
seconds: 9,
milliseconds: 123,
microseconds: 456,
nanoseconds: 789,
};
new Intl.DurationFormat("en", { style: "long" }).formatToParts(duration);
// Returned value:
[
{ type: "integer", value: "7", unit: "hour" },
{ type: "literal", value: " ", unit: "hour" },
{ type: "unit", value: "hours", unit: "hour" },
{ type: "literal", value: ", " },
{ type: "integer", value: "8", unit: "minute" },
{ type: "literal", value: " ", unit: "minute" },
{ type: "unit", value: "minutes", unit: "minute" },
{ type: "literal", value: ", " },
{ type: "integer", value: "9", unit: "second" },
{ type: "literal", value: " ", unit: "second" },
{ type: "unit", value: "seconds", unit: "second" },
{ type: "literal", value: ", " },
{ type: "integer", value: "123", unit: "millisecond" },
{ type: "literal", value: " ", unit: "millisecond" },
{ type: "unit", value: "milliseconds", unit: "millisecond" },
{ type: "literal", value: ", " },
{ type: "integer", value: "456", unit: "microsecond" },
{ type: "literal", value: " ", unit: "microsecond" },
{ type: "unit", value: "microseconds", unit: "microsecond" },
{ type: "literal", value: ", " },
{ type: "integer", value: "789", unit: "nanosecond" },
{ type: "literal", value: " ", unit: "nanosecond" },
{ type: "unit", value: "nanoseconds", unit: "nanosecond" },
];
Specifications
| Specification |
|---|
| Intl.DurationFormat # sec-Intl.DurationFormat.prototype.formatToParts |


Temporal.Duration.prototype.years

Temporal.Duration.prototype.years
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
The years
accessor property of Temporal.Duration
instances returns an integer representing the number of years in the duration.
You can know the sign of years
by checking the duration's sign
property.
The set accessor of years
is undefined
. You cannot change this property directly. Use the with()
method to create a new Temporal.Duration
object with the desired new value.
Examples
Using years
js
const d1 = Temporal.Duration.from({ years: 1, months: 1 });
const d2 = Temporal.Duration.from({ years: -1, months: -1 });
const d3 = Temporal.Duration.from({ years: 1 });
const d4 = Temporal.Duration.from({ months: 12 });
console.log(d1.years); // 1
console.log(d2.years); // -1
console.log(d3.years); // 1
console.log(d4.years); // 0
// Balance d4
const d4Balanced = d4.round({
largestUnit: "years",
relativeTo: Temporal.PlainDate.from("2021-01-01"), // ISO 8601 calendar
});
console.log(d4Balanced.years); // 1
console.log(d4Balanced.months); // 0
Specifications
| Specification |
|---|
| Temporal # sec-get-temporal.duration.prototype.years |
Browser compatibility
See also
Temporal.Duration
Temporal.Duration.prototype.months
Temporal.Duration.prototype.weeks
Temporal.Duration.prototype.days
Temporal.Duration.prototype.hours
Temporal.Duration.prototype.minutes
Temporal.Duration.prototype.seconds
Temporal.Duration.prototype.milliseconds
Temporal.Duration.prototype.microseconds
Temporal.Duration.prototype.nanoseconds


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/iteration_protocols/index.md

# Original Wiki contributors
dd-pardal
sinanergin
mfuji09
RainSlide
fscholz
tim_cannon
Zearin_Galaurum
wbamberg
KennethKinLum
GKJCJG
dmitryrn
juraj
SIMON-Yann
conartist6
kdex
jackblackevo
Robg1
stephaniehobson
yackSpillsaps
Landmaster
rwaldron
CodeFry
mamacdon
wedaren
mksarge
XMO
bcherny
nmve
DarylPinto
jsbisht
Delapouite
danwellman
AshCoolman
teoli
Nickolay
stevekinney
arai
icold
SphinxKnight
ziyunfei
KevinLozandier
dbruant
Havvy


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/function/length/index.md

# Original Wiki contributors
mfuji09
fscholz
jpmedley
SphinxKnight
naveenrawat51
Gwyn
wbamberg
jameshkramer
wuct
Jeremie
julienq
Mingun
Sheppy
shizm46
ethertank
evilpie
trevorh
ziyunfei
Sevenspade
mathiasbynens
Brettz9
Mgjbot
Maian
Dria


Array.prototype[Symbol.unscopables]

Array.prototype[Symbol.unscopables]
The [Symbol.unscopables]
data property of Array.prototype
is shared by all Array
instances. It contains property names that were not included in the ECMAScript standard prior to the ES2015 version and that are ignored for with
statement-binding purposes.
Value
A null
-prototype object with property names given below and their values set to true
.
Property attributes of Array.prototype[Symbol.unscopables] | |
|---|---|
| Writable | no |
| Enumerable | no |
| Configurable | yes |
Description
The default Array
properties that are ignored for with
statement-binding purposes are:
at()
copyWithin()
entries()
fill()
find()
findIndex()
findLast()
findLastIndex()
flat()
flatMap()
includes()
keys()
toReversed()
toSorted()
toSpliced()
values()
Array.prototype[Symbol.unscopables]
is an empty object only containing all the above property names with the value true
. Its prototype is null
, so Object.prototype
properties like toString
won't accidentally be made unscopable, and a toString()
within the with
statement will continue to be called on the array.
See Symbol.unscopables
for how to set unscopable properties for your own objects.
Examples
Imagine the values.push('something')
call below is in code that was written prior to ECMAScript 2015.
var values = [];
with (values) {
values.push("something");
}
When ECMAScript 2015 introduced the Array.prototype.values()
method, the with
statement in the above code started to interpret values
as the values.values
array method instead of the external values
variable. The values.push('something')
call would break because it's now accessing push
on the values.values
method. This caused a bug to be reported to Firefox (Firefox Bug 883914).
So the [Symbol.unscopables]
data property for Array.prototype
causes the Array
properties introduced in ECMAScript 2015 to be ignored for with
statement-binding purposes — allowing code that was written prior to ECMAScript 2015 to continue working as expected, rather than breaking.
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-array.prototype-%symbol.unscopables% |


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/intl/numberformat/supportedlocalesof/index.md

# Original Wiki contributors
mfuji09
fscholz
wbamberg
sideshowbarker
battaglr
arai
eduardoboucas
Mingun
Sheppy
Norbert


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/global_objects/intl/listformat/format/index.md

# Original Wiki contributors
mfuji09
wbamberg
fscholz
brian_
SphinxKnight
senna
rwe2020
sideshowbarker


# Contributors by commit history
https://github.com/mdn/content/commits/main/files/en-us/web/javascript/reference/errors/requires_global_regexp/index.md