Function: name

Function: name
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since August 2016.
The name
data property of a Function
instance indicates the function's name as specified when it was created, or it may be either anonymous
or ''
(an empty string) for functions created anonymously.
Try it
const func1 = function () {};
const object = {
func2: function () {},
};
console.log(func1.name);
// Expected output: "func1"
console.log(object.func2.name);
// Expected output: "func2"
Value
A string.
Property attributes of Function: name | |
|---|---|
| Writable | no |
| Enumerable | no |
| Configurable | yes |
Note:
In non-standard, pre-ES2015 implementations the configurable
attribute was false
as well.
Description
The function's name
property can be used to identify the function in debugging tools or error messages. It has no semantic significance to the language itself.
The name
property is read-only and cannot be changed by the assignment operator:
function someFunction() {}
someFunction.name = "otherFunction";
console.log(someFunction.name); // someFunction
To change it, use Object.defineProperty()
.
The name
property is typically inferred from how the function is defined. In the following sections, we will describe the various ways in which it can be inferred.
Function declaration
The name
property returns the name of a function declaration.
function doSomething() {}
doSomething.name; // "doSomething"
Default-exported function declaration
An export default
declaration exports the function as a declaration instead of an expression. If the declaration is anonymous, the name is "default"
.
// -- someModule.js --
export default function () {}
// -- main.js --
import someModule from "./someModule.js";
someModule.name; // "default"
Function constructor
Functions created with the Function()
constructor have name "anonymous".
new Function().name; // "anonymous"
Function expression
If the function expression is named, that name is used as the name
property.
const someFunction = function someFunctionName() {};
someFunction.name; // "someFunctionName"
Anonymous function expressions, created using either the function
keyword or the arrow function syntax, have ""
(an empty string) as their name by default.
(function () {}).name; // ""
(() => {}).name; // ""
However, such cases are rare — usually, in order to call the function elsewhere, the function expression is associated with an identifier. The name of an anonymous function expression can be inferred within certain syntactic contexts, including: variable declaration, method, initializer, and default value.
One practical case where the name cannot be inferred is a function returned from another function:
function getFoo() {
return () => {};
}
getFoo().name; // ""
Variable declaration and method
Variables and methods can infer the name of an anonymous function from its syntactic position.
const f = function () {};
const object = {
someMethod: function () {},
};
console.log(f.name); // "f"
console.log(object.someMethod.name); // "someMethod"
The same applies to assignment:
let f;
f = () => {};
f.name; // "f"
Initializer and default value
Functions in initializers (default values) of destructuring, default parameters, class fields, etc., will inherit the name of the bound identifier as their name
.
const [f = () => {}] = [];
f.name; // "f"
const { someMethod: m = () => {} } = {};
m.name; // "m"
function foo(f = () => {}) {
console.log(f.name);
}
foo(); // "f"
class Foo {
static someMethod = () => {};
}
Foo.someMethod.name; // someMethod
Shorthand method
const o = {
foo() {},
};
o.foo.name; // "foo";
Bound function
Function.prototype.bind()
produces a function whose name is "bound " plus the function name.
function foo() {}
foo.bind({}).name; // "bound foo"
Getter and setter
When using get
and set
accessor properties, "get" or "set" will appear in the function name.
const o = {
get foo() {
return 1;
},
set foo(x) {},
};
const descriptor = Object.getOwnPropertyDescriptor(o, "foo");
descriptor.get.name; // "get foo"
descriptor.set.name; // "set foo";
Class
A class's name follows the same algorithm as function declarations and expressions.
class Foo {}
Foo.name; // "Foo"
Warning:
JavaScript will set the function's name
property only if a function does not have an own property called name
. However, classes' static members will be set as own properties of the class constructor function, and thus prevent the built-in name
from being applied. See an example below.
Symbol as function name
If a Symbol
is used a function name and the symbol has a description, the method's name is the description in square brackets.
const sym1 = Symbol("foo");
const sym2 = Symbol();
const o = {
[sym1]() {},
[sym2]() {},
};
o[sym1].name; // "[foo]"
o[sym2].name; // "[]"
Private fields and methods
Private fields and private methods have the hash (#
) as part of their names.
class Foo {
#field = () => {};
#method() {}
getNames() {
console.log(this.#field.name);
console.log(this.#method.name);
}
}
new Foo().getNames();
// "#field"
// "#method"
Examples
Telling the constructor name of an object
You can use obj.constructor.name
to check the "class" of an object.
function Foo() {} // Or: class Foo {}
const fooInstance = new Foo();
console.log(fooInstance.constructor.name); // "Foo"
However, because static members will become own properties of the class, we can't obtain the class name for virtually any class with a static method property name()
:
class Foo {
constructor() {}
static name() {}
}
With a static name()
method Foo.name
no longer holds the actual class name but a reference to the name()
function object. Trying to obtain the class of fooInstance
via fooInstance.constructor.name
won't give us the class name at all, but instead a reference to the static class method. Example:
const fooInstance = new Foo();
console.log(fooInstance.constructor.name); // ƒ name() {}
Due to the existence of static fields, name
may not be a function either.
class Foo {
static name = 123;
}
console.log(new Foo().constructor.name); // 123
If a class has a static property called name
, it will also become writable. The built-in definition in the absence of a custom static definition is read-only:
Foo.name = "Hello";
console.log(Foo.name); // "Hello" if class Foo has a static "name" property, but "Foo" if not.
Therefore you may not rely on the built-in name
property to always hold a class's name.
JavaScript compressors and minifiers
Warning:
Be careful when using the name
property with source-code transformations, such as those carried out by JavaScript compressors (minifiers) or obfuscators. These tools are often used as part of a JavaScript build pipeline to reduce the size of a program prior to deploying it to production. Such transformations often change a function's name at build time.
Source code such as:
function Foo() {}
const foo = new Foo();
if (foo.constructor.name === "Foo") {
console.log("'foo' is an instance of 'Foo'");
} else {
console.log("Oops!");
}
may be compressed to:
function a() {}
const b = new a();
if (b.constructor.name === "Foo") {
console.log("'foo' is an instance of 'Foo'");
} else {
console.log("Oops!");
}
In the uncompressed version, the program runs into the truthy branch and logs "'foo' is an instance of 'Foo'" — whereas, in the compressed version it behaves differently, and runs into the else branch. If you rely on the name
property, like in the example above, make sure your build pipeline doesn't change function names, or don't assume a function has a particular name.
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-function-instances-name |


JSON.rawJSON()

JSON.rawJSON()
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
The JSON.rawJSON()
static method creates a "raw JSON" object containing a piece of JSON text. When serialized to JSON, the raw JSON object is treated as if it is already a piece of JSON. This text is required to be valid JSON.
Syntax
JSON.rawJSON(string)
Parameters
string
-
The JSON text. Must be valid JSON representing a primitive value.
Return value
An object that can be used to create JSON text with the exact same content as the string
provided, without quotes around the string itself. This object has null
prototype and is frozen (so it never gets accidentally serialized as a regular object by any kind of primitive conversion), and the following property:
rawJSON
-
The original JSON
string
provided.
Furthermore, it has a private field that marks itself as a raw JSON object. This allows it to be identified by JSON.stringify()
and JSON.isRawJSON()
.
Exceptions
SyntaxError
-
Thrown if the
string
is not valid JSON, or if it represents an object or array.
Description
A raw JSON object can be seen as an immutable, atomic data structure like any kind of primitive. It is not a regular object and it contains no data other than the raw JSON text. It is used to "pre-serialize" data to formats that JSON.stringify
itself cannot produce for various reasons. The most typical use case is the floating point number loss of precision problem. For example:
JSON.stringify({ value: 12345678901234567890 });
// {"value":12345678901234567000}
The value is not exactly equivalent to the original number any more! This is because JavaScript uses floating point representation for all numbers, so it cannot represent all integers exactly. The number literal 12345678901234567890
itself is already rounded to the nearest representable number when it is parsed by JavaScript.
Without JSON.rawJSON
, there is no way to tell JSON.stringify
to produce the number literal 12345678901234567890
, because there is simply no corresponding JavaScript number value. With raw JSON, you can directly tell JSON.stringify()
what a particular value should be stringified as:
const rawJSON = JSON.rawJSON("12345678901234567890");
JSON.stringify({ value: rawJSON });
// {"value":12345678901234567890}
For a more complete example of this, see Lossless number serialization.
Note that although we passed a string to JSON.rawJSON()
, it still becomes a number in the final JSON. This is because the string represents the verbatim JSON text. If you want to serialize a string, you should use JSON.rawJSON()
with a quotes-enclosed string value:
const rawJSON = JSON.rawJSON('"Hello world"');
JSON.stringify({ value: rawJSON });
// {"value":"Hello world"}
JSON.rawJSON
allows you to insert arbitrary JSON text, but does not allow you to create invalid JSON. Anything that was not permitted by the JSON syntax is not permitted by JSON.rawJSON()
either:
const rawJSON = JSON.rawJSON('"Hello\nworld"'); // Syntax error, because line breaks are not allowed in JSON strings
Furthermore, you cannot use JSON.rawJSON()
to create JSON objects or arrays.
Examples
Using JSON.rawJSON() to create JSON expressions of different types
const numJSON = JSON.rawJSON("123");
const strJSON = JSON.rawJSON('"Hello world"');
const boolJSON = JSON.rawJSON("true");
const nullJSON = JSON.rawJSON("null");
console.log(
JSON.stringify({
age: numJSON,
message: strJSON,
isActive: boolJSON,
nothing: nullJSON,
}),
);
// {"age":123,"message":"Hello world","isActive":true,"nothing":null}
However, you cannot use JSON.rawJSON()
to create JSON objects or arrays:
const arrJSON = JSON.rawJSON("[1, 2, 3]");
const objJSON = JSON.rawJSON('{"a": 1, "b": 2}');
// SyntaxError
Using JSON.rawJSON() to create escaped string literals
Apart from numbers, there is only one other type that does not have a one-to-one correspondence between JavaScript values and JSON text: strings. When strings are serialized to JSON, all code points, other than those that are not legal inside JSON string literals (such as line breaks), are printed literally:
console.log(JSON.stringify({ value: "\ud83d\ude04" })); // {"value":"😄"}
This may not be desirable, because the receiver of this string may handle Unicode differently. To improve interoperability, you can explicitly specify the string to be serialized with escape sequences:
const rawJSON = JSON.rawJSON('"\\ud83d\\ude04"');
const objStr = JSON.stringify({ value: rawJSON });
console.log(objStr); // {"value":"\ud83d\ude04"}
console.log(JSON.parse(objStr).value); // 😄
Note that the double backslashes in the rawJSON
actually represents a single slash character.
Specifications
| Specification |
|---|
| JSON.parse source text access # sec-json.rawjson |


JSON.isRawJSON()

JSON.isRawJSON()
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
The JSON.isRawJSON()
static method tests whether a value is an object returned by JSON.rawJSON()
.
Syntax
JSON.isRawJSON(value)
Parameters
value
-
The value to test.
Return value
true
if value
is created by JSON.rawJSON()
; otherwise, false
.
Description
"Raw JSON" objects, when serialized to JSON, are treated as if they are already a piece of JSON. Furthermore, because of the way JSON.rawJSON()
works, the raw JSON is guaranteed to be syntactically valid JSON. For more information on the shape and behavior of raw JSON objects, see JSON.rawJSON()
. This method exists to allow other serialization libraries to implement similar behavior to JSON.stringify()
for raw JSON objects.
Examples
Using JSON.isRawJSON()
The following example demonstrates how to use JSON.isRawJSON()
to test whether an object was returned by JSON.rawJSON()
. It implements a custom serializer that serializes data to a YAML-like format.
function mySerializer(value, indent = "") {
if (typeof value !== "object" || value === null) {
return JSON.stringify(value);
}
if (JSON.isRawJSON(value)) {
return value.rawJSON;
}
const subIndent = `${indent} `;
if (Array.isArray(value)) {
return `- ${value.map((v) => mySerializer(v, subIndent)).join(`\n${indent}- `)}`;
}
return Object.entries(value)
.map(([key, value]) => {
const subValue = mySerializer(value, subIndent);
if (subValue.includes("\n")) {
return `${key}:\n${subIndent}${subValue}`;
}
return `${key}: ${subValue}`;
})
.join(`\n${indent}`);
}
console.log(
mySerializer({
name: "Josh",
userId: JSON.rawJSON("12345678901234567890"),
friends: [
{ name: "Alice", userId: JSON.rawJSON("9876543210987654321") },
{ name: "Bob", userId: JSON.rawJSON("56789012345678901234") },
],
}),
);
// name: "Josh"
// userId: 12345678901234567890
// friends:
// - name: "Alice"
// userId: 9876543210987654321
// - name: "Bob"
// userId: 56789012345678901234
If in the above example, the userId
values were not created by JSON.rawJSON()
, but passed as numbers directly, then we will get loss of precision upfront because of JS floating point precision limitations.
console.log(
mySerializer({
name: "Josh",
userId: 12345678901234567890,
friends: [
{ name: "Alice", userId: 9876543210987654321 },
{ name: "Bob", userId: 56789012345678901234 },
],
}),
);
// name: "Josh"
// userId: 12345678901234567000
// friends:
// - name: "Alice"
// userId: 9876543210987655000
// - name: "Bob"
// userId: 56789012345678900000
Specifications
| Specification |
|---|
| JSON.parse source text access # sec-json.israwjson |


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

# Original Wiki contributors
mfuji09
SebastianSimon
wbamberg
hikigaya58
fscholz
nakhodkiin
anonyco
SphinxKnight
Richienb
alattalatta
schalkneethling
whirr.click
bartolocarrasco
jameshkramer
keirog
david_ross
FredGandt
kdex
oksana-khristenko
ccoenen
NodeGuy
Sheppy
duraik3
eduardoboucas
yortus
jordanbtucker
kmaglione
ElFelli
Mingun
broadl21
georgebatalinski
ziyunfei
DCK
madarche
ethertank
evilpie
marcello.nuccio
Waldo


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 |


Function: displayName

Function: displayName
Non-standard: This feature is not standardized. We do not recommend using non-standard features in production, as they have limited browser support, and may change or be removed. However, they can be a suitable alternative in specific cases where no standard option exists.
The optional displayName
property of a Function
instance specifies the display name of the function.
Value
The displayName
property is not initially present on any function — it's added by the code authors. For the purpose of display, it should be a string.
Description
The displayName
property, if present, may be preferred by consoles and profilers over the name
property to be displayed as the name of a function.
Among browsers, only the Firefox console utilizes this property. React devtools also use the displayName
property when displaying the component tree.
Firefox does some basic attempts to decode the displayName
that's possibly generated by the anonymous JavaScript functions naming convention algorithm. The following patterns are detected:
- If
displayName
ends with a sequence of alphanumeric characters,_
, and$
, the longest such suffix is displayed. - If
displayName
ends with a sequence of[]
-enclosed characters, that sequence is displayed without the square brackets. - If
displayName
ends with a sequence of alphanumeric characters and_
followed by some/
,.
, or<
, the sequence is returned without the trailing/
,.
, or<
characters. - If
displayName
ends with a sequence of alphanumeric characters and_
followed by(^)
, the sequence is displayed without the(^)
.
If none of the above patterns match, the entire displayName
is displayed.
Examples
Setting a displayName
By entering the following in a Firefox console, it should display as something like function MyFunction()
:
function a() {}
a.displayName = "MyFunction";
a; // function MyFunction()
Changing displayName dynamically
You can dynamically change the displayName
of a function:
const object = {
// anonymous
someMethod: function someMethod(value) {
someMethod.displayName = `someMethod (${value})`;
},
};
console.log(object.someMethod.displayName); // undefined
object.someMethod("123");
console.log(object.someMethod.displayName); // "someMethod (123)"
Cleaning of displayName
Firefox devtools would clean up a few common patterns in the displayName
property before displaying it.
function foo() {}
function testName(name) {
foo.displayName = name;
console.log(foo);
}
testName("$foo$"); // function $foo$()
testName("foo bar"); // function bar()
testName("Foo.prototype.add"); // function add()
testName("foo ."); // function foo .()
testName("foo <"); // function foo <()
testName("foo?"); // function foo?()
testName("foo()"); // function foo()()
testName("[...]"); // function ...()
testName("foo<"); // function foo()
testName("foo..."); // function foo()
testName("foo(^)"); // function foo()
Specifications
Not part of any standard.


# 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


Function.prototype[Symbol.hasInstance]()
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.hasInstance]()
method of Function
instances specifies the default procedure for determining if a constructor function recognizes an object as one of the constructor's instances. It is called by the instanceof
operator.
Syntax
func[Symbol.hasInstance](value)
Parameters
value
-
The object to test. Primitive values always return
false
.
Return value
true
if func.prototype
is in the prototype chain of value
; otherwise, false
. Always returns false
if value
is not an object or this
is not a function. If this
is a bound function, returns the result of an instanceof
test on value
and the underlying target function.
Exceptions
TypeError
-
Thrown if
this
is not a bound function andthis.prototype
is not an object.
Description
The instanceof
operator calls the [Symbol.hasInstance]()
method of the right-hand side whenever such a method exists. Because all functions inherit from Function.prototype
by default, they would all have the [Symbol.hasInstance]()
method, so most of the time, the Function.prototype[Symbol.hasInstance]()
method specifies the behavior of instanceof
when the right-hand side is a function. This method implements the default behavior of the instanceof
operator (the same algorithm when constructor
has no [Symbol.hasInstance]()
method).
Unlike most methods, the Function.prototype[Symbol.hasInstance]()
property is non-configurable and non-writable. This is a security feature to prevent the underlying target function of a bound function from being obtainable. See this Stack Overflow answer for an example.
Examples
Reverting to default instanceof behavior
You would rarely need to call this method directly. Instead, this method is called by the instanceof
operator. You should expect the two results to usually be equivalent.
class Foo {}
const foo = new Foo();
console.log(foo instanceof Foo === Foo[Symbol.hasInstance](foo)); // true
You may want to use this method if you want to invoke the default instanceof
behavior, but you don't know if a constructor has an overridden [Symbol.hasInstance]()
method.
class Foo {
static [Symbol.hasInstance](value) {
// A custom implementation
return false;
}
}
const foo = new Foo();
console.log(foo instanceof Foo); // false
console.log(Function.prototype[Symbol.hasInstance].call(Foo, foo)); // true
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-function.prototype-%symbol.hasinstance% |


Object.prototype.constructor

Object.prototype.constructor
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 constructor
data property of an Object
instance returns a reference to the constructor function that created the instance object. Note that the value of this property is a reference to the function itself, not a string containing the function's name.
Note:
This is a property of JavaScript objects. For the constructor
method in classes, see its own reference page.
Value
A reference to the constructor function that created the instance object.
Property attributes of Object.prototype.constructor | |
|---|---|
| Writable | yes |
| Enumerable | no |
| Configurable | yes |
Note:
This property is created by default on the prototype
property of every constructor function and is inherited by all objects created by that constructor.
Description
Any object (with the exception of null
prototype objects) will have a constructor
property on its [[Prototype]]
. Objects created with literals will also have a constructor
property that points to the constructor type for that object — for example, array literals create Array
objects, and object literals create plain objects.
const o1 = {};
o1.constructor === Object; // true
const o2 = new Object();
o2.constructor === Object; // true
const a1 = [];
a1.constructor === Array; // true
const a2 = new Array();
a2.constructor === Array; // true
const n = 3;
n.constructor === Number; // true
Note that constructor
usually comes from the constructor's prototype
property. If you have a longer prototype chain, you can usually expect every object in the chain to have a constructor
property.
const o = new TypeError(); // Inheritance: TypeError -> Error -> Object
const proto = Object.getPrototypeOf;
Object.hasOwn(o, "constructor"); // false
proto(o).constructor === TypeError; // true
proto(proto(o)).constructor === Error; // true
proto(proto(proto(o))).constructor === Object; // true
Examples
Displaying the constructor of an object
The following example creates a constructor (Tree
) and an object of that type (theTree
). The example then displays the constructor
property for the object theTree
.
function Tree(name) {
this.name = name;
}
const theTree = new Tree("Redwood");
console.log(`theTree.constructor is ${theTree.constructor}`);
This example displays the following output:
theTree.constructor is function Tree(name) { this.name = name; }
Assigning the constructor property to an object
One can assign the constructor
property of non-primitives.
const arr = [];
arr.constructor = String;
arr.constructor === String; // true
arr instanceof String; // false
arr instanceof Array; // true
const foo = new Foo();
foo.constructor = "bar";
foo.constructor === "bar"; // true
// etc.
This does not overwrite the old constructor
property — it was originally present on the instance's [[Prototype]]
, not as its own property.
const arr = [];
Object.hasOwn(arr, "constructor"); // false
Object.hasOwn(Object.getPrototypeOf(arr), "constructor"); // true
arr.constructor = String;
Object.hasOwn(arr, "constructor"); // true — the instance property shadows the one on its prototype
But even when Object.getPrototypeOf(a).constructor
is re-assigned, it won't change other behaviors of the object. For example, the behavior of instanceof
is controlled by Symbol.hasInstance
, not constructor
:
const arr = [];
arr.constructor = String;
arr instanceof String; // false
arr instanceof Array; // true
There is nothing protecting the constructor
property from being re-assigned or shadowed, so using it to detect the type of a variable should usually be avoided in favor of less fragile ways like instanceof
and Symbol.toStringTag
for objects, or typeof
for primitives.
Changing the constructor of a constructor function's prototype
Every constructor has a prototype
property, which will become the instance's [[Prototype]]
when called via the new
operator. ConstructorFunction.prototype.constructor
will therefore become a property on the instance's [[Prototype]]
, as previously demonstrated.
However, if ConstructorFunction.prototype
is re-assigned, the constructor
property will be lost. For example, the following is a common way to create an inheritance pattern:
function Parent() {
// …
}
Parent.prototype.parentMethod = function () {};
function Child() {
Parent.call(this); // Make sure everything is initialized properly
}
// Pointing the [[Prototype]] of Child.prototype to Parent.prototype
Child.prototype = Object.create(Parent.prototype);
The constructor
of instances of Child
will be Parent
due to Child.prototype
being re-assigned.
This is usually not a big deal — the language almost never reads the constructor
property of an object. The only exception is when using [Symbol.species]
to create new instances of a class, but such cases are rare, and you should be using the extends
syntax to subclass builtins anyway.
However, ensuring that Child.prototype.constructor
always points to Child
itself is crucial when some caller is using constructor
to access the original class from an instance. Take the following case: the object has the create()
method to create itself.
function Parent() {
// …
}
function CreatedConstructor() {
Parent.call(this);
}
CreatedConstructor.prototype = Object.create(Parent.prototype);
CreatedConstructor.prototype.create = function () {
return new this.constructor();
};
new CreatedConstructor().create().create(); // TypeError: new CreatedConstructor().create().create is undefined, since constructor === Parent
In the example above, an exception is thrown, since the constructor
links to Parent
. To avoid this, just assign the necessary constructor you are going to use.
function Parent() {
// …
}
function CreatedConstructor() {
// …
}
CreatedConstructor.prototype = Object.create(Parent.prototype, {
// Return original constructor to Child
constructor: {
value: CreatedConstructor,
enumerable: false, // Make it non-enumerable, so it won't appear in `for...in` loop
writable: true,
configurable: true,
},
});
CreatedConstructor.prototype.create = function () {
return new this.constructor();
};
new CreatedConstructor().create().create(); // it's pretty fine
Note that when manually adding the constructor
property, it's crucial to make the property non-enumerable, so constructor
won't be visited in for...in
loops — as it normally isn't.
If the code above looks like too much boilerplate, you may also consider using Object.setPrototypeOf()
to manipulate the prototype chain.
function Parent() {
// …
}
function CreatedConstructor() {
// …
}
Object.setPrototypeOf(CreatedConstructor.prototype, Parent.prototype);
CreatedConstructor.prototype.create = function () {
return new this.constructor();
};
new CreatedConstructor().create().create(); // still works without re-creating constructor property
Object.setPrototypeOf()
comes with its potential performance downsides because all previously created objects involved in the prototype chain have to be re-compiled; but if the above initialization code happens before Parent
or CreatedConstructor
are constructed, the effect should be minimal.
Let's consider one more involved case.
function ParentWithStatic() {}
ParentWithStatic.startPosition = { x: 0, y: 0 }; // Static member property
ParentWithStatic.getStartPosition = function () {
return this.startPosition;
};
function Child(x, y) {
this.position = { x, y };
}
Child.prototype = Object.create(ParentWithStatic.prototype, {
// Return original constructor to Child
constructor: {
value: Child,
enumerable: false,
writable: true,
configurable: true,
},
});
Child.prototype.getOffsetByInitialPosition = function () {
const position = this.position;
// Using this.constructor, in hope that getStartPosition exists as a static method
const startPosition = this.constructor.getStartPosition();
return {
offsetX: startPosition.x - position.x,
offsetY: startPosition.y - position.y,
};
};
new Child(1, 1).getOffsetByInitialPosition();
// Error: this.constructor.getStartPosition is undefined, since the
// constructor is Child, which doesn't have the getStartPosition static method
For this example to work properly, we can reassign the Parent
's static properties to Child
:
// …
Object.assign(Child, ParentWithStatic); // Notice that we assign it before we create() a prototype below
Child.prototype = Object.create(ParentWithStatic.prototype, {
// Return original constructor to Child
constructor: {
value: Child,
enumerable: false,
writable: true,
configurable: true,
},
});
// …
But even better, we can make the constructor functions themselves extend each other, as classes' extends
do.
function ParentWithStatic() {}
ParentWithStatic.startPosition = { x: 0, y: 0 }; // Static member property
ParentWithStatic.getStartPosition = function () {
return this.startPosition;
};
function Child(x, y) {
this.position = { x, y };
}
// Properly create inheritance!
Object.setPrototypeOf(Child.prototype, ParentWithStatic.prototype);
Object.setPrototypeOf(Child, ParentWithStatic);
Child.prototype.getOffsetByInitialPosition = function () {
const position = this.position;
const startPosition = this.constructor.getStartPosition();
return {
offsetX: startPosition.x - position.x,
offsetY: startPosition.y - position.y,
};
};
console.log(new Child(1, 1).getOffsetByInitialPosition()); // { offsetX: -1, offsetY: -1 }
Again, using Object.setPrototypeOf()
may have adverse performance effects, so make sure it happens immediately after the constructor declaration and before any instances are created — to avoid objects being "tainted".
Note:
Manually updating or setting the constructor can lead to different and sometimes confusing consequences. To prevent this, just define the role of constructor
in each specific case. In most cases, constructor
is not used and reassigning it is not necessary.
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-object.prototype.constructor |


Object.prototype.toLocaleString()

Object.prototype.toLocaleString()
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 toLocaleString()
method of Object
instances returns a string representing this object. This method is meant to be overridden by derived objects for locale-specific purposes.
Try it
const date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
console.log(date.toLocaleString("ar-EG"));
// Expected output: "٢٠/١٢/٢٠١٢ ٤:٠٠:٠٠ ص"
const number = 123456.789;
console.log(number.toLocaleString("de-DE"));
// Expected output: "123.456,789"
Syntax
toLocaleString()
Parameters
None. However, all objects that override this method are expected to accept at most two parameters, corresponding to locales
and options
, such as Number.prototype.toLocaleString
. The parameter positions should not be used for any other purpose.
Return value
The return value of calling this.toString()
.
Description
All objects that inherit from Object.prototype
(that is, all except null
-prototype objects) inherit the toLocaleString()
method. Object
's toLocaleString
returns the result of calling this.toString()
.
This function is provided to give objects a generic toLocaleString
method, even though not all may use it. In the core language, these built-in objects override toLocaleString
to provide locale-specific formatting:
Examples
Using the base toLocaleString() method
The base toLocaleString()
method simply calls toString()
.
const obj = {
toString() {
return "My Object";
},
};
console.log(obj.toLocaleString()); // "My Object"
Array toLocaleString() override
Array.prototype.toLocaleString()
is used to print array values as a string by invoking each element's toLocaleString()
method and joining the results with a locale-specific separator. For example:
const testArray = [4, 7, 10];
const euroPrices = testArray.toLocaleString("fr", {
style: "currency",
currency: "EUR",
});
// "4,00 €,7,00 €,10,00 €"
Date toLocaleString() override
Date.prototype.toLocaleString()
is used to print out date displays more suitable for specific locales. For example:
const testDate = new Date();
// "Fri May 29 2020 18:04:24 GMT+0100 (British Summer Time)"
const deDate = testDate.toLocaleString("de");
// "29.5.2020, 18:04:24"
const frDate = testDate.toLocaleString("fr");
// "29/05/2020, 18:04:24"
Number toLocaleString() override
Number.prototype.toLocaleString()
is used to print out number displays more suitable for specific locales, e.g., with the correct separators. For example:
const testNumber = 2901234564;
// "2901234564"
const deNumber = testNumber.toLocaleString("de");
// "2.901.234.564"
const frNumber = testNumber.toLocaleString("fr");
// "2 901 234 564"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-object.prototype.tolocalestring |


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

# Original Wiki contributors
mfuji09
ninevra
brianebert
Anonymous
wbamberg
fscholz
Zearin_Galaurum
DariaManko
RainSlide
Delapouite
jameshkramer
vermaslal
eduardoboucas
chrisfillmore
jsx
jajang20
Mingun
Sheppy
ethertank
trevorh
tokuhirom
evilpie
Wyvernoid
Sevenspade
Mgjbot
Nickolay
Taken
Maian
Marcoos
Dria


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 |


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 |


BigInt.prototype.toString()

BigInt.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 September 2020.
The toString()
method of BigInt
values returns a string representing the specified BigInt
value. The trailing "n" is not part of the string.
Try it
console.log(1024n.toString());
// Expected output: "1024"
console.log(1024n.toString(2));
// Expected output: "10000000000"
console.log(1024n.toString(16));
// Expected output: "400"
Syntax
toString()
toString(radix)
Parameters
radix
Optional-
An integer in the range 2 through 36 specifying the base to use for representing the BigInt value. Defaults to 10.
Return value
A string representing the specified BigInt
value.
Exceptions
RangeError
-
Thrown if
radix
is less than 2 or greater than 36.
Description
The BigInt
object overrides the toString
method of Object
; it does not inherit
Object.prototype.toString()
. For BigInt
values, the toString()
method returns a string representation of the value in the specified radix.
For radixes above 10, the letters of the alphabet indicate digits greater than 9. For example, for hexadecimal numbers (base 16) a
through f
are used.
If the specified BigInt value is negative, the sign is preserved. This is the case even if the radix is 2; the string returned is the positive binary representation of the BigInt value preceded by a -
sign, not the two's complement of the BigInt value.
The toString()
method requires its this
value to be a BigInt
primitive or wrapper object. It throws a TypeError
for other this
values without attempting to coerce them to BigInt values.
Because BigInt
doesn't have a [Symbol.toPrimitive]()
method, JavaScript calls the toString()
method automatically when a BigInt
object is used in a context expecting a string, such as in a template literal. However, BigInt primitive values do not consult the toString()
method to be coerced to strings — rather, they are directly converted using the same algorithm as the initial toString()
implementation.
BigInt.prototype.toString = () => "Overridden";
console.log(`${1n}`); // "1"
console.log(`${Object(1n)}`); // "Overridden"
Examples
Using toString()
17n.toString(); // "17"
66n.toString(2); // "1000010"
254n.toString(16); // "fe"
(-10n).toString(2); // "-1010"
(-0xffn).toString(2); // "-11111111"
Negative-zero BigInt
There is no negative-zero BigInt
as there are no negative zeros in integers. -0.0
is an IEEE floating-point concept that only appears in the JavaScript Number
type.
(-0n).toString(); // "0"
BigInt(-0).toString(); // "0"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-bigint.prototype.tostring |


Number.prototype.toString()

Number.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 Number
values returns a string representing this number value.
Try it
function hexColor(c) {
if (c < 256) {
return Math.abs(c).toString(16);
}
return 0;
}
console.log(hexColor(233));
// Expected output: "e9"
console.log(hexColor("11"));
// Expected output: "b"
Syntax
toString()
toString(radix)
Parameters
radix
Optional-
An integer in the range
2
through36
specifying the base to use for representing the number value. Defaults to 10.
Return value
A string representing the specified number value. Scientific notation is used if radix is 10 and the number's magnitude (ignoring sign) is greater than or equal to 1021 or less than 10-6.
Exceptions
RangeError
-
Thrown if
radix
is less than 2 or greater than 36. TypeError
-
Thrown if this method is invoked on an object that is not a
Number
.
Description
The Number
object overrides the toString
method of Object
; it does not inherit
Object.prototype.toString()
. For Number
values, the toString
method returns a string representation of the value in the specified radix.
For radixes above 10, the letters of the alphabet indicate digits greater than 9. For example, for hexadecimal numbers (base 16) a
through f
are used.
If the specified number value is negative, the sign is preserved. This is the case even if the radix is 2; the string returned is the positive binary representation of the number value preceded by a -
sign, not the two's complement of the number value.
Both 0
and -0
have "0"
as their string representation. Infinity
returns "Infinity"
and NaN
returns "NaN"
.
If the number is not a whole number, the decimal point .
is used to separate the decimal places. Scientific notation is used if the radix is 10 and the number's magnitude (ignoring sign) is greater than or equal to 1021 or less than 10-6. In this case, the returned string always explicitly specifies the sign of the exponent.
console.log((10 ** 21.5).toString()); // "3.1622776601683794e+21"
console.log((10 ** 21.5).toString(8)); // "526665530627250154000000"
The underlying representation for floating point numbers is base-2 scientific notation (see number encoding). However, the toString()
method doesn't directly use this most precise representation of the number value. Rather, the algorithm uses the least number of significant figures necessary to distinguish the output from adjacent number values. For example, if the number is large, there will be many equivalent string representations of the same floating point number, and toString()
will choose the one with the most 0s to the right (for any given radix).
console.log((1000000000000000128).toString()); // "1000000000000000100"
console.log(1000000000000000100 === 1000000000000000128); // true
On the other hand, Number.prototype.toFixed()
and Number.prototype.toPrecision()
allow you to specify the precision and can be more precise than toString()
.
The toString()
method requires its this
value to be a Number
primitive or wrapper object. It throws a TypeError
for other this
values without attempting to coerce them to number values.
Because Number
doesn't have a [Symbol.toPrimitive]()
method, JavaScript calls the toString()
method automatically when a Number
object is used in a context expecting a string, such as in a template literal. However, Number primitive values do not consult the toString()
method to be coerced to strings — rather, they are directly converted using the same algorithm as the initial toString()
implementation.
Number.prototype.toString = () => "Overridden";
console.log(`${1}`); // "1"
console.log(`${new Number(1)}`); // "Overridden"
Examples
Using toString()
const count = 10;
console.log(count.toString()); // "10"
console.log((17).toString()); // "17"
console.log((17.2).toString()); // "17.2"
const x = 6;
console.log(x.toString(2)); // "110"
console.log((254).toString(16)); // "fe"
console.log((-10).toString(2)); // "-1010"
console.log((-0xff).toString(2)); // "-11111111"
Converting radix of number strings
If you have a string representing a number in a non-decimal radix, you can use parseInt()
and toString()
to convert it to a different radix.
const hex = "CAFEBABE";
const bin = parseInt(hex, 16).toString(2); // "11001010111111101011101010111110"
Beware of loss of precision: if the original number string is too large (larger than Number.MAX_SAFE_INTEGER
, for example), you should use a BigInt
instead. However, the BigInt
constructor only has support for strings representing number literals (i.e., strings starting with 0b
, 0o
, 0x
). In case your original radix is not one of binary, octal, decimal, or hexadecimal, you may need to hand-write your radix converter, or use a library.
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-number.prototype.tostring |


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

# Original Wiki contributors
mfuji09
Quelklef
shaedrich
fscholz
jpmedley
wbamberg
Delapouite
Abbraxar
Youmoo
jameshkramer
UICreation
eduardoboucas
mrenty
ChrisMondok
Mingun
Sheppy
ethertank
ziyunfei
gary.court
Sevenspade
evilpie
Potappo
BenoitL
Mgjbot
Yuichirou
Maian
Marcoos
Dria


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

# Original Wiki contributors
mfuji09
wbamberg
fscholz
benaston
nakhodkiin
ihanson
vinyldarkscratch
Yialo
rkoeninger
yg448
snuggs
pmdartus
Sheppy
christophe.hurpeau
minstrel1977
jameshkramer
Velenir
ZeroUnderscoreOu
david_ross
darrenburgess
nmve
kdex
about-code
xfq
mata007
jleedev
jpmedley
reecehudson
bergus
fastest963
Mingun
Qantas94Heavy
ethertank
ziyunfei
fasttime
evilpie
Sevenspade
Nickolay
Andrea@3site.it
Seant23
Andreas Wuest


Symbol.toPrimitive

Symbol.toPrimitive
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.toPrimitive
static data property represents the well-known symbol Symbol.toPrimitive
. All type coercion algorithms look up this symbol on objects for the method that accepts a preferred type and returns a primitive representation of the object, before falling back to using the object's valueOf()
and toString()
methods.
Try it
const object = {
[Symbol.toPrimitive](hint) {
if (hint === "number") {
return 42;
}
return null;
},
};
console.log(+object);
// Expected output: 42
Value
The well-known symbol Symbol.toPrimitive
.
Property attributes of Symbol.toPrimitive | |
|---|---|
| Writable | no |
| Enumerable | no |
| Configurable | no |
Description
With the help of the Symbol.toPrimitive
property (used as a function value), an object can be converted to a primitive value. The function is called with a string argument hint
, which specifies the preferred type of the result primitive value. The hint
argument can be one of "number"
, "string"
, and "default"
.
The "number"
hint is used by numeric coercion algorithms. The "string"
hint is used by the string coercion algorithm. The "default"
hint is used by the primitive coercion algorithm. The hint
only acts as a weak signal of preference, and the implementation is free to ignore it (as Symbol.prototype[Symbol.toPrimitive]()
does). The language does not enforce alignment between the hint
and the result type, although [Symbol.toPrimitive]()
must return a primitive, or a TypeError
is thrown.
Objects without the [Symbol.toPrimitive]
property are converted to primitives by calling the valueOf()
and toString()
methods in different orders, which is explained in more detail in the type coercion section. [Symbol.toPrimitive]()
allows full control over the primitive conversion process. For example, Date.prototype[Symbol.toPrimitive]()
treats "default"
as if it's "string"
and calls toString()
instead of valueOf()
. Symbol.prototype[Symbol.toPrimitive]()
ignores the hint and always returns a symbol, which means even in string contexts, Symbol.prototype.toString()
won't be called, and Symbol
objects must always be explicitly converted to strings through String()
.
Examples
Modifying primitive values converted from an object
Following example describes how Symbol.toPrimitive
property can modify the primitive value converted from an object.
// An object without Symbol.toPrimitive property.
const obj1 = {};
console.log(+obj1); // NaN
console.log(`${obj1}`); // "[object Object]"
console.log(obj1 + ""); // "[object Object]"
// An object with Symbol.toPrimitive property.
const obj2 = {
[Symbol.toPrimitive](hint) {
if (hint === "number") {
return 10;
}
if (hint === "string") {
return "hello";
}
return true;
},
};
console.log(+obj2); // 10 — hint is "number"
console.log(`${obj2}`); // "hello" — hint is "string"
console.log(obj2 + ""); // "true" — hint is "default"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-symbol.toprimitive |


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


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


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 |


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

# Original Wiki contributors
gmanpersona
mfuji09
krvajal
MaximYaskov
fscholz
lionel-rowe
dfmartin
Wind1808
chrisdavidmills
Artoria2e5
dong-jy
zeta12ti
Waldo
ExE-Boss
pre1ude
johnmorseytest007
pepkin88
ross-u
Zearin_Galaurum
bmarkovic
Sheppy
Brettz9
paury
jonasraoni
SphinxKnight
shripal7
Konrud
wbamberg
schalkneethling
Jedipedia
wisgh
kubijo
autra
vandanasamudrala
jacobp100
jameshkramer
nmve
wbhob
madarche
matthung0807
eduardoboucas
whinc
doomsterinc
nickleus
noscripter
andfaulkner
kevinburkeshyp
kevinburke
chris.johnson
Mingun
ziyunfei
mlissner
miller.augusto
georgebatalinski
stevemao
miller_augusto
enaeseth
paul.irish
Nickolay
evilpie


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

# Original Wiki contributors
fscholz
mfluehr
minstrel1977
georgeawg
Mingun
toothbrush


Date.prototype.toISOString()

Date.prototype.toISOString()
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 toISOString()
method of Date
instances returns a string representing this date in the date time string format, a simplified format based on ISO 8601, which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ
or ±YYYYYY-MM-DDTHH:mm:ss.sssZ
, respectively). The timezone is always UTC, as denoted by the suffix Z
.
Try it
const event = new Date("05 October 2011 14:48 UTC");
console.log(event.toString());
// Expected output: "Wed Oct 05 2011 16:48:00 GMT+0200 (CEST)"
// Note: your timezone may vary
console.log(event.toISOString());
// Expected output: "2011-10-05T14:48:00.000Z"
Syntax
toISOString()
Parameters
None.
Return value
A string representing the given date in the date time string format according to universal time. It's the same format as the one required to be recognized by Date.parse()
.
Exceptions
RangeError
-
Thrown if the date is invalid or if it corresponds to a year that cannot be represented in the date string format.
Examples
Using toISOString()
const d = new Date(0);
console.log(d.toISOString()); // "1970-01-01T00:00:00.000Z"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-date.prototype.toisostring |


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


