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

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


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 |


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 |


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

# Original Wiki contributors
fscholz


Date.prototype.toLocaleTimeString()

Date.prototype.toLocaleTimeString()
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 toLocaleTimeString()
method of Date
instances returns a string with a language-sensitive representation of the time portion of this date in the local timezone. In implementations with Intl.DateTimeFormat
API support, this method delegates to Intl.DateTimeFormat
.
Every time toLocaleTimeString
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.DateTimeFormat
object and use its format()
method, because a DateTimeFormat
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
// Depending on timezone, your results will vary
const event = new Date("August 19, 1975 23:15:30 GMT+00:00");
console.log(event.toLocaleTimeString("en-US"));
// Expected output: "1:15:30 AM"
console.log(event.toLocaleTimeString("it-IT"));
// Expected output: "01:15:30"
console.log(event.toLocaleTimeString("ar-EG"));
// Expected output: "١٢:١٥:٣٠ ص"
Syntax
toLocaleTimeString()
toLocaleTimeString(locales)
toLocaleTimeString(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.DateTimeFormat
API, these parameters correspond exactly to the Intl.DateTimeFormat()
constructor's parameters. Implementations without Intl.DateTimeFormat
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.DateTimeFormat()
constructor.In implementations without
Intl.DateTimeFormat
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.DateTimeFormat()
constructor. IfdayPeriod
,hour
,minute
,second
, andfractionalSecondDigits
are all undefined, thenhour
,minute
,second
will be set to"numeric"
.In implementations without
Intl.DateTimeFormat
support, this parameter is ignored.
See the Intl.DateTimeFormat()
constructor for details on these parameters and how to use them.
Return value
A string representing the time portion of the given date according to language-specific conventions.
In implementations with Intl.DateTimeFormat
, this is equivalent to new Intl.DateTimeFormat(locales, options).format(date)
, where options
has been normalized as described above.
Note:
Most of the time, the formatting returned by toLocaleTimeString()
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 toLocaleTimeString()
to hardcoded constants.
Examples
Using toLocaleTimeString()
Basic use of this method without specifying a locale
returns a formatted string in the default locale and with default options.
const date = new Date(Date.UTC(2012, 11, 12, 3, 0, 0));
// toLocaleTimeString() without arguments depends on the implementation,
// the default locale, and the default time zone
console.log(date.toLocaleTimeString());
// "7:00:00 PM" if run in en-US locale with time zone America/Los_Angeles
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, toLocaleTimeString()
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 toLocaleTimeStringSupportsLocales() {
return (
typeof Intl === "object" &&
!!Intl &&
typeof Intl.DateTimeFormat === "function"
);
}
Using locales
This example shows some of the variations in localized time 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 date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
// formats below assume the local time zone of the locale;
// America/Los_Angeles for the US
// US English uses 12-hour time with AM/PM
console.log(date.toLocaleTimeString("en-US"));
// "7:00:00 PM"
// British English uses 24-hour time without AM/PM
console.log(date.toLocaleTimeString("en-GB"));
// "03:00:00"
// Korean uses 12-hour time with AM/PM
console.log(date.toLocaleTimeString("ko-KR"));
// "오후 12:00:00"
// Arabic in most Arabic speaking countries uses real Arabic digits
console.log(date.toLocaleTimeString("ar-EG"));
// "٧:٠٠:٠٠ م"
// when requesting a language that may not be supported, such as
// Balinese, include a fallback language, in this case Indonesian
console.log(date.toLocaleTimeString(["ban", "id"]));
// "11.00.00"
Using options
The results provided by toLocaleTimeString()
can be customized using the options
parameter:
const date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
// An application may want to use UTC and make that visible
const options = { timeZone: "UTC", timeZoneName: "short" };
console.log(date.toLocaleTimeString("en-US", options));
// "3:00:00 AM GMT"
// Sometimes even the US needs 24-hour time
console.log(date.toLocaleTimeString("en-US", { hour12: false }));
// "19:00:00"
// Show only hours and minutes, use options with the default locale - use an empty array
console.log(
date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }),
);
// "20:01"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification # sec-date.prototype.tolocaletimestring |
| ECMAScript® 2026 Internationalization API Specification # sup-date.prototype.tolocaletimestring |


# 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/errors/constructor_cant_be_used_directly/index.md


TypeError: X.prototype.y called on incompatible type
The JavaScript exception "called on incompatible target (or object)" occurs when a
function (on a given object), is called with a this
not corresponding to
the type expected by the function.
Message
TypeError: Method Set.prototype.add called on incompatible receiver undefined (V8-based) TypeError: Bind must be called on a function (V8-based) TypeError: Illegal invocation (V8-based) TypeError: Function.prototype.toString requires that 'this' be a Function (V8-based) TypeError: this is not a Date object. (V8-based) TypeError: this is not a typed array. (V8-based) TypeError: Function.prototype.toString called on incompatible object (Firefox) TypeError: Function.prototype.bind called on incompatible target (Firefox) TypeError: 'addEventListener' called on an object that does not implement interface EventTarget. (Firefox) TypeError: Type error (Safari) TypeError: undefined is not an object (Safari)
Error type
TypeError
What went wrong?
When this error is thrown, a function (on a given object), is called with a
this
not corresponding to the type expected by the function.
This issue can arise when using the Function.prototype.call()
or
Function.prototype.apply()
methods, and providing a this
argument which does not have the expected type.
This issue can also happen when providing a function that is stored as a property of an
object as an argument to another function. In this case, the object that stores the
function won't be the this
target of that function when it is called by the
other function. To work-around this issue, you will either need to wrap the callback function in another function, or use the Function.prototype.bind()
method to
force the this
argument to the expected object.
Examples
Invalid cases
const mySet = new Set();
["bar", "baz"].forEach(mySet.add);
// mySet.add is a function, but "mySet" is not captured as this.
function myFun() {
console.log(this);
}
["bar", "baz"].forEach(myFun.bind);
// myFun.bind is a function, but "myFun" is not captured as this.
Valid cases
const mySet = new Set();
["bar", "baz"].forEach(mySet.add.bind(mySet));
// This works due to binding "mySet" as this.
function myFun() {
console.log(this);
}
["bar", "baz"].forEach((x) => myFun.bind(x));
// This works using the "bind" function. It creates a new function forwarding the argument.


Strict mode