# 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


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

# Original Wiki contributors
mfuji09
chrisdavidmills
fscholz
alattalatta
stmoreau
wbamberg
jameshkramer
eduardoboucas
mhubenthal
Mingun
Sheppy
Norbert
ethertank
Yuichirou
Ptak82
Nickolay
Maian


BigInt.prototype.toLocaleString()

BigInt.prototype.toLocaleString()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2020.
The toLocaleString()
method of BigInt
values returns a string with a language-sensitive representation of this BigInt. In implementations with Intl.NumberFormat
API support, this method delegates to Intl.NumberFormat
.
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.NumberFormat
object and use its format()
method, because a NumberFormat
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.
Try it
const bigint = 123456789123456789n;
// German uses period for thousands
console.log(bigint.toLocaleString("de-DE"));
// Expected output: "123.456.789.123.456.789"
// Request a currency format
console.log(
bigint.toLocaleString("de-DE", { style: "currency", currency: "EUR" }),
);
// Expected output: "123.456.789.123.456.789,00 €"
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.NumberFormat
API, these parameters correspond exactly to the Intl.NumberFormat()
constructor's parameters. Implementations without Intl.NumberFormat
support are asked to ignore both parameters, making the locale used and the form of the string returned entirely implementation-dependent.
locales
Optional-
A string with a BCP 47 language tag, or an array of such strings. Corresponds to the
locales
parameter of theIntl.NumberFormat()
constructor.In implementations without
Intl.NumberFormat
support, this parameter is ignored and the host's locale is usually used. options
Optional-
An object adjusting the output format. Corresponds to the
options
parameter of theIntl.NumberFormat()
constructor.In implementations without
Intl.NumberFormat
support, this parameter is ignored.
See the Intl.NumberFormat()
constructor for details on these parameters and how to use them.
Return value
A string representing the given BigInt according to language-specific conventions.
In implementations with Intl.NumberFormat
, this is equivalent to new Intl.NumberFormat(locales, options).format(number)
.
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 bigint = 3500n;
console.log(bigint.toLocaleString());
// "3,500" if in U.S. English locale
Checking for support for locales and options parameters
The locales
and options
parameters may not be supported in all implementations, because support for the internationalization API is optional, and some systems may not have the necessary data. For implementations without internationalization support, toLocaleString()
always uses the system's locale, which may not be what you want. Because any implementation that supports the locales
and options
parameters must support the Intl
API, you can check the existence of the latter for support:
function toLocaleStringSupportsLocales() {
return (
typeof Intl === "object" &&
!!Intl &&
typeof Intl.NumberFormat === "function"
);
}
Using locales
This example shows some of the variations in localized number formats. In order to get
the format of the language used in the user interface of your application, make sure to
specify that language (and possibly some fallback languages) using the
locales
argument:
const bigint = 123456789123456789n;
// German uses period for thousands
console.log(bigint.toLocaleString("de-DE"));
// 123.456.789.123.456.789
// Arabic in most Arabic speaking countries uses Eastern Arabic digits
console.log(bigint.toLocaleString("ar-EG"));
// ١٢٣٬٤٥٦٬٧٨٩٬١٢٣٬٤٥٦٬٧٨٩
// India uses thousands/lakh/crore separators
console.log(bigint.toLocaleString("en-IN"));
// 1,23,45,67,89,12,34,56,789
// the nu extension key requests a numbering system, e.g. Chinese decimal
console.log(bigint.toLocaleString("zh-Hans-CN-u-nu-hanidec"));
// 一二三,四五六,七八九,一二三,四五六,七八九
// when requesting a language that may not be supported, such as
// Balinese, include a fallback language, in this case Indonesian
console.log(bigint.toLocaleString(["ban", "id"]));
// 123.456.789.123.456.789
Using options
The results provided by toLocaleString()
can be customized using the options
parameter:
const bigint = 123456789123456789n;
// request a currency format
console.log(
bigint.toLocaleString("de-DE", { style: "currency", currency: "EUR" }),
);
// 123.456.789.123.456.789,00 €
// the Japanese yen doesn't use a minor unit
console.log(
bigint.toLocaleString("ja-JP", { style: "currency", currency: "JPY" }),
);
// ￥123,456,789,123,456,789
// limit to three significant digits
console.log(bigint.toLocaleString("en-IN", { maximumSignificantDigits: 3 }));
// 1,23,00,00,00,00,00,00,000
Specifications
| Specification |
|---|
| ECMAScript® 2026 Internationalization API Specification # sup-bigint.prototype.tolocalestring |