Strict mode
Note: Sometimes you'll see the default, non-strict mode referred to as sloppy mode. This isn't an official term, but be aware of it, just in case.
JavaScript's strict mode is a way to opt in to a restricted variant of JavaScript, thereby implicitly opting-out of "sloppy mode". Strict mode isn't just a subset: it intentionally has different semantics from normal code. Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally.
Strict mode makes several changes to normal JavaScript semantics:
- Eliminates some JavaScript silent errors by changing them to throw errors.
- Fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that's not strict mode.
- Prohibits some syntax likely to be defined in future versions of ECMAScript.
Invoking strict mode
Strict mode applies to entire scripts or to individual functions. It doesn't apply to block statements enclosed in {}
braces; attempting to apply it to such contexts does nothing. eval
code, Function
code, event handler attributes, strings passed to setTimeout()
, and related functions are either function bodies or entire scripts, and invoking strict mode in them works as expected.
Strict mode for scripts
To invoke strict mode for an entire script, put the exact statement "use strict";
(or 'use strict';
) before any other statements.
// Whole-script strict mode syntax
"use strict";
const v = "Hi! I'm a strict mode script!";
Strict mode for functions
Likewise, to invoke strict mode for a function, put the exact statement "use strict";
(or 'use strict';
) in the function's body before any other statements.
function myStrictFunction() {
// Function-level strict mode syntax
"use strict";
function nested() {
return "And so am I!";
}
return `Hi! I'm a strict mode function! ${nested()}`;
}
function myNotStrictFunction() {
return "I'm not strict.";
}
The "use strict"
directive can only be applied to the body of functions with simple parameters. Using "use strict"
in functions with rest, default, or destructured parameters is a syntax error.
function sum(a = 1, b = 2) {
// SyntaxError: "use strict" not allowed in function with default parameter
"use strict";
return a + b;
}
Strict mode for modules
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
function myStrictFunction() {
// because this is a module, I'm strict by default
}
export default myStrictFunction;
Strict mode for classes
All parts of a class's body are strict mode code, including both class declarations and class expressions.
class C1 {
// All code here is evaluated in strict mode
test() {
delete Object.prototype;
}
}
new C1().test(); // TypeError, because test() is in strict mode
const C2 = class {
// All code here is evaluated in strict mode
};
// Code here may not be in strict mode
delete Object.prototype; // Will not throw error
Changes in strict mode
Strict mode changes both syntax and runtime behavior. Changes generally fall into these categories:
- changes converting mistakes into errors (as syntax errors or at runtime)
- changes simplifying how variable references are resolved
- changes simplifying
eval
andarguments
- changes making it easier to write "secure" JavaScript
- changes anticipating future ECMAScript evolution.
Converting mistakes into errors
Strict mode changes some previously-accepted mistakes into errors. JavaScript was designed to be easy for novice developers, and sometimes it gives operations which should be errors non-error semantics. Sometimes this fixes the immediate problem, but sometimes this creates worse problems in the future. Strict mode treats these mistakes as errors so that they're discovered and promptly fixed.
Assigning to undeclared variables
Strict mode makes it impossible to accidentally create global variables. In sloppy mode, mistyping a variable in an assignment creates a new property on the global object and continues to "work". Assignments which would accidentally create global variables throw an error in strict mode:
"use strict";
let mistypeVariable;
// Assuming no global variable mistypeVarible exists
// this line throws a ReferenceError due to the
// misspelling of "mistypeVariable" (lack of an "a")
mistypeVarible = 17;
Failing to assign to object properties
Strict mode makes assignments which would otherwise silently fail to throw an exception. There are three ways to fail a property assignment:
- assignment to a non-writable data property
- assignment to a getter-only accessor property
- assignment to a new property on a non-extensible object
For example, NaN
is a non-writable global variable. In sloppy mode, assigning to NaN
does nothing; the developer receives no failure feedback. In strict mode, assigning to NaN
throws an exception.
"use strict";
// Assignment to a non-writable global
undefined = 5; // TypeError
Infinity = 5; // TypeError
// Assignment to a non-writable property
const obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // TypeError
// Assignment to a getter-only property
const obj2 = {
get x() {
return 17;
},
};
obj2.x = 5; // TypeError
// Assignment to a new property on a non-extensible object
const fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // TypeError
Failing to delete object properties
Attempts to delete a non-configurable or otherwise undeletable (e.g., it's intercepted by a proxy's deleteProperty
handler which returns false
) property throw in strict mode (where before the attempt would have no effect):
"use strict";
delete Object.prototype; // TypeError
delete [].length; // TypeError
Strict mode also forbids deleting plain names. delete name
in strict mode is a syntax error:
"use strict";
var x;
delete x; // syntax error
If the name is a configurable global property, prefix it with globalThis
to delete it.
"use strict";
delete globalThis.x;
Duplicate parameter names
Strict mode requires that function parameter names be unique. In sloppy mode, the last duplicated argument hides previous identically-named arguments. Those previous arguments remain available through arguments
, so they're not completely inaccessible. Still, this hiding makes little sense and is probably undesirable (it might hide a typo, for example), so in strict mode, duplicate argument names are a syntax error:
function sum(a, a, c) {
// syntax error
"use strict";
return a + a + c; // wrong if this code ran
}
It is also a syntax error in non-strict mode to have duplicate parameter names, if the function has a default parameter, rest parameter, or destructured parameter.
Legacy octal literals
Strict mode forbids a 0
-prefixed octal literal. In sloppy mode, a number beginning with a 0
, such as 0644
, is interpreted as an octal number (0644 === 420
), if all digits are smaller than 8. Novice developers sometimes believe a leading-zero prefix has no semantic meaning, so they might use it as an alignment device — but this changes the number's meaning! A leading-zero syntax for the octal is rarely useful and can be mistakenly used, so strict mode makes it a syntax error:
"use strict";
const sum =
015 + // syntax error
197 +
142;
The standardized way to denote octal literals is via the 0o
prefix. For example:
const sumWithOctal = 0o10 + 8;
console.log(sumWithOctal); // 16
Octal escape sequences, such as "\45"
, which is equal to "%"
, can be used to represent characters by extended-ASCII character code numbers in octal. In strict mode, this is a syntax error. More formally, it's disallowed to have \
followed by any decimal digit other than 0
, or \0
followed by a decimal digit; for example \9
and \07
.
Setting properties on primitive values
Strict mode forbids setting properties on primitive values. Accessing a property on a primitive implicitly creates a wrapper object that's unobservable, so in sloppy mode, setting properties is ignored (no-op). In strict mode, a TypeError
is thrown.
"use strict";
false.true = ""; // TypeError
(14).sailing = "home"; // TypeError
"with".you = "far away"; // TypeError
Duplicate property names
Duplicate property names used to be considered a SyntaxError
in strict mode. With the introduction of computed property names, making duplication possible at runtime, this restriction was removed in ES2015.
"use strict";
const o = { p: 1, p: 2 }; // syntax error prior to ECMAScript 2015
Note: Making code that used to error become non-errors is always considered backwards-compatible. This is a good part of the language being strict about throwing errors: it leaves room for future semantic changes.
Simplifying scope management
Strict mode simplifies how variable names map to particular variable definitions in the code. Many compiler optimizations rely on the ability to say that variable X is stored in that location: this is critical to fully optimizing JavaScript code. JavaScript sometimes makes this basic mapping of name to variable definition in the code impossible to perform until runtime. Strict mode removes most cases where this happens, so the compiler can better optimize strict mode code.
Removal of the with statement
Strict mode prohibits with
. The problem with with
is that any name inside the block might map either to a property of the object passed to it, or to a variable in surrounding (or even global) scope, at runtime; it's impossible to know which beforehand. Strict mode makes with
a syntax error, so there's no chance for a name in a with
to refer to an unknown location at runtime:
"use strict";
const x = 17;
with (obj) {
// Syntax error
// If this weren't strict mode, would this be const x, or
// would it instead be obj.x? It's impossible in general
// to say without running the code, so the name can't be
// optimized.
x;
}
The alternative of assigning the object to a short name variable, then accessing the corresponding property on that variable, stands ready to replace with
.
Non-leaking eval
In strict mode, eval
does not introduce new variables into the surrounding scope. In sloppy mode, eval("var x;")
introduces a variable x
into the surrounding function or the global scope. This means that, in general, in a function containing a call to eval
, every name not referring to an argument or local variable must be mapped to a particular definition at runtime (because that eval
might have introduced a new variable that would hide the outer variable). In strict mode, eval
creates variables only for the code being evaluated, so eval
can't affect whether a name refers to an outer variable or some local variable:
var x = 17;
var evalX = eval("'use strict'; var x = 42; x;");
console.assert(x === 17);
console.assert(evalX === 42);
Whether the string passed to eval()
is evaluated in strict mode depends on how eval()
is invoked (direct eval or indirect eval).
Block-scoped function declarations
The JavaScript language specification, since its start, had not allowed function declarations nested in block statements. However, it was so intuitive that most browsers implemented it as an extension grammar. Unfortunately, the implementations' semantics diverged, and it became impossible for the language specification to reconcile all implementations. Therefore, block-scoped function declarations are only explicitly specified in strict mode (whereas they were once disallowed in strict mode), while sloppy mode behavior remains divergent among browsers.
Making eval and arguments simpler
Strict mode makes arguments
and eval
less bizarrely magical. Both involve a considerable amount of magical behavior in sloppy mode: eval
to add or remove bindings and to change binding values, and arguments
syncing named arguments with its indexed properties. Strict mode makes great strides toward treating eval
and arguments
as keywords.
Preventing binding or assigning eval and arguments
The names eval
and arguments
can't be bound or assigned in language syntax. All these attempts to do so are syntax errors:
"use strict";
eval = 17;
arguments++;
++eval;
const obj = { set p(arguments) {} };
let eval;
try {
} catch (arguments) {}
function x(eval) {}
function arguments() {}
const y = function eval() {};
const f = new Function("arguments", "'use strict'; return 17;");
No syncing between parameters and arguments indices
Strict mode code doesn't sync indices of the arguments
object with each parameter binding. In a sloppy mode function whose first argument is arg
, setting arg
also sets arguments[0]
, and vice versa (unless no arguments were provided or arguments[0]
is deleted). arguments
objects for strict mode functions store the original arguments when the function was invoked. arguments[i]
does not track the value of the corresponding named argument, nor does a named argument track the value in the corresponding arguments[i]
.
function f(a) {
"use strict";
a = 42;
return [a, arguments[0]];
}
const pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);
"Securing" JavaScript
Strict mode makes it easier to write "secure" JavaScript. Some websites now provide ways for users to write JavaScript which will be run by the website on behalf of other users. JavaScript in browsers can access the user's private information, so such JavaScript must be partially transformed before it is run, to censor access to forbidden functionality. JavaScript's flexibility makes it effectively impossible to do this without many runtime checks. Certain language functions are so pervasive that performing runtime checks has a considerable performance cost. A few strict mode tweaks, plus requiring that user-submitted JavaScript be strict mode code and that it be invoked in a certain manner, substantially reduce the need for those runtime checks.
No this substitution
The value passed as this
to a function in strict mode is not forced into being an object (a.k.a. "boxed"). For a sloppy mode function, this
is always an object: either the provided object, if called with an object-valued this
; or the boxed value of this
, if called with a primitive as this
; or the global object, if called with undefined
or null
as this
. (Use call
, apply
, or bind
to specify a particular this
.) Not only is automatic boxing a performance cost, but exposing the global object in browsers is a security hazard because the global object provides access to functionality that "secure" JavaScript environments must restrict. Thus for a strict mode function, the specified this
is not boxed into an object, and if unspecified, this
is undefined
instead of globalThis
:
"use strict";
function fun() {
return this;
}
console.assert(fun() === undefined);
console.assert(fun.call(2) === 2);
console.assert(fun.apply(null) === null);
console.assert(fun.call(undefined) === undefined);
console.assert(fun.bind(true)() === true);
Removal of stack-walking properties
In strict mode it's no longer possible to "walk" the JavaScript stack. Many implementations used to implement some extension features that make it possible to detect the upstream caller of a function. When a function fun
is in the middle of being called, fun.caller
is the function that most recently called fun
, and fun.arguments
is the arguments
for that invocation of fun
. Both extensions are problematic for "secure" JavaScript because they allow "secured" code to access "privileged" functions and their (potentially unsecured) arguments. If fun
is in strict mode, both fun.caller
and fun.arguments
are non-deletable properties which throw when set or retrieved:
function restricted() {
"use strict";
restricted.caller; // throws a TypeError
restricted.arguments; // throws a TypeError
}
function privilegedInvoker() {
return restricted();
}
privilegedInvoker();
Similarly, arguments.callee
is no longer supported. In sloppy mode, arguments.callee
refers to the enclosing function. This use case is weak: name the enclosing function! Moreover, arguments.callee
substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if arguments.callee
is accessed. arguments.callee
for strict mode functions is a non-deletable property which throws an error when set or retrieved:
"use strict";
function f() {
return arguments.callee;
}
f(); // throws a TypeError
Future-proofing JavaScript
Extra reserved words
Reserved words are identifiers that can't be used as variable names. Strict mode reserves some more names than sloppy mode, some of which are already used in the language, and some of which are reserved for the future to make future syntax extensions easier to implement.
Transitioning to strict mode
Strict mode has been designed so that the transition to it can be made gradually. It is possible to change each file individually and even to transition code to strict mode down to the function granularity.
You can migrate a codebase to strict mode by first adding "use strict"
to a piece of source code, and then fixing all execution errors, while watching out for semantic differences.
Syntax errors
When adding 'use strict';
, the following cases will throw a SyntaxError
before the script is executing:
- Octal syntax
const n = 023;
with
statement- Using
delete
on a variable namedelete myVariable
; - Using
eval
orarguments
as variable or function argument name - Using one of the newly reserved keywords (in prevision for future language features):
implements
,interface
,let
,package
,private
,protected
,public
,static
, andyield
- Declaring two function parameters with the same name
function f(a, b, b) {}
- Declaring the same property name twice in an object literal
{a: 1, b: 3, a: 7}
. This constraint was later removed (bug 1041128).
These errors are good, because they reveal plain errors or bad practices. They occur before the code is running, so they are easily discoverable as long as the code gets parsed by the runtime.
New runtime errors
JavaScript used to silently fail in contexts where what was done should be an error. Strict mode throws in such cases. If your code base contains such cases, testing will be necessary to be sure nothing is broken. You can screen for such errors at the function granularity level.
- Assigning to an undeclared variable throws a
ReferenceError
. This used to set a property on the global object, which is rarely the expected effect. If you really want to set a value to the global object, explicitly assign it as a property onglobalThis
. - Failing to assign to an object's property (e.g., it's read-only) throws a
TypeError
. In sloppy mode, this would silently fail. - Deleting a non-deletable property throws a
TypeError
. In sloppy mode, this would silently fail. - Accessing
arguments.callee
,strictFunction.caller
, orstrictFunction.arguments
throws aTypeError
if the function is in strict mode. If you are usingarguments.callee
to call the function recursively, you can use a named function expression instead.
Semantic differences
These differences are very subtle differences. It's possible that a test suite doesn't catch this kind of subtle difference. Careful review of your code base will probably be necessary to be sure these differences don't affect the semantics of your code. Fortunately, this careful review can be done gradually down the function granularity.
this
-
In sloppy mode, function calls like
f()
would pass the global object as thethis
value. In strict mode, it is nowundefined
. When a function was called withcall
orapply
, if the value was a primitive value, this one was boxed into an object (or the global object forundefined
andnull
). In strict mode, the value is passed directly without conversion or replacement. arguments
-
In sloppy mode, modifying a value in the
arguments
object modifies the corresponding named argument. This made optimizations complicated for JavaScript engine and made code harder to read/understand. In strict mode, thearguments
object is created and initialized with the same values than the named arguments, but changes to either thearguments
object or the named arguments aren't reflected in one another. eval
-
In strict mode code,
eval
doesn't create a new variable in the scope from which it was called. Also, of course, in strict mode, the string is evaluated with strict mode rules. Thorough testing will need to be performed to make sure nothing breaks. Not using eval if you don't really need it may be another pragmatic solution. - Block-scoped function declarations
-
In sloppy mode, a function declaration inside a block may be visible outside the block and even callable. In strict mode, a function declaration inside a block is only visible inside the block.
Specifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification |


Intl.DurationFormat.prototype.resolvedOptions()
Baseline
2025
Newly available
Since March 2025, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
The resolvedOptions()
method of Intl.DurationFormat
instances returns a new object with properties reflecting the options computed during initialization of this DurationFormat
object.
Syntax
resolvedOptions()
Parameters
None.
Return value
A new object with properties reflecting the options computed during the initialization of this DurationFormat
object. The object has the following properties, in the order they are listed:
locale
-
The BCP 47 language tag for the locale actually used, determined by the locale negotiation process. Only the
nu
Unicode extension key, if requested, may be included in the output. numberingSystem
-
The value provided for this property in the
options
argument, or using the Unicode extension key"nu"
, with default filled in as needed. It is a supported numbering system for this locale. The default is locale dependent. style
-
The value provided for this property in the
options
argument, with default filled in as needed. It is either"long"
,"short"
,"narrow"
, or"digital"
. The default is"short"
. years
,yearsDisplay
,months
,monthsDisplay
,weeks
,weeksDisplay
,days
,daysDisplay
,hours
,hoursDisplay
,minutes
,minutesDisplay
,seconds
,secondsDisplay
,milliseconds
,millisecondsDisplay
,nanoseconds
,nanosecondsDisplay
-
The values provided for these properties in the
options
argument, with defaults filled in as needed. For the valid values and defaults for each, see theoptions
argument of the constructor. fractionalDigits
Optional-
The value provided for this property in the
options
argument. It is only present if specified inoptions
. It is an integer from 0 to 9, inclusive.
Examples
Using the resolvedOptions method
const duration = new Intl.DurationFormat("en");
const usedOptions = duration.resolvedOptions();
usedOptions.locale; // "en"
usedOptions.numberingSystem; // "latn"
usedOptions.years; // "long"
usedOptions.yearsDisplay; // "auto"
usedOptions.style; // "long"
Specifications
| Specification |
|---|
| Intl.DurationFormat # sec-Intl.DurationFormat.prototype.resolvedOptions |


TypeError: WeakSet key/WeakMap value 'x' must be an object or an unregistered symbol
The JavaScript exception "WeakSet key (or WeakMap value) 'x' must be an object or an unregistered symbol" occurs when a value of invalid type is used as a key in a WeakSet
or as a value in a WeakMap
.
Message
TypeError: Invalid value used as weak map key (V8-based) TypeError: WeakMap key 1 must be an object or an unregistered symbol (Firefox) TypeError: WeakMap keys must be objects or non-registered symbols (Safari) TypeError: Invalid value used in weak set (V8-based) TypeError: WeakSet value 1 must be an object or an unregistered symbol (Firefox) TypeError: WeakSet values must be objects or non-registered symbols (Safari)
Error type
TypeError
What went wrong?
WeakSet
and WeakMap
require the keys to be garbage collectable. Only objects and non-registered symbols (that is, symbols not returned by Symbol.for()
) are valid. For more information, see Memory management. If you want to add keys that are strings, numbers, or other primitive values, you should store them in a regular Set
or Map
instead.
Examples
Invalid cases
js
new WeakSet().add(1); // TypeError
new WeakMap().set(1, {}); // TypeError
new WeakSet([1]); // TypeError
new WeakMap([[1, {}]]); // TypeError
Valid cases
js
new WeakSet().add({}); // OK
new WeakMap().set({}, 1); // OK
new Set([1]); // OK
new Map([[1, {}]]); // OK