Symbol.prototype.description

Symbol.prototype.description
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.
The description
accessor property of Symbol
values returns a string containing the description of this symbol, or undefined
if the symbol has no description.
Try it
console.log(Symbol("desc").description);
// Expected output: "desc"
console.log(Symbol.iterator.description);
// Expected output: "Symbol.iterator"
console.log(Symbol.for("foo").description);
// Expected output: "foo"
console.log(`${Symbol("foo").description}bar`);
// Expected output: "foobar"
Description
Symbol
objects can be created with an optional description which can be used for debugging but not to access the symbol itself. The Symbol.prototype.description
property can be used to read that description. It is different to Symbol.prototype.toString()
as it does not contain the enclosing "Symbol()"
string. See the examples.
Examples
Using description
js
Symbol("desc").toString(); // "Symbol(desc)"
Symbol("desc").description; // "desc"
Symbol("").description; // ""
Symbol().description; // undefined
// well-known symbols
Symbol.iterator.toString(); // "Symbol(Symbol.iterator)"
Symbol.iterator.description; // "Symbol.iterator"
// global symbols
Symbol.for("foo").toString(); // "Symbol(foo)"
Symbol.for("foo").description; // "foo"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-symbol.prototype.description |


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% |


BigInt.asUintN()

BigInt.asUintN()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2020.
The BigInt.asUintN()
static method truncates a BigInt
value to the given number of least significant bits and returns that value as an unsigned integer.
Try it
const U64_CEIL = 2n ** 64n;
console.log(BigInt.asUintN(64, U64_CEIL - 1n));
// 18446744073709551615n (2n ** 64n - 1n, the maximum non-wrapping value)
console.log(BigInt.asUintN(64, U64_CEIL));
// 0n (wraps to zero)
console.log(BigInt.asUintN(64, U64_CEIL + 1n));
// 1n
console.log(BigInt.asUintN(64, U64_CEIL * 2n));
// 0n (wraps on multiples)
console.log(BigInt.asUintN(64, U64_CEIL * -42n));
// 0n (also wraps on negative multiples)
Syntax
BigInt.asUintN(bits, bigint)
Parameters
Return value
The value of bigint
modulo 2 ** bits
, as an unsigned integer.
Exceptions
RangeError
-
Thrown if
bits
is negative or greater than 253 - 1.
Description
The BigInt.asUintN
method truncates a BigInt
value to the given number of bits, and interprets the result as an unsigned integer. Unsigned integers have no sign bits and are always non-negative. For example, for BigInt.asUintN(4, 25n)
, the value 25n
is truncated to 9n
:
25n = 00011001 (base 2) ^==== Use only the four remaining bits ===> 1001 (base 2) = 9n
Note:
BigInt
values are always encoded as two's complement in binary.
Unlike similar language APIs such as Number.prototype.toExponential()
, asUintN
is a static property of BigInt
, so you always use it as BigInt.asUintN()
, rather than as a method of a BigInt value. Exposing asUintN()
as a "standard library function" allows interop with asm.js.
Examples
Staying in 64-bit ranges
The BigInt.asUintN()
method can be useful to stay in the range of 64-bit arithmetic.
const max = 2n ** 64n - 1n;
BigInt.asUintN(64, max); // 18446744073709551615n
BigInt.asUintN(64, max + 1n); // 0n
// zero because of overflow: the lowest 64 bits are all zeros
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-bigint.asuintn |


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 |