Intl.Collator.supportedLocalesOf()

Intl.Collator.supportedLocalesOf()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2017.
The Intl.Collator.supportedLocalesOf()
static method returns an array containing those of the provided locales that are supported in collation without having to fall back to the runtime's default locale.
Try it
const locales = ["ban", "id-u-co-pinyin", "de-ID"];
const options = { localeMatcher: "lookup" };
console.log(Intl.Collator.supportedLocalesOf(locales, options));
// Expected output: Array ["id-u-co-pinyin", "de-ID"]
// (Note: the exact output may be browser-dependent)
Syntax
Intl.Collator.supportedLocalesOf(locales)
Intl.Collator.supportedLocalesOf(locales, options)
Parameters
locales
-
A string with a BCP 47 language tag, or an array of such strings. For the general form and interpretation of the
locales
argument, see the parameter description on theIntl
main page. options
Optional-
An object that may have the following property:
localeMatcher
-
The locale matching algorithm to use. Possible values are
"lookup"
and"best fit"
; the default is"best fit"
. For information about this option, see the Intl page.
Return value
An array of strings representing a subset of the given locale tags that are supported in collation without having to fall back to the runtime's default locale.
Examples
Using supportedLocalesOf()
Assuming a runtime that supports Indonesian and German but not Balinese in collation, supportedLocalesOf
returns the Indonesian and German language tags unchanged, even though pinyin
collation is not used with Indonesian, and a specialized German for Indonesia is unlikely to be supported. Note the specification of the "lookup"
algorithm here — a "best fit"
matcher might decide that Indonesian is an adequate match for Balinese since most Balinese speakers also understand Indonesian, and therefore return the Balinese language tag as well.
const locales = ["ban", "id-u-co-pinyin", "de-ID"];
const options = { localeMatcher: "lookup" };
console.log(Intl.Collator.supportedLocalesOf(locales, options));
// ["id-u-co-pinyin", "de-ID"]
Specifications
| Specification |
|---|
| ECMAScript® 2026 Internationalization API Specification # sec-intl.collator.supportedlocalesof |