Number.POSITIVE_INFINITY

Number.POSITIVE_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.POSITIVE_INFINITY
static data property represents the positive Infinity value.
Try it
function checkNumber(bigNumber) {
if (bigNumber === Number.POSITIVE_INFINITY) {
return "Process number as Infinity";
}
return bigNumber;
}
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 value of the global Infinity
property.
Property attributes of Number.POSITIVE_INFINITY | |
|---|---|
| Writable | no |
| Enumerable | no |
| Configurable | no |
Description
The Number.POSITIVE_INFINITY
value behaves slightly differently than mathematical infinity:
- Any positive value, including
POSITIVE_INFINITY
, multiplied byPOSITIVE_INFINITY
isPOSITIVE_INFINITY
. - Any negative value, including
NEGATIVE_INFINITY
, multiplied byPOSITIVE_INFINITY
isNEGATIVE_INFINITY
. - Any positive number divided by
POSITIVE_INFINITY
is positive zero (as defined in IEEE 754). - Any negative number divided by
POSITIVE_INFINITY
is negative zero (as defined in IEEE 754. - Zero multiplied by
POSITIVE_INFINITY
isNaN
. NaN
multiplied byPOSITIVE_INFINITY
isNaN
.POSITIVE_INFINITY
, divided by any negative value exceptNEGATIVE_INFINITY
, isNEGATIVE_INFINITY
.POSITIVE_INFINITY
, divided by any positive value exceptPOSITIVE_INFINITY
, isPOSITIVE_INFINITY
.POSITIVE_INFINITY
, divided by eitherNEGATIVE_INFINITY
orPOSITIVE_INFINITY
, isNaN
.Number.POSITIVE_INFINITY > x
is true for any number x that isn'tPOSITIVE_INFINITY
.
You might use the Number.POSITIVE_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 POSITIVE_INFINITY
is a static property of Number
, you always use it as Number.POSITIVE_INFINITY
, rather than as a property of a number value.
Examples
Using POSITIVE_INFINITY
In the following example, the variable bigNumber
is assigned a value that is larger than the maximum value. When the if
statement executes, bigNumber
has the value Infinity
, so bigNumber
is set to a more manageable value before continuing.
let bigNumber = Number.MAX_VALUE * 2;
if (bigNumber === Number.POSITIVE_INFINITY) {
bigNumber = returnFinite();
}
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-number.positive_infinity |


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/symbol/toprimitive/index.md

# Original Wiki contributors
mfuji09
fscholz
wbamberg
Delapouite
jameshkramer
GreenJello
nmve
Konrud
kdex
HugoGiraudel
ZeikJT
The-Quill
arai


String() constructor

String() constructor
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 String()
constructor creates String
objects. When called as a function, it returns primitive values of type String.
Syntax
new String(thing)
String(thing)
Note:
String()
can be called with or without new
, but with different effects. See Return value.
Parameters
thing
-
Anything to be converted to a string.
Return value
When String()
is called as a function (without new
), it returns value
coerced to a string primitive. Specially, Symbol values are converted to "Symbol(description)"
, where description
is the description of the Symbol, instead of throwing.
When String()
is called as a constructor (with new
), it coerces value
to a string primitive (without special symbol handling) and returns a wrapping String
object, which is not a primitive.
Warning:
You should rarely find yourself using String
as a constructor.
Examples
String constructor and String function
String function and String constructor produce different results:
const a = new String("Hello world"); // a === "Hello world" is false
const b = String("Hello world"); // b === "Hello world" is true
a instanceof String; // is true
b instanceof String; // is false
typeof a; // "object"
typeof b; // "string"
Here, the function produces a string (the primitive type) as promised. However, the constructor produces an instance of the type String (an object wrapper) and that's why you rarely want to use the String constructor at all.
Using String() to stringify a symbol
String()
is the only case where a symbol can be converted to a string without throwing, because it's very explicit.
const sym = Symbol("example");
`${sym}`; // TypeError: Cannot convert a Symbol value to a string
"" + sym; // TypeError: Cannot convert a Symbol value to a string
"".concat(sym); // TypeError: Cannot convert a Symbol value to a string
const sym = Symbol("example");
String(sym); // "Symbol(example)"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-string-constructor |
Browser compatibility
See also
- Numbers and strings guide


Date.prototype[Symbol.toPrimitive]()

Date.prototype[Symbol.toPrimitive]()
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.toPrimitive]()
method of Date
instances returns a primitive value representing this date. It may either be a string or a number, depending on the hint given.
Try it
// Depending on timezone, your results will vary
const date = new Date("20 December 2019 14:48");
console.log(date[Symbol.toPrimitive]("string"));
// Expected output: "Fri Dec 20 2019 14:48:00 GMT+0530 (India Standard Time)"
console.log(date[Symbol.toPrimitive]("number"));
// Expected output: 1576833480000
Syntax
date[Symbol.toPrimitive](hint)
Parameters
hint
-
A string representing the type of the primitive value to return. The following values are valid:
"string"
or"default"
: The method should return a string."number"
: The method should return a number.
Return value
If hint
is "string"
or "default"
, this method returns a string by coercing the this
value to a string (first trying toString()
then trying valueOf()
).
If hint
is "number"
, this method returns a number by coercing the this
value to a number (first trying valueOf()
then trying toString()
).
Exceptions
TypeError
-
Thrown if the
hint
argument is not one of the three valid values.
Description
The [Symbol.toPrimitive]()
method is part of the type coercion protocol. JavaScript always calls the [Symbol.toPrimitive]()
method in priority to convert an object to a primitive value. You rarely need to invoke the [Symbol.toPrimitive]()
method yourself; JavaScript automatically invokes it when encountering an object where a primitive value is expected.
The [Symbol.toPrimitive]()
method of the Date
object returns a primitive value by either invoking this.valueOf()
and returning a number, or invoking this.toString()
and returning a string. It exists to override the default primitive coercion process to return a string instead of a number, because primitive coercion, by default, calls valueOf()
before toString()
. With the custom [Symbol.toPrimitive]()
, new Date(0) + 1
returns "Thu Jan 01 1970 00:00:00 GMT+0000 (Coordinated Universal Time)1"
(a string) instead of 1
(a number).
Examples
Using [Symbol.toPrimitive]()
const d = new Date(0); // 1970-01-01T00:00:00.000Z
d[Symbol.toPrimitive]("string"); // "Thu Jan 01 1970 00:00:00 GMT+0000 (Coordinated Universal Time)"
d[Symbol.toPrimitive]("number"); // 0
d[Symbol.toPrimitive]("default"); // "Thu Jan 01 1970 00:00:00 GMT+0000 (Coordinated Universal Time)"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-date.prototype-%symbol.toprimitive% |


# 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