TypeError: null/undefined has no properties
The JavaScript exception "null (or undefined) has no properties" occurs when you
attempt to access properties of null
and undefined
. They
don't have any.
Message
TypeError: Cannot read properties of undefined (reading 'x') (V8-based) TypeError: Cannot destructure 'x' as it is undefined. (V8-based) TypeError: Cannot destructure property 'x' of 'y' as it is undefined. (V8-based) TypeError: null has no properties (Firefox) TypeError: undefined has no properties (Firefox) TypeError: undefined is not an object (evaluating 'undefined.x') (Safari) TypeError: Right side of assignment cannot be destructured (Safari)
Error type
What went wrong?
Both null
and undefined
have no properties you could access. Therefore, you cannot use property accessors on them, or destructure them.
Examples
null and undefined have no properties
js
null.foo;
// TypeError: null has no properties
undefined.bar;
// TypeError: undefined has no properties


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


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


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


Intl.getCanonicalLocales()

Intl.getCanonicalLocales()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.
The Intl.getCanonicalLocales()
static method returns an array
containing the canonical locale names. Duplicates will be omitted and elements will be
validated as structurally valid language tags.
Try it
console.log(Intl.getCanonicalLocales("EN-US"));
// Expected output: Array ["en-US"]
console.log(Intl.getCanonicalLocales(["EN-US", "Fr"]));
// Expected output: Array ["en-US", "fr"]
try {
Intl.getCanonicalLocales("EN_US");
} catch (err) {
console.log(err.toString());
// Expected output: RangeError: invalid language tag: "EN_US"
}
Syntax
js
Intl.getCanonicalLocales(locales)
Parameters
Return value
An array containing the canonical locale names.
Examples
Using getCanonicalLocales
js
Intl.getCanonicalLocales("EN-US"); // ["en-US"]
Intl.getCanonicalLocales(["EN-US", "Fr"]); // ["en-US", "fr"]
Intl.getCanonicalLocales("EN_US");
// RangeError: invalid language tag: "EN_US"
Specifications
| Specification |
|---|
| ECMAScript® 2026 Internationalization API Specification # sec-intl.getcanonicallocales |


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

# Original Wiki contributors
mfuji09
chrisdavidmills
fscholz
wbamberg
jameshkramer
Mingun
Sheppy
slippyd
dbruant
evilpie
Mgjbot
Sevenspade
Diablownik
Maian
Nickolay
Dria


Intl.RelativeTimeFormat

Intl.RelativeTimeFormat
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 Intl.RelativeTimeFormat
object enables language-sensitive relative time formatting.
Try it
const rtf1 = new Intl.RelativeTimeFormat("en", { style: "short" });
console.log(rtf1.format(3, "quarter"));
// Expected output: "in 3 qtrs."
console.log(rtf1.format(-1, "day"));
// Expected output: "1 day ago"
const rtf2 = new Intl.RelativeTimeFormat("es", { numeric: "auto" });
console.log(rtf2.format(2, "day"));
// Expected output: "pasado mañana"
Constructor
Intl.RelativeTimeFormat()
-
Creates a new
Intl.RelativeTimeFormat
object.
Static methods
Intl.RelativeTimeFormat.supportedLocalesOf()
-
Returns an array containing those of the provided locales that are supported without having to fall back to the runtime's default locale.
Instance properties
These properties are defined on Intl.RelativeTimeFormat.prototype
and shared by all Intl.RelativeTimeFormat
instances.
Intl.RelativeTimeFormat.prototype.constructor
-
The constructor function that created the instance object. For
Intl.RelativeTimeFormat
instances, the initial value is theIntl.RelativeTimeFormat
constructor. Intl.RelativeTimeFormat.prototype[Symbol.toStringTag]
-
The initial value of the
[Symbol.toStringTag]
property is the string"Intl.RelativeTimeFormat"
. This property is used inObject.prototype.toString()
.
Instance methods
Intl.RelativeTimeFormat.prototype.format()
-
Formats a
value
and aunit
according to the locale and formatting options of the givenIntl.RelativeTimeFormat
object. Intl.RelativeTimeFormat.prototype.formatToParts()
-
Returns an
Array
of objects representing the relative time format in parts that can be used for custom locale-aware formatting. Intl.RelativeTimeFormat.prototype.resolvedOptions()
-
Returns a new object with properties reflecting the locale and formatting options computed during initialization of the object.
Examples
Basic format usage
The following example shows how to use a relative time formatter for the English language.
// Create a relative time formatter in your locale
// with default values explicitly passed in.
const rtf = new Intl.RelativeTimeFormat("en", {
localeMatcher: "best fit", // other values: "lookup"
numeric: "always", // other values: "auto"
style: "long", // other values: "short" or "narrow"
});
// Format relative time using negative value (-1).
rtf.format(-1, "day"); // "1 day ago"
// Format relative time using positive value (1).
rtf.format(1, "day"); // "in 1 day"
Using formatToParts
The following example shows how to create a relative time formatter returning formatted parts.
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
// Format relative time using the day unit.
rtf.formatToParts(-1, "day");
// [{ type: "literal", value: "yesterday"}]
rtf.formatToParts(100, "day");
// [
// { type: "literal", value: "in " },
// { type: "integer", value: "100", unit: "day" },
// { type: "literal", value: " days" }
// ]
Specifications
| Specification |
|---|
| ECMAScript® 2026 Internationalization API Specification # relativetimeformat-objects |
Browser compatibility
See also
- Polyfill of
Intl.RelativeTimeFormat
in FormatJS Intl
Intl.RelativeTimeFormat
on v8.dev (2018)


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

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