Multiplication (*) - JavaScript

Multiplication (\*)
===================

The **multiplication (`*`)** operator produces the product of the operands.

Try it
------

Syntax
------

```js
x \* y
```

Description
-----------

The `*` operator is overloaded for two types of operands: number and BigInt. It first coerces both operands to numeric values and tests the types of them. It performs BigInt multiplication if both operands become BigInts; otherwise, it performs number multiplication. A `TypeError` is thrown if one operand becomes a BigInt but the other becomes a number.

Examples
--------

### Multiplication using numbers

```js
2 \* 2; // 4
-2 \* 2; // -4
```

### Multiplication with Infinity

```js
Infinity \* 0; // NaN
Infinity \* Infinity; // Infinity
```

### Multiplication with non-numbers

```js
"foo" \* 2; // NaN
"2" \* 2; // 4
```

### Multiplication using BigInts

```js
2n \* 2n; // 4n
-2n \* 2n; // -4n

2n \* 2; // TypeError: Cannot mix BigInt and other types, use explicit conversions

// To multiply a BigInt with a non-BigInt, convert either operand
2n \* BigInt(2); // 4n
Number(2n) \* 2; // 4
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-multiplicative-operators |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Addition (`+`)
* Subtraction (`-`)
* Division (`/`)
* Remainder (`%`)
* Exponentiation (`**`)
* Increment (`++`)
* Decrement (`--`)
* Unary negation (`-`)
* Unary plus (`+`)


delete - JavaScript

delete
======

The **`delete`** operator removes a property from an object. If the property's value is an object and there are no more references to the object, the object held by that property is eventually released automatically.

Try it
------

Syntax
------

```js
delete object.property
delete object[property]
```

**Note:** The syntax allows a wider range of expressions following the `delete` operator, but only the above forms lead to meaningful behaviors.

### Parameters

`object`

The name of an object, or an expression evaluating to an object.

`property`

The property to delete.

### Return value

`true` for all cases except when the property is an own non-configurable property, in which case `false` is returned in non-strict mode.

### Exceptions

`TypeError`

Thrown in strict mode if the property is an own non-configurable property.

`ReferenceError`

Thrown if `object` is `super`.

Description
-----------

The `delete` operator has the same precedence as other unary operators like `typeof`. Therefore, it accepts any expression formed by higher-precedence operators. However, the following forms lead to early syntax errors in strict mode:

```js
delete identifier;
delete object.#privateProperty;
```

Because classes are automatically in strict mode, and private properties can only be legally referenced in class bodies, this means private properties can never be deleted. While `delete identifier` may work if `identifier` refers to a configurable property of the global object, you should avoid this form and prefix it with `globalThis` instead.

While other expressions are accepted, they don't lead to meaningful behaviors:

```js
delete console.log(1);
// Logs 1, returns true, but nothing deleted
```

The `delete` operator removes a given property from an object. On successful deletion, it will return `true`, else `false` will be returned. Unlike what common belief suggests (perhaps due to other programming languages like delete in C++), the `delete` operator has **nothing** to do with directly freeing memory. Memory management is done indirectly via breaking references. See the memory management page for more details.

It is important to consider the following scenarios:

* If the property which you are trying to delete does not exist, `delete` will not have any effect and will return `true`.
* `delete` only has an effect on own properties. If a property with the same name exists on the object's prototype chain, then after deletion, the object will use the property from the prototype chain.
* Non-configurable properties cannot be removed. This includes properties of built-in objects like `Math`, `Array`, `Object` and properties that are created as non-configurable with methods like `Object.defineProperty()`.
* Deleting variables, including function parameters, never works. `delete variable` will throw a `SyntaxError` in strict mode, and will have no effect in non-strict mode.
    + Any variable declared with `var` cannot be deleted from the global scope or from a function's scope, because while they may be attached to the global object, they are not configurable.
    + Any variable declared with `let` or `const` cannot be deleted from the scope within which they were defined, because they are not attached to an object.
Examples
--------

### Using delete

**Note:** The following example uses non-strict-mode only features, like implicitly creating global variables and deleting identifiers, which are forbidden in strict mode.

```js
// Creates the property empCount on the global scope.
// Since we are using var, this is marked as non-configurable.
var empCount = 43;

// Creates the property EmployeeDetails on the global scope.
// Since it was defined without "var", it is marked configurable.
EmployeeDetails = {
  name: "xyz",
  age: 5,
  designation: "Developer",
};

// delete can be used to remove properties from objects.
delete EmployeeDetails.name; // returns true

// Even when the property does not exist, delete returns "true".
delete EmployeeDetails.salary; // returns true

// EmployeeDetails is a property of the global scope.
delete EmployeeDetails; // returns true

// On the contrary, empCount is not configurable
// since var was used.
delete empCount; // returns false

// delete also does not affect built-in static properties
// that are non-configurable.
delete Math.PI; // returns false

function f() {
  var z = 44;

  // delete doesn't affect local variable names
  delete z; // returns false
}
```

### delete and the prototype chain

In the following example, we delete an own property of an object while a property with the same name is available on the prototype chain:

```js
function Foo() {
  this.bar = 10;
}

Foo.prototype.bar = 42;

const foo = new Foo();

// foo.bar is associated with the
// own property.
console.log(foo.bar); // 10

// Delete the own property within the
// foo object.
delete foo.bar; // returns true

// foo.bar is still available in the
// prototype chain.
console.log(foo.bar); // 42

// Delete the property on the prototype.
delete Foo.prototype.bar; // returns true

// The "bar" property can no longer be
// inherited from Foo since it has been
// deleted.
console.log(foo.bar); // undefined
```

### Deleting array elements

When you delete an array element, the array `length` is not affected. This holds even if you delete the last element of the array.

When the `delete` operator removes an array element, that element is no longer in the array. In the following example, `trees[3]` is removed with `delete`.

```js
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
delete trees[3];
console.log(3 in trees); // false
```

This creates a sparse array with an empty slot. If you want an array element to exist but have an undefined value, use the `undefined` value instead of the `delete` operator. In the following example, `trees[3]` is assigned the value `undefined`, but the array element still exists:

```js
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
trees[3] = undefined;
console.log(3 in trees); // true
```

If instead, you want to remove an array element by changing the contents of the array, use the `splice()` method. In the following example, `trees[3]` is removed from the array completely using `splice()`:

```js
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
trees.splice(3, 1);
console.log(trees); // ["redwood", "bay", "cedar", "maple"]
```

### Deleting non-configurable properties

When a property is marked as non-configurable, `delete` won't have any effect, and will return `false`. In strict mode, this will raise a `TypeError`.

```js
const Employee = {};
Object.defineProperty(Employee, "name", { configurable: false });

console.log(delete Employee.name); // returns false
```

`var` creates non-configurable properties that cannot be deleted with the `delete` operator:

```js
// Since "nameOther" is added using with the
// var keyword, it is marked as non-configurable
var nameOther = "XYZ";

// We can access this global property using:
Object.getOwnPropertyDescriptor(globalThis, "nameOther");
// {
// value: "XYZ",
// writable: true,
// enumerable: true,
// configurable: false
// }

delete globalThis.nameOther; // return false
```

In strict mode, this would raise an exception.

### Deleting global properties

If a global property is configurable (for example, via direct property assignment), it can be deleted, and subsequent references to them as global variables will produce a `ReferenceError`.

```js
globalThis.globalVar = 1;
console.log(globalVar); // 1
// In non-strict mode, you can use `delete globalVar` as well
delete globalThis.globalVar;
console.log(globalVar); // ReferenceError: globalVar is not defined
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-delete-operator |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* In depth analysis on delete
* `Reflect.deleteProperty()`
* `Map.prototype.delete()`


Bitwise AND (&) - JavaScript

Bitwise AND (&)
===============

The **bitwise AND (`&`)** operator returns a number or BigInt whose binary representation has a `1` in each bit position for which the corresponding bits of both operands are `1`.

Try it
------

Syntax
------

```js
x & y
```

Description
-----------

The `&` operator is overloaded for two types of operands: number and BigInt. For numbers, the operator returns a 32-bit integer. For BigInts, the operator returns a BigInt. It first coerces both operands to numeric values and tests the types of them. It performs BigInt AND if both operands become BigInts; otherwise, it converts both operands to 32-bit integers and performs number bitwise AND. A `TypeError` is thrown if one operand becomes a BigInt but the other becomes a number.

The operator operates on the operands' bit representations in two's complement. Each bit in the first operand is paired with the corresponding bit in the second operand: *first bit* to *first bit*, *second bit* to *second bit*, and so on. The operator is applied to each pair of bits, and the result is constructed bitwise.

The truth table for the AND operation is:

| x | y | x AND y |
| --- | --- | --- |
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
```

     9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
```

Numbers with more than 32 bits get their most significant bits discarded. For example, the following integer with more than 32 bits will be converted to a 32-bit integer:
```

Before: 11100110111110100000000000000110000000000001
After:              10100000000000000110000000000001
```

For BigInts, there's no truncation. Conceptually, understand positive BigInts as having an infinite number of leading `0` bits, and negative BigInts having an infinite number of leading `1` bits.

Bitwise ANDing any number `x` with `-1` returns `x` converted to a 32-bit integer. Do not use `& -1` to truncate numbers to integers; use `Math.trunc()` instead.

Examples
--------

### Using bitwise AND

```js
// 9 (00000000000000000000000000001001)
// 14 (00000000000000000000000000001110)

14 & 9;
// 8 (00000000000000000000000000001000)

14n & 9n; // 8n
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # prod-BitwiseANDExpression |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Bitwise operators in the JS guide
* Bitwise AND assignment (`&=`)


import() - JavaScript

import()
========

The **`import()`** syntax, commonly called *dynamic import*, is a function-like expression that allows loading an ECMAScript module asynchronously and dynamically into a potentially non-module environment.

Unlike the declaration-style counterpart, dynamic imports are only evaluated when needed, and permit greater syntactic flexibility.

Syntax
------

```js
import(moduleName)
```

The `import()` call is a syntax that closely resembles a function call, but `import` itself is a keyword, not a function. You cannot alias it like `const myImport = import`, which will throw a `SyntaxError`.

### Parameters

`moduleName`

The module to import from. The evaluation of the specifier is host-specified, but always follows the same algorithm as static import declarations.

### Return value

Returns a promise which fulfills to a module namespace object: an object containing all exports from `moduleName`.

The evaluation of `import()` never synchronously throws an error. `moduleName` is coerced to a string, and if coercion throws, the promise is rejected with the thrown error.

Description
-----------

The import declaration syntax (`import something from "somewhere"`) is static and will always result in the imported module being evaluated at load time. Dynamic imports allow one to circumvent the syntactic rigidity of import declarations and load a module conditionally or on demand. The following are some reasons why you might need to use dynamic import:

* When importing statically significantly slows the loading of your code or increases your program's memory usage, and there is a low likelihood that you will need the code you are importing, or you will not need it until a later time.
* When the module you are importing does not exist at load time.
* When the import specifier string needs to be constructed dynamically. (Static import only supports static specifiers.)
* When the module being imported has side effects, and you do not want those side effects unless some condition is true. (It is recommended not to have any side effects in a module, but you sometimes cannot control this in your module dependencies.)
* When you are in a non-module environment (for example, `eval` or a script file).

Use dynamic import only when necessary. The static form is preferable for loading initial dependencies, and can benefit more readily from static analysis tools and tree shaking.

If your file is not run as a module (if it's referenced in an HTML file, the script tag must have `type="module"`), you will not be able to use static import declarations, but the asynchronous dynamic import syntax will always be available, allowing you to import modules into non-module environments.

 Dynamic module import is not permitted in all execution contexts.
 For example, `import()` can be used in the main thread, a shared worker, or a dedicated worker, but will throw if called within a service worker or a worklet.

### Module namespace object

A *module namespace object* is an object that describes all exports from a module. It is a static object that is created when the module is evaluated. There are two ways to access the module namespace object of a module: through a namespace import (`import * as name from moduleName`), or through the fulfillment value of a dynamic import.

The module namespace object is a sealed object with `null` prototype. This means all string keys of the object correspond to the exports of the module and there are never extra keys. All keys are enumerable in lexicographic order (i.e. the default behavior of `Array.prototype.sort()`), with the default export available as a key called `default`. In addition, the module namespace object has a `@@toStringTag` property with the value `"Module"`, used in `Object.prototype.toString()`.

The string properties are non-configurable and writable when you use `Object.getOwnPropertyDescriptors()` to get their descriptors. However, they are effectively read-only, because you cannot re-assign a property to a new value. This behavior mirrors the fact that static imports create "live bindings" — the values can be re-assigned by the module exporting them, but not by the module importing them. The writability of the properties reflects the possibility of the values changing, because non-configurable and non-writable properties must be constant. For example, you can re-assign the exported value of a variable, and the new value can be observed in the module namespace object.

Each module specifier corresponds to a unique module namespace object, so the following is generally true:

```js
import \* as mod from "/my-module.js";

import("/my-module.js").then((mod2) => {
  console.log(mod === mod2); // true
});
```

Except in one curious case: because a promise never fulfills to a thenable, if the `my-module.js` module exports a function called `then()`, that function will automatically get called when the dynamic import's promise is fulfilled, as part of the promise resolution process.

```js
// my-module.js
export function then(resolve) {
  console.log("then() called");
  resolve(1);
}
```

```js
// main.js
import \* as mod from "/my-module.js";

import("/my-module.js").then((mod2) => {
  // Logs "then() called"
  console.log(mod === mod2); // false
});
```

**Warning:** Do not export a function called `then()` from a module. This will cause the module to behave differently when imported dynamically than when imported statically.

Examples
--------

### Import a module for its side effects only

```js
(async () => {
  if (somethingIsTrue) {
    // import module for side effects
    await import("/modules/my-module.js");
  }
})();
```

 If your project uses packages that export ESM, you can also import them for side
 effects only. This will run the code in the package entry point file (and any files it
 imports) only.

### Importing defaults

You need to destructure and rename the "default" key from the returned object.

```js
(async () => {
  if (somethingIsTrue) {
    const {
      default: myDefault,
      foo,
      bar,
    } = await import("/modules/my-module.js");
  }
})();
```

### Importing on-demand in response to user action

This example shows how to load functionality on to a page based on a user action, in this case a button click, and then call a function within that module. This is not the only way to implement this functionality. The `import()` function also supports `await`.

```js
const main = document.querySelector("main");
for (const link of document.querySelectorAll("nav > a")) {
  link.addEventListener("click", (e) => {
    e.preventDefault();

    import("/modules/my-module.js")
      .then((module) => {
        module.loadPageInto(main);
      })
      .catch((err) => {
        main.textContent = err.message;
      });
  });
}
```

### Importing different modules based on environment

In processes such as server-side rendering, you may need to load different logic on server or in browser because they interact with different globals or modules (for example, browser code has access to web APIs like `document` and `navigator`, while server code has access to the server file system). You can do so through a conditional dynamic import.

```js
let myModule;

if (typeof window === "undefined") {
  myModule = await import("module-used-on-server");
} else {
  myModule = await import("module-used-in-browser");
}
```

### Importing modules with a non-literal specifier

Dynamic imports allow any expression as the module specifier, not necessarily string literals.

Here, we load 10 modules, `/modules/module-0.js`, `/modules/module-1.js`, etc., concurrently, and call the `load` functions that each one exports.

```js
Promise.all(
  Array.from({ length: 10 }).map(
    (\_, index) => import(`/modules/module-${index}.js`),
  ),
).then((modules) => modules.forEach((module) => module.load()));
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-import-calls |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `import`


void operator - JavaScript

void operator
=============

 The **`void`** operator evaluates the given
 `expression` and then returns `undefined`.

Try it
------

Syntax
------

```js
void expression
```

Description
-----------

 This operator allows evaluating expressions that produce a value into places where an
 expression that evaluates to `undefined` is desired.

 The `void` operator is often used merely to obtain the
 `undefined` primitive value, usually using `void(0)` (which is
 equivalent to `void 0`). In these cases, the global variable
 `undefined` can be used.

 It should be noted that the precedence
 of the `void` operator should be taken into account and that
 parentheses can help clarify the resolution of the expression following the
 `void` operator:

```js
void 2 === "2"; // (void 2) === '2', returns false
void (2 === "2"); // void (2 === '2'), returns undefined
```

Examples
--------

### Immediately Invoked Function Expressions

When using an immediately-invoked function expression, the `function` keyword cannot be at the immediate start of the statement, because that would be parsed as a function declaration, and would generate a syntax error when the parentheses representing invocation is reached — if the function is unnamed, it would immediately be a syntax error if the function is parsed as a declaration.

```js
function iife() {
  console.log("Executed!");
}(); // SyntaxError: Unexpected token ')'

function () {
  console.log("Executed!");
}(); // SyntaxError: Function statements require a function name
```

In order for the function to be parsed as an expression, the `function` keyword has to appear at a position that only accepts expressions, not statements. This can be achieved be prefixing the keyword with a unary operator, which only accepts expressions as operands. Function invocation has higher precedence than unary operators, so it will be executed first. Its return value (which is almost always `undefined`) will be passed to the unary operator and then immediately discarded.

Of all the unary operators, `void` offers the best semantic, because it clearly signals that the return value of the function invocation should be discarded.

```js
void function () {
  console.log("Executed!");
}();

// Logs "Executed!"
```

This is a bit longer than wrapping the function expression in parentheses, which has the same effect of forcing the `function` keyword to be parsed as the start of an expression instead of a statement.

```js
(function () {
  console.log("Executed!");
})();
```

### JavaScript URIs

 When a browser follows a `javascript:` URI, it evaluates the code in the URI
 and then replaces the contents of the page with the returned value, unless the returned
 value is `undefined`. The `void` operator can be used to return
 `undefined`. For example:

```html
<a href="javascript:void(0);">Click here to do nothing</a>

<a href="javascript:void(document.body.style.backgroundColor='green');">
  Click here for green background
</a>
```

**Note:** `javascript:` pseudo protocol is discouraged over
 other alternatives, such as unobtrusive event handlers.

### Non-leaking Arrow Functions

 Arrow functions introduce a short-hand braceless syntax that returns an expression.
 This can cause unintended side effects if the expression is a function call where the returned value changes from `undefined` to some other value.

For example, if `doSomething()` returns `false` in the code below, the checkbox will no longer be marked as checked or unchecked when the checkbox is clicked (setting the handler to `false` disables the default action).

```js
checkbox.onclick = () => doSomething();
```

 This is unlikely to be desired behaviour!
 To be safe, when the return value of a function is not intended to be used, it can be passed to the `void` operator to ensure that (for example) changing APIs do not cause arrow functions' behaviors to change.

```js
checkbox.onclick = () => void doSomething();
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-void-operator |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `undefined`


Addition (+) - JavaScript

Addition (+)
============

The **addition (`+`)** operator produces the sum of numeric operands or string concatenation.

Try it
------

Syntax
------

```js
x + y
```

Description
-----------

The `+` operator is overloaded for two distinct operations: numeric addition and string concatenation. When evaluating, it first coerces both operands to primitives. Then, the two operands' types are tested:

* If one side is a string, the other operand is also converted to a string and they are concatenated.
* If they are both BigInts, BigInt addition is performed. If one side is a BigInt but the other is not, a `TypeError` is thrown.
* Otherwise, both sides are converted to numbers, and numeric addition is performed.

String concatenation is often thought to be equivalent with template literals or `String.prototype.concat()`, but they are not. Addition coerces the expression to a *primitive*, which calls `valueOf()` in priority; on the other hand, template literals and `concat()` coerce the expression to a *string*, which calls `toString()` in priority. If the expression has a `@@toPrimitive` method, string concatenation calls it with `"default"` as hint, while template literals use `"string"`. This is important for objects that have different string and primitive representations — such as Temporal, whose `valueOf()` method throws.

```js
const t = Temporal.Now.instant();
"" + t; // Throws TypeError
`${t}`; // '2022-07-31T04:48:56.113918308Z'
"".concat(t); // '2022-07-31T04:48:56.113918308Z'
```

You are advised to not use `"" + x` to perform string coercion.

Examples
--------

### Number addition

```js
// Number + Number -> addition
1 + 2; // 3

// Boolean + Number -> addition
true + 1; // 2

// Boolean + Boolean -> addition
false + false; // 0
```

### BigInt addition

```js
// BigInt + BigInt -> addition
1n + 2n; // 3n

// BigInt + Number -> throws TypeError
1n + 2; // TypeError: Cannot mix BigInt and other types, use explicit conversions

// To add a BigInt to a non-BigInt, convert either operand
1n + BigInt(2); // 3n
Number(1n) + 2; // 3
```

### String concatenation

```js
// String + String -> concatenation
"foo" + "bar"; // "foobar"

// Number + String -> concatenation
5 + "foo"; // "5foo"

// String + Boolean -> concatenation
"foo" + false; // "foofalse"

// String + Number -> concatenation
"2" + 2; // "22"
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-addition-operator-plus |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Subtraction (`-`)
* Division (`/`)
* Multiplication (`*`)
* Remainder (`%`)
* Exponentiation (`**`)
* Increment (`++`)
* Decrement (`--`)
* Unary negation (`-`)
* Unary plus (`+`)


function* expression - JavaScript

function\* expression
=====================

The **`function*`** keyword can be used to define a generator function inside an expression.

You can also define generator functions using the `function*` declaration.

Try it
------

Syntax
------

```js
function\* (param0) {
  statements
}
function\* (param0, param1) {
  statements
}
function\* (param0, param1, /\* …, \*/ paramN) {
  statements
}

function\* name(param0) {
  statements
}
function\* name(param0, param1) {
  statements
}
function\* name(param0, param1, /\* …, \*/ paramN) {
  statements
}
```

**Note:** An expression statement cannot begin with the keyword `function` to avoid ambiguity with a `function*` declaration. The `function` keyword only begins an expression when it appears in a context that cannot accept statements.

### Parameters

`name` Optional

The function name. Can be omitted, in which case the function is *anonymous*. The name is only local to the function body.

`paramN` Optional

The name of a formal parameter for the function. For the parameters' syntax, see the Functions reference.

`statements` Optional

The statements which comprise the body of the function.

Description
-----------

A `function*` expression is very similar to, and has almost the same syntax as, a `function*` declaration. The main difference between a `function*` expression and a `function*` declaration is the *function name*, which can be omitted in `function*` expressions to create *anonymous* functions. A `function*` expression can be used as an IIFE (Immediately Invoked Function Expression) which runs as soon as it is defined, allowing you to create an ad-hoc iterable iterator object. See also the chapter about functions for more information.

Examples
--------

### Using function\* expression

The following example defines an unnamed generator function and assigns it to `x`. The function yields the square of its argument:

```js
const x = function\* (y) {
  yield y \* y;
};
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-generator-function-definitions |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Functions guide
* Functions
* `function*`
* `GeneratorFunction`
* Iteration protocols
* `yield`
* `yield*`


Comma operator (,) - JavaScript

Comma operator (,)
==================

The **comma (`,`)** operator evaluates each of its operands (from left to right) and returns the value of the last operand. This is commonly used to provide multiple updaters to a `for` loop's afterthought.

Try it
------

Syntax
------

```js
expr1, expr2, expr3/\* , … \*/
```

### Parameters

`expr1`, `expr2`, `expr3`, …

One or more expressions, the last of which is returned as the value of the compound expression.

Description
-----------

You can use the comma operator when you want to include multiple expressions in a location that requires a single expression. The most common usage of this operator is to supply multiple updaters in a `for` loop.

Because all expressions except the last are evaluated and then discarded, these expressions must have side effects to be useful. Common expressions that have side effects are assignments, function calls, and `++` and `--` operators. Others may also have side effects if they invoke getters or trigger type coercions.

The comma operator has the lowest precedence of all operators. If you want to incorporate a comma-joined expression into a bigger expression, you must parenthesize it.

The comma operator is completely different from commas used as syntactic separators in other locations, which include:

* Elements in array initializers (`[1, 2, 3]`)
* Properties in object initializers (`{ a: 1, b: 2 }`)
* Parameters in function declarations/expressions (`function f(a, b) { … }`)
* Arguments in function calls (`f(1, 2)`)
* Binding lists in `let`, `const`, or `var` declarations (`const a = 1, b = 2;`)
* Import lists in `import` declarations (`import { a, b } from "c";`)
* Export lists in `export` declarations (`export { a, b };`)

In fact, although some of these places accept almost all expressions, they don't accept comma-joined expressions because that would be ambiguous with the syntactic comma separators. In this case, you must parenthesize the comma-joined expression. For example, the following is a `const` declaration that declares two variables, where the comma is not the comma operator:

```js
const a = 1, b = 2;
```

It is different from the following, where `b = 2` is an assignment expression, not a declaration. The value of `a` is `2`, the return value of the assignment, while the value of `1` is discarded:

```js
const a = (1, b = 2);
```

Comma operators cannot appear as trailing commas.

Examples
--------

### Using the comma operator in a for loop

If `a` is a 2-dimensional array with 10 elements on each side, the following code uses the comma operator to increment `i` and decrement `j` at once, thus printing the values of the diagonal elements in the array:

```js
const a = Array.from({ length: 10 }, () =>
  Array.from({ length: 10 }, Math.random),
); // A 10×10 array of random numbers

for (let i = 0, j = 9; i <= 9; i++, j--) {
  console.log(`a[${i}][${j}] = ${a[i][j]}`);
}
```

### Using the comma operator to join assignments

Because commas have the lowest precedence — even lower than assignment — commas can be used to join multiple assignment expressions. In the following example, `a` is set to the value of `b = 3` (which is 3). Then, the `c = 4` expression evaluates and its result becomes the return value of the entire comma expression.

```js
let a, b, c;

a = b = 3, c = 4; // Returns 4
console.log(a); // 3 (left-most)

let x, y, z;

x = (y = 5, z = 6); // Returns 6
console.log(x); // 6 (right-most)
```

### Processing and then returning

Another example that one could make with the comma operator is processing before returning. As stated, only the last element will be returned but all others are going to be evaluated as well. So, one could do:

```js
function myFunc() {
  let x = 0;

  return (x += 1, x); // the same as return ++x;
}
```

This is especially useful for one-line arrow functions. The following example uses a single `map()` to get both the sum of an array and the squares of its elements, which would otherwise require two iterations, one with `reduce()` and one with `map()`:

```js
let sum = 0;
const squares = [1, 2, 3, 4, 5].map((x) => ((sum += x), x \* x));
console.log(squares); // [1, 4, 9, 16, 25]
console.log(sum); // 15
```

### Discarding reference binding

The comma operator always returns the last expression as a *value* instead of a *reference*. This causes some contextual information such as the `this` binding to be lost. For example, a property access returns a reference to the function, which also remembers the object that it's accessed on, so that calling the property works properly. If the method is returned from a comma expression, then the function is called as if it's a new function value, and `this` is `undefined`.

```js
const obj = {
  value: "obj",
  method() {
    console.log(this.value);
  },
};

obj.method(); // "obj"
(obj.method)(); // "obj" (the grouping operator still returns the reference)
(0, obj.method)(); // undefined (the comma operator returns a new value)
```

You can enter indirect eval with this technique, because direct eval requires the function call to happen on the reference to the `eval()` function.

```js
globalThis.isDirectEval = false;

{
  const isDirectEval = true;
  console.log(eval("isDirectEval")); // true
  console.log((eval)("isDirectEval")); // true (the grouping operator still returns a reference to `eval`)
  console.log((0, eval)("isDirectEval")); // false (the comma operator returns a new value)
}
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-comma-operator |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `for`


Subtraction (-) - JavaScript

Subtraction (-)
===============

The **subtraction (`-`)** operator subtracts the two operands, producing their difference.

Try it
------

Syntax
------

```js
x - y
```

Description
-----------

The `-` operator is overloaded for two types of operands: number and BigInt. It first coerces both operands to numeric values and tests the types of them. It performs BigInt subtraction if both operands become BigInts; otherwise, it performs number subtraction. A `TypeError` is thrown if one operand becomes a BigInt but the other becomes a number.

Examples
--------

### Subtraction with numbers

```js
// Number - Number -> subtraction
5 - 3; // 2

// Number - Number -> subtraction
3 - 5; // -2
```

### Subtraction with non-numbers

```js
// String - Number -> subtraction
"foo" - 3; // NaN; "foo" is converted to the number NaN

// Number - String -> subtraction
5 - "3"; // 2; "3" is converted to the number 3
```

### Subtraction with BigInts

```js
// BigInt - BigInt -> subtraction
2n - 1n; // 1n
```

You cannot mix BigInt and number operands in subtraction.

```js
2n - 1; // TypeError: Cannot mix BigInt and other types, use explicit conversions
2 - 1n; // TypeError: Cannot mix BigInt and other types, use explicit conversions
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-subtraction-operator-minus |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Addition (`+`)
* Division (`/`)
* Multiplication (`*`)
* Remainder (`%`)
* Exponentiation (`**`)
* Increment (`++`)
* Decrement (`--`)
* Unary negation (`-`)
* Unary plus (`+`)


typeof - JavaScript

typeof
======

The **`typeof`** operator returns a string indicating the type of the operand's value.

Try it
------

Syntax
------

```js
typeof operand
```

### Parameters

`operand`

An expression representing the object or primitive whose type is to be returned.

Description
-----------

The following table summarizes the possible return values of `typeof`. For more information about types and primitives, see also the JavaScript data structure page.

| Type | Result |
| --- | --- |
| Undefined | `"undefined"` |
| Null | `"object"` (reason) |
| Boolean | `"boolean"` |
| Number | `"number"` |
| BigInt | `"bigint"` |
| String | `"string"` |
| Symbol | `"symbol"` |
| Function (implements [[Call]] in ECMA-262 terms; classes are functions as well) | `"function"` |
| Any other object | `"object"` |

This list of values is exhaustive. No spec-compliant engines are reported to produce (or had historically produced) values other than those listed.

Examples
--------

### Basic usage

```js
// Numbers
typeof 37 === "number";
typeof 3.14 === "number";
typeof 42 === "number";
typeof Math.LN2 === "number";
typeof Infinity === "number";
typeof NaN === "number"; // Despite being "Not-A-Number"
typeof Number("1") === "number"; // Number tries to parse things into numbers
typeof Number("shoe") === "number"; // including values that cannot be type coerced to a number

typeof 42n === "bigint";

// Strings
typeof "" === "string";
typeof "bla" === "string";
typeof `template literal` === "string";
typeof "1" === "string"; // note that a number within a string is still typeof string
typeof typeof 1 === "string"; // typeof always returns a string
typeof String(1) === "string"; // String converts anything into a string, safer than toString

// Booleans
typeof true === "boolean";
typeof false === "boolean";
typeof Boolean(1) === "boolean"; // Boolean() will convert values based on if they're truthy or falsy
typeof !!1 === "boolean"; // two calls of the ! (logical NOT) operator are equivalent to Boolean()

// Symbols
typeof Symbol() === "symbol";
typeof Symbol("foo") === "symbol";
typeof Symbol.iterator === "symbol";

// Undefined
typeof undefined === "undefined";
typeof declaredButUndefinedVariable === "undefined";
typeof undeclaredVariable === "undefined";

// Objects
typeof { a: 1 } === "object";

// use Array.isArray or Object.prototype.toString.call
// to differentiate regular objects from arrays
typeof [1, 2, 4] === "object";

typeof new Date() === "object";
typeof /regex/ === "object";

// The following are confusing, dangerous, and wasteful. Avoid them.
typeof new Boolean(true) === "object";
typeof new Number(1) === "object";
typeof new String("abc") === "object";

// Functions
typeof function () {} === "function";
typeof class C {} === "function";
typeof Math.sin === "function";
```

### typeof null

```js
// This stands since the beginning of JavaScript
typeof null === "object";
```

In the first implementation of JavaScript, JavaScript values were represented as a type tag and a value. The type tag for objects was `0`. `null` was represented as the NULL pointer (`0x00` in most platforms). Consequently, `null` had `0` as type tag, hence the `typeof` return value `"object"`. (reference)

A fix was proposed for ECMAScript (via an opt-in), but was rejected. It would have resulted in `typeof null === "null"`.

### Using new operator

All constructor functions called with `new` will return non-primitives (`"object"` or `"function"`). Most return objects, with the notable exception being `Function`, which returns a function.

```js
const str = new String("String");
const num = new Number(100);

typeof str; // "object"
typeof num; // "object"

const func = new Function();

typeof func; // "function"
```

### Need for parentheses in syntax

The `typeof` operator has higher precedence than binary operators like addition (`+`). Therefore, parentheses are needed to evaluate the type of an addition result.

```js
// Parentheses can be used for determining the data type of expressions.
const someData = 99;

typeof someData + " Wisen"; // "number Wisen"
typeof (someData + " Wisen"); // "string"
```

### Interaction with undeclared and uninitialized variables

`typeof` is generally always guaranteed to return a string for any operand it is supplied with. Even with undeclared identifiers, `typeof` will return `"undefined"` instead of throwing an error.

```js
typeof undeclaredVariable; // "undefined"
```

However, using `typeof` on lexical declarations (`let` `const`, and `class`) in the same block before the place of declaration will throw a `ReferenceError`. Block scoped variables are in a *temporal dead zone* from the start of the block until the initialization is processed, during which it will throw an error if accessed.

```js
typeof newLetVariable; // ReferenceError
typeof newConstVariable; // ReferenceError
typeof newClass; // ReferenceError

let newLetVariable;
const newConstVariable = "hello";
class newClass {}
```

### Exceptional behavior of document.all

All current browsers expose a non-standard host object `document.all` with type `undefined`.

```js
typeof document.all === "undefined";
```

Although `document.all` is also falsy and loosely equal to `undefined`, it is not `undefined`. The case of `document.all` having type `"undefined"` is classified in the web standards as a "willful violation" of the original ECMAScript standard for web compatibility.

### Custom method that gets a more specific type

`typeof` is very useful, but it's not as versatile as might be required. For example, `typeof []` is `"object"`, as well as `typeof new Date()`, `typeof /abc/`, etc.

For greater specificity in checking types, here we present a custom `type(value)` function, which mostly mimics the behavior of `typeof`, but for non-primitives (i.e. objects and functions), it returns a more granular type name where possible.

```js
function type(value) {
  if (value === null) {
    return "null";
  }
  const baseType = typeof value;
  // Primitive types
  if (!["object", "function"].includes(baseType)) {
    return baseType;
  }

  // Symbol.toStringTag often specifies the "display name" of the
  // object's class. It's used in Object.prototype.toString().
  const tag = value[Symbol.toStringTag];
  if (typeof tag === "string") {
    return tag;
  }

  // If it's a function whose source code starts with the "class" keyword
  if (
    baseType === "function" &&
    Function.prototype.toString.call(value).startsWith("class")
  ) {
    return "class";
  }

  // The name of the constructor; for example `Array`, `GeneratorFunction`,
  // `Number`, `String`, `Boolean` or `MyCustomClass`
  const className = value.constructor.name;
  if (typeof className === "string" && className !== "") {
    return className;
  }

  // At this point there's no robust way to get the type of value,
  // so we use the base implementation.
  return baseType;
}
```

For checking potentially non-existent variables that would otherwise throw a `ReferenceError`, use `typeof nonExistentVar === "undefined"` because this behavior cannot be mimicked with custom code.

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-typeof-operator |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `instanceof`
* `document.all` willful violation of the standard


yield* - JavaScript

yield\*
=======

The **`yield*`** operator is used to delegate to another iterable object, such as a `Generator`.

Try it
------

Syntax
------

```js
yield\* expression
```

### Parameters

`expression` Optional

An iterable object.

### Return value

Returns the value returned by that iterator when it's closed (when `done` is `true`).

Description
-----------

The `yield*` expression iterates over the operand and yields each value returned by it. It delegates iteration of the current generator to an underlying iterator — which we will refer to as "generator" and "iterator", respectively. `yield*` first gets the iterator from the operand by calling the latter's `@@iterator` method. Then, each time the `next()` method of the generator is called, `yield*` calls the iterator's `next()` method, passing the argument received by the generator's `next()` method (always `undefined` for the first call), and yielding the same result object as what's returned from the iterator's `next()` method. If the iterator result has `done: true`, then the `yield*` expression stops executing and returns the `value` of that result.

The `yield*` operator forwards the current generator's `throw()` and `return()` methods to the underlying iterator as well. If the current generator is prematurely closed through one of these methods, the underlying iterator will be notified. If the generator's `throw()`/`return()` method is called, the `throw()`/`return()` method of the underlying iterator is called with the same argument. The return value of `throw()`/`return()` is handled like the `next()` method's result, and if the method throws, the exception is propagated from the `yield*` expression.

If the underlying iterator doesn't have a `throw()` method, this causes `yield*` to throw a `TypeError` – but before throwing the error, the underlying iterator's `return()` method is called if one exists. If the underlying iterator doesn't have a `return()` method, the `yield*` expression turns into a `return` statement, just like calling `return()` on a suspended `yield` expression.

Examples
--------

### Delegating to another generator

 In following code, values yielded by `g1()` are returned from
 `next()` calls just like those which are yielded by `g2()`.

```js
function\* g1() {
  yield 2;
  yield 3;
  yield 4;
}

function\* g2() {
  yield 1;
  yield\* g1();
  yield 5;
}

const gen = g2();

console.log(gen.next()); // {value: 1, done: false}
console.log(gen.next()); // {value: 2, done: false}
console.log(gen.next()); // {value: 3, done: false}
console.log(gen.next()); // {value: 4, done: false}
console.log(gen.next()); // {value: 5, done: false}
console.log(gen.next()); // {value: undefined, done: true}
```

### Other Iterable objects

 Besides generator objects, `yield*` can also `yield` other kinds
 of iterables (e.g., arrays, strings, or `arguments`
 objects).

```js
function\* g3(...args) {
  yield\* [1, 2];
  yield\* "34";
  yield\* args;
}

const gen = g3(5, 6);

console.log(gen.next()); // {value: 1, done: false}
console.log(gen.next()); // {value: 2, done: false}
console.log(gen.next()); // {value: "3", done: false}
console.log(gen.next()); // {value: "4", done: false}
console.log(gen.next()); // {value: 5, done: false}
console.log(gen.next()); // {value: 6, done: false}
console.log(gen.next()); // {value: undefined, done: true}
```

### The value of yield\* expression itself

`yield*` is an expression, not a statement, so it evaluates to a value.

```js
function\* g4() {
  yield\* [1, 2, 3];
  return "foo";
}

function\* g5() {
  const g4ReturnValue = yield\* g4();
  console.log(g4ReturnValue); // 'foo'
  return g4ReturnValue;
}

const gen = g5();

console.log(gen.next()); // {value: 1, done: false}
console.log(gen.next()); // {value: 2, done: false}
console.log(gen.next()); // {value: 3, done: false} done is false because g5 generator isn't finished, only g4
console.log(gen.next()); // {value: 'foo', done: true}
```

### Method forwarding

The `next()`, `throw()`, and `return()` methods of the current generator are all forwarded to the underlying iterator.

```js
const iterable = {
  [Symbol.iterator]() {
    let count = 0;
    return {
      next(v) {
        console.log("next called with", v);
        count++;
        return { value: count, done: false };
      },
      return(v) {
        console.log("return called with", v);
        return { value: "iterable return value", done: true };
      },
      throw(v) {
        console.log("throw called with", v);
        return { value: "iterable thrown value", done: true };
      },
    };
  },
};

function\* gf() {
  yield\* iterable;
  return "gf return value";
}

const gen = gf();
console.log(gen.next(10));
// next called with undefined; the argument of the first next() call is always ignored
// { value: 1, done: false }
console.log(gen.next(20));
// next called with 20
// { value: 2, done: false }
console.log(gen.return(30));
// return called with 30
// { value: 'iterable return value', done: true }
console.log(gen.next(40));
// { value: undefined, done: true }; gen is already closed

const gen2 = gf();
console.log(gen2.next(10));
// next called with undefined
// { value: 1, done: false }
console.log(gen2.throw(50));
// throw called with 50
// { value: 'gf return value', done: true }
console.log(gen.next(60));
// { value: undefined, done: true }; gen is already closed
```

If the `return()`/`throw()` method of the underlying iterator returns `done: false`, the current generator continues executing and `yield*` continues to delegate to the underlying iterator.

```js
const iterable = {
  [Symbol.iterator]() {
    let count = 0;
    return {
      next(v) {
        console.log("next called with", v);
        count++;
        return { value: count, done: false };
      },
      return(v) {
        console.log("return called with", v);
        return { value: "iterable return value", done: false };
      },
    };
  },
};

function\* gf() {
  yield\* iterable;
  return "gf return value";
}

const gen = gf();
console.log(gen.next(10));
// next called with undefined
// { value: 1, done: false }
console.log(gen.return(20));
// return called with 20
// { value: 'iterable return value', done: false }
console.log(gen.next(30));
// { value: 2, done: false }; gen is not closed
```

If the underlying iterator doesn't have a `throw()` method and the generator's `throw()` is called, `yield*` throws an error.

```js
const iterable = {
  [Symbol.iterator]() {
    let count = 0;
    return {
      next(v) {
        count++;
        return { value: count, done: false };
      },
    };
  },
};

function\* gf() {
  yield\* iterable;
  return "gf return value";
}

const gen = gf();
gen.next(); // First next() starts the yield\* expression
gen.throw(20); // TypeError: The iterator does not provide a 'throw' method.
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-generator-function-definitions-runtime-semantics-evaluation |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Iteration protocols
* `function*`
* `function*` expression
* `yield`


in - JavaScript

in
==

The **`in`** operator returns `true` if the specified property is in the specified object or its prototype chain.

Try it
------

Syntax
------

```js
prop in object
#prop in object
```

### Parameters

`prop`

A string or symbol representing a property name (non-symbols will be coerced to strings). Can also be a private property identifier.

`object`

Object to check if it (or its prototype chain) contains the property with specified name (`prop`).

### Exceptions

`TypeError`

Thrown if `object` is not an object (i.e. a primitive).

Description
-----------

The `in` operator tests if a string or symbol property is present in an object or its prototype chain. If you want to check for only *non-inherited* properties, use `Object.hasOwn()` instead.

A property may be present in an object but have value `undefined`. Therefore, `x in obj` is not the same as `obj.x !== undefined`. To make `in` return `false` after a property is added, use the `delete` operator instead of setting that property's value to `undefined`.

You can also use the `in` operator to check whether a particular private class field or method has been defined in an object. The operator returns `true` if the property is defined, and `false` otherwise. This is known as a *branded check*, because it returns `true` if and only if the object was created with that class constructor, after which you can safely access other private properties as well.

This is a special syntax — the left-hand side of the `in` operator is a property identifier instead of an expression, but unquoted (because otherwise it's a string property, not a private property).

Because accessing private properties on objects unrelated to the current class throws a `TypeError` instead of returning `undefined`, this syntax allows you to shorten:

```js
class C {
  #x;
  static isC(obj) {
    try {
      obj.#x;
      return true;
    } catch {
      return false;
    }
  }
}
```

To:

```js
class C {
  #x;
  static isC(obj) {
    return #x in obj;
  }
}
```

It also generally avoids the need for dealing with error handling just to access a private property that may be nonexistent.

However, the `in` operator still requires the private property to be declared beforehand in the enclosing class — otherwise, it would throw a `SyntaxError` ("Private field '#x' must be declared in an enclosing class"), the same one as when you try to access an undeclared private property.

```js
class C {
  foo() {
    #x in this;
  }
}

new C().foo(); // SyntaxError: Private field '#x' must be declared in an enclosing class
```

Examples
--------

### Basic usage

The following examples show some uses of the `in` operator.

```js
// Arrays
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
0 in trees; // returns true
3 in trees; // returns true
6 in trees; // returns false
"bay" in trees; // returns false (you must specify the index number, not the value at that index)
"length" in trees; // returns true (length is an Array property)
Symbol.iterator in trees; // returns true

// Predefined objects
"PI" in Math; // returns true

// Custom objects
const mycar = { make: "Honda", model: "Accord", year: 1998 };
"make" in mycar; // returns true
"model" in mycar; // returns true
```

You must specify an object on the right side of the `in` operator. For example, you can specify a string created with the `String` constructor, but you cannot specify a string literal.

```js
const color1 = new String("green");
"length" in color1; // returns true

const color2 = "coral";
// generates an error (color2 is not a String object)
"length" in color2;
```

### Using the in operator with deleted or undefined properties

If you delete a property with the `delete` operator, the `in` operator returns `false` for that property.

```js
const mycar = { make: "Honda", model: "Accord", year: 1998 };
delete mycar.make;
"make" in mycar; // returns false

const trees = ["redwood", "bay", "cedar", "oak", "maple"];
delete trees[3];
3 in trees; // returns false
```

If you set a property to `undefined` but do not delete it, the `in` operator returns true for that property.

```js
const mycar = { make: "Honda", model: "Accord", year: 1998 };
mycar.make = undefined;
"make" in mycar; // returns true
```

```js
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
trees[3] = undefined;
3 in trees; // returns true
```

The `in` operator will return `false` for empty array slots, even if accessing it directly returns `undefined`.

```js
const empties = new Array(3);
empties[2]; // returns undefined
2 in empties; // returns false
```

To avoid this, make sure a new array is always filled with non-empty values or not write to indexes past the end of array.

```js
const empties = new Array(3).fill(undefined);
2 in empties; // returns true
```

### Inherited properties

The `in` operator returns `true` for properties in the prototype chain. This may be undesirable if you are using objects to store arbitrary key-value pairs.

```js
const ages = { alice: 18, bob: 27 };

function hasPerson(name) {
  return name in ages;
}

hasPerson("hasOwnProperty"); // true
```

You can use `Object.hasOwn()` to check if the object has the key.

```js
const ages = { alice: 18, bob: 27 };

function hasPerson(name) {
  return Object.hasOwn(ages, name);
}

hasPerson("hasOwnProperty"); // false
```

Alternatively, you should consider using a null prototype object or a `Map` for storing `ages`, to avoid other bugs.

```js
const ages = new Map([
  ["alice", 18],
  ["bob", 27],
]);

function hasPerson(name) {
  return ages.has(name);
}

hasPerson("hasOwnProperty"); // false
```

### Using the in operator to implement branded checks

The code fragment below demonstrates a static function that tells if an object was created with the `Person` constructor and therefore can perform other methods safely.

```js
class Person {
  #age;
  constructor(age) {
    this.#age = age;
  }
  static isPerson(o) {
    return #age in o;
  }
  ageDifference(other) {
    return this.#age - other.#age;
  }
}

const p1 = new Person(20);
const p2 = new Person(30);
console.log(p1.ageDifference(p2)); // -10
console.log(Person.isPerson(p1)); // true

if (Person.isPerson(p1) && Person.isPerson(p2)) {
  console.log(p1.ageDifference(p2)); // -10
}
```

It helps to prevent the following case:

```js
const p2 = {};

p1.ageDifference(p2); // TypeError: Cannot read private member #age from an object whose class did not declare it
```

Without the `in` operator, you would have to use a `try...catch` block to check if the object has the private property.

You can also implement this as a `@@hasInstance` method of the class, so that you can use the `instanceof` operator to perform the same check (which, by default, only checks for the existence of `Person.prototype` in the object's prototype chain).

```js
class Person {
  #age;
  constructor(age) {
    this.#age = age;
  }
  static [Symbol.hasInstance](o) {
    // Testing `this` to prevent false-positives when
    // calling `instanceof SubclassOfPerson`
    return this === Person && #age in o;
  }
  ageDifference(other) {
    return this.#age - other.#age;
  }
}

const p1 = new Person(20);
const p2 = new Person(30);

if (p1 instanceof Person && p2 instanceof Person) {
  console.log(p1.ageDifference(p2)); // -10
}
```

For more examples, see Private properties and the class guide.

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-relational-operators |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `for...in`
* `delete`
* `Object.hasOwn()`
* `Reflect.has()`
* Enumerability and ownership of properties


super - JavaScript

super
=====

The **`super`** keyword is used to access properties on an object literal or class's [[Prototype]], or invoke a superclass's constructor.

The `super.prop` and `super[expr]` expressions are valid in any method definition in both classes and object literals. The `super(...args)` expression is valid in class constructors.

Try it
------

Syntax
------

```js
super([arguments]) // calls the parent constructor.
super.propertyOnParent
super[expression]
```

Description
-----------

The `super` keyword can be used in two ways: as a "function call" (`super(...args)`), or as a "property lookup" (`super.prop` and `super[expr]`).

**Note:** `super` is a keyword and these are special syntactic constructs. `super` is not a variable that points to the prototype object. Attempting to read `super` itself is a `SyntaxError`.

```js
const child = {
  myParent() {
    console.log(super); // SyntaxError: 'super' keyword unexpected here
  },
};
```

In the constructor body of a derived class (with `extends`), the `super` keyword may appear as a "function call" (`super(...args)`), which must be called before the `this` keyword is used, and before the constructor returns. It calls the parent class's constructor and binds the parent class's public fields, after which the derived class's constructor can further access and modify `this`.

The "property lookup" form can be used to access methods and properties of an object literal's or class's [[Prototype]]. Within a class's body, the reference of `super` can be either the superclass's constructor itself, or the constructor's `prototype`, depending on whether the execution context is instance creation or class initialization. See the Examples section for more details.

Note that the reference of `super` is determined by the class or object literal `super` was declared in, not the object the method is called on. Therefore, unbinding or re-binding a method doesn't change the reference of `super` in it (although they do change the reference of `this`). You can see `super` as a variable in the class or object literal scope, which the methods create a closure over. (But also beware that it's not actually a variable, as explained above.)

When setting properties through `super`, the property is set on `this` instead.

Examples
--------

### Using super in classes

This code snippet is taken from the classes sample (live demo). Here `super()` is called to avoid duplicating the constructor parts' that are common between `Rectangle` and `Square`.

```js
class Rectangle {
  constructor(height, width) {
    this.name = "Rectangle";
    this.height = height;
    this.width = width;
  }
  sayName() {
    console.log(`Hi, I am a ${this.name}.`);
  }
  get area() {
    return this.height \* this.width;
  }
  set area(value) {
    this._area = value;
  }
}

class Square extends Rectangle {
  constructor(length) {
    // Here, it calls the parent class's constructor with lengths
    // provided for the Rectangle's width and height
    super(length, length);

    // Note: In derived classes, super() must be called before you
    // can use 'this'. Moving this to the top causes a ReferenceError.
    this.name = "Square";
  }
}
```

### Super-calling static methods

You are also able to call super on static methods.

```js
class Rectangle {
  static logNbSides() {
    return "I have 4 sides";
  }
}

class Square extends Rectangle {
  static logDescription() {
    return `${super.logNbSides()} which are all equal`;
  }
}
Square.logDescription(); // 'I have 4 sides which are all equal'
```

### Accessing super in class field declaration

`super` can also be accessed during class field initialization. The reference of `super` depends on whether the current field is an instance field or a static field.

```js
class Base {
  static baseStaticField = 90;
  baseMethod() {
    return 10;
  }
}

class Extended extends Base {
  extendedField = super.baseMethod(); // 10
  static extendedStaticField = super.baseStaticField; // 90
}
```

Note that instance fields are set on the instance instead of the constructor's `prototype`, so you can't use `super` to access the instance field of a superclass.

```js
class Base {
  baseField = 10;
}

class Extended extends Base {
  extendedField = super.baseField; // undefined
}
```

Here, `extendedField` is `undefined` instead of 10, because `baseField` is defined as an own property of the `Base` instance, instead of `Base.prototype`. `super`, in this context, only looks up properties on `Base.prototype`, because that's the [[Prototype]] of `Extended.prototype`.

### Deleting super properties will throw an error

You cannot use the `delete` operator and `super.prop` or `super[expr]` to delete a parent class' property — it will throw a `ReferenceError`.

```js
class Base {
  foo() {}
}
class Derived extends Base {
  delete() {
    delete super.foo; // this is bad
  }
}

new Derived().delete(); // ReferenceError: invalid delete involving 'super'.
```

### Using super.prop in object literals

Super can also be used in the object initializer notation. In this example, two objects define a method. In the second object, `super` calls the first object's method. This works with the help of `Object.setPrototypeOf()` with which we are able to set the prototype of `obj2` to `obj1`, so that `super` is able to find `method1` on `obj1`.

```js
const obj1 = {
  method1() {
    console.log("method 1");
  },
};

const obj2 = {
  method2() {
    super.method1();
  },
};

Object.setPrototypeOf(obj2, obj1);
obj2.method2(); // Logs "method 1"
```

### Methods that read super.prop do not behave differently when bound to other objects

Accessing `super.x` behaves like `Reflect.get(Object.getPrototypeOf(objectLiteral), "x", this)`, which means the property is always seeked on the object literal/class declaration's prototype, and unbinding and re-binding a method won't change the reference of `super`.

```js
class Base {
  baseGetX() {
    return 1;
  }
}
class Extended extends Base {
  getX() {
    return super.baseGetX();
  }
}

const e = new Extended();
console.log(e.getX()); // 1
const { getX } = e;
console.log(getX()); // 1
```

The same happens in object literals.

```js
const parent1 = { prop: 1 };
const parent2 = { prop: 2 };

const child = {
  myParent() {
    console.log(super.prop);
  },
};

Object.setPrototypeOf(child, parent1);
child.myParent(); // Logs "1"

const myParent = child.myParent;
myParent(); // Still logs "1"

const anotherChild = { \_\_proto\_\_: parent2, myParent };
anotherChild.myParent(); // Still logs "1"
```

Only resetting the entire inheritance chain will change the reference of `super`.

```js
class Base {
  baseGetX() {
    return 1;
  }
  static staticBaseGetX() {
    return 3;
  }
}
class AnotherBase {
  baseGetX() {
    return 2;
  }
  static staticBaseGetX() {
    return 4;
  }
}
class Extended extends Base {
  getX() {
    return super.baseGetX();
  }
  static staticGetX() {
    return super.staticBaseGetX();
  }
}

const e = new Extended();
// Reset instance inheritance
Object.setPrototypeOf(Extended.prototype, AnotherBase.prototype);
console.log(e.getX()); // Logs "2" instead of "1", because the prototype chain has changed
console.log(Extended.staticGetX()); // Still logs "3", because we haven't modified the static part yet
// Reset static inheritance
Object.setPrototypeOf(Extended, AnotherBase);
console.log(Extended.staticGetX()); // Now logs "4"
```

### Calling methods from super

When calling `super.prop` as a function, the `this` value inside the `prop` function is the current `this`, not the object that `super` points to. For example, the `super.getName()` call logs `"Extended"`, despite the code looking like it's equivalent to `Base.getName()`.

```js
class Base {
  static getName() {
    console.log(this.name);
  }
}

class Extended extends Base {
  static getName() {
    super.getName();
  }
}

Extended.getName(); // Logs "Extended"
```

This is especially important when interacting with static private properties.

### Setting super.prop sets the property on this instead

Setting properties of `super`, such as `super.x = 1`, behaves like `Reflect.set(Object.getPrototypeOf(objectLiteral), "x", 1, this)`. This is one of the cases where understanding `super` as simply "reference of the prototype object" falls short, because it actually sets the property on `this` instead.

```js
class A {}
class B extends A {
  setX() {
    super.x = 1;
  }
}

const b = new B();
b.setX();
console.log(b); // B { x: 1 }
console.log(Object.hasOwn(b, "x")); // true
```

`super.x = 1` will look for the property descriptor of `x` on `A.prototype` (and invoke the setters defined there), but the `this` value will be set to `this`, which is `b` in this context. You can read `Reflect.set` for more details on the case when `target` and `receiver` differ.

This means that while methods that *get* `super.prop` are usually not susceptible to changes in the `this` context, those that *set* `super.prop` are.

```js
/\* Reusing same declarations as above \*/

const b2 = new B();
b2.setX.call(null); // TypeError: Cannot assign to read only property 'x' of object 'null'
```

However, `super.x = 1` still consults the property descriptor of the prototype object, which means you cannot rewrite non-writable properties, and setters will be invoked.

```js
class X {
  constructor() {
    // Create a non-writable property
    Object.defineProperty(this, "prop", {
      configurable: true,
      writable: false,
      value: 1,
    });
  }
}

class Y extends X {
  constructor() {
    super();
  }
  foo() {
    super.prop = 2; // Cannot overwrite the value.
  }
}

const y = new Y();
y.foo(); // TypeError: "prop" is read-only
console.log(y.prop); // 1
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-super-keyword |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Classes


Left shift (<<) - JavaScript

Left shift (<<)
===============

The **left shift (`<<`)** operator returns a number or BigInt whose binary representation is the first operand shifted by the specified number of bits to the left. Excess bits shifted off to the left are discarded, and zero bits are shifted in from the right.

Try it
------

Syntax
------

```js
x << y
```

Description
-----------

The `<<` operator is overloaded for two types of operands: number and BigInt. For numbers, the operator returns a 32-bit integer. For BigInts, the operator returns a BigInt. It first coerces both operands to numeric values and tests the types of them. It performs BigInt left shift if both operands become BigInts; otherwise, it converts both operands to 32-bit integers and performs number left shift. A `TypeError` is thrown if one operand becomes a BigInt but the other becomes a number.

The operator operates on the left operand's bit representation in two's complement. For example, `9 << 2` yields 36:
```

     9 (base 10): 00000000000000000000000000001001 (base 2)
                  --------------------------------
9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
```

Bitwise a 32-bit integer `x` to the left by `y` bits yields `x * 2 ** y`. So for example, `9 << 3` is equivalent to `9 * (2 ** 3) = 9 * (8) = 72`.

If the left operand is a number with more than 32 bits, it will get the most significant bits discarded. For example, the following integer with more than 32 bits will be converted to a 32-bit integer:
```

Before: 11100110111110100000000000000110000000000001
After:              10100000000000000110000000000001
```

The right operand will be converted to an unsigned 32-bit integer and then taken modulo 32, so the actual shift offset will always be a positive integer between 0 and 31, inclusive. For example, `100 << 32` is the same as `100 << 0` (and produces `100`) because 32 modulo 32 is 0.

For BigInts, there's no truncation. Conceptually, understand positive BigInts as having an infinite number of leading `0` bits, and negative BigInts having an infinite number of leading `1` bits.

Left shifting any number `x` by `0` returns `x` converted to a 32-bit integer. Do not use `<< 0` to truncate numbers to integers; use `Math.trunc()` instead.

Examples
--------

### Using left shift

```js
9 << 3; // 72

// 9 \* (2 \*\* 3) = 9 \* (8) = 72

9n << 3n; // 72n
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-left-shift-operator |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Bitwise operators in the JS guide
* Left shift assignment (`<<=`)


Equality (==) - JavaScript

Equality (==)
=============

 The **equality (`==`)** operator checks whether its two operands are equal,
 returning a Boolean result.
 Unlike the strict equality operator,
 it attempts to convert and compare operands that are of different types.

Try it
------

Syntax
------

```js
x == y
```

Description
-----------

The equality operators (`==` and `!=`) provide the IsLooselyEqual semantic. This can be roughly summarized as follows:

1. If the operands have the same type, they are compared as follows:
    * Object: return `true` only if both operands reference the same object.
    * String: return `true` only if both operands have the same characters in the same order.
    * Number: return `true` only if both operands have the same value. `+0` and `-0` are treated as the same value. If either operand is `NaN`, return `false`; so, `NaN` is never equal to `NaN`.
    * Boolean: return `true` only if operands are both `true` or both `false`.
    * BigInt: return `true` only if both operands have the same value.
    * Symbol: return `true` only if both operands reference the same symbol.
2. If one of the operands is `null` or `undefined`, the other must also be `null` or `undefined` to return `true`. Otherwise return `false`.
3. If one of the operands is an object and the other is a primitive, convert the object to a primitive.
4. At this step, both operands are converted to primitives (one of String, Number, Boolean, Symbol, and BigInt). The rest of the conversion is done case-by-case.
    * If they are of the same type, compare them using step 1.
    * If one of the operands is a Symbol but the other is not, return `false`.
    * If one of the operands is a Boolean but the other is not, convert the boolean to a number: `true` is converted to 1, and `false` is converted to 0. Then compare the two operands loosely again.
    * Number to String: convert the string to a number. Conversion failure results in `NaN`, which will guarantee the equality to be `false`.
    * Number to BigInt: compare by their numeric value. If the number is ±Infinity or `NaN`, return `false`.
    * String to BigInt: convert the string to a BigInt using the same algorithm as the `BigInt()` constructor. If conversion fails, return `false`.

Loose equality is *symmetric*: `A == B` always has identical semantics to `B == A` for any values of `A` and `B` (except for the order of applied conversions).

The most notable difference between this operator and the strict equality (`===`) operator is that the strict equality operator does not attempt type conversion. Instead, the strict equality operator always considers operands of different types to be different. The strict equality operator essentially carries out only step 1, and then returns `false` for all other cases.

There's a "willful violation" of the above algorithm: if one of the operands is `document.all`, it is treated as if it's `undefined`. This means that `document.all == null` is `true`, but `document.all === undefined && document.all === null` is `false`.

Examples
--------

### Comparison with no type conversion

```js
1 == 1; // true
"hello" == "hello"; // true
```

### Comparison with type conversion

```js
"1" == 1; // true
1 == "1"; // true
0 == false; // true
0 == null; // false
0 == undefined; // false
0 == !!null; // true, look at Logical NOT operator
0 == !!undefined; // true, look at Logical NOT operator
null == undefined; // true

const number1 = new Number(3);
const number2 = new Number(3);
number1 == 3; // true
number1 == number2; // false
```

### Comparison of objects

```js
const object1 = {
  key: "value",
};

const object2 = {
  key: "value",
};

console.log(object1 == object2); // false
console.log(object1 == object1); // true
```

### Comparing strings and String objects

 Note that strings constructed using `new String()` are objects. If you
 compare one of these with a string literal, the `String` object will be
 converted to a string literal and the contents will be compared. However, if both
 operands are `String` objects, then they are compared as objects and must
 reference the same object for comparison to succeed:

```js
const string1 = "hello";
const string2 = String("hello");
const string3 = new String("hello");
const string4 = new String("hello");

console.log(string1 == string2); // true
console.log(string1 == string3); // true
console.log(string2 == string3); // true
console.log(string3 == string4); // false
console.log(string4 == string4); // true
```

### Comparing Dates and strings

```js
const d = new Date("1995-12-17T03:24:00");
const s = d.toString(); // for example: "Sun Dec 17 1995 03:24:00 GMT-0800 (Pacific Standard Time)"
console.log(d == s); //true
```

### Comparing arrays and strings

```js
const a = [1, 2, 3];
const b = "1,2,3";
a == b; // true, `a` converts to string

const c = [true, 0.5, "hey"];
const d = c.toString(); // "true,0.5,hey"
c == d; // true
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-equality-operators |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Inequality (`!=`)
* Strict equality (`===`)
* Strict inequality (`!==`)


Unary negation (-) - JavaScript

Unary negation (-)
==================

The **unary negation (`-`)** operator precedes its operand and negates it.

Try it
------

Syntax
------

```js
-x
```

Description
-----------

The `-` operator is overloaded for two types of operands: number and BigInt. It first coerces the operand to a numeric value and tests the type of it. It performs BigInt negation if the operand becomes a BigInt; otherwise, it performs number negation.

Examples
--------

### Negating numbers

```js
const x = 3;
const y = -x;
// y is -3; x is 3
```

### Negating non-numbers

The unary negation operator can convert a non-number into a number.

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

// y is -4
```

BigInts can be negated using the unary negation operator.

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

// y is -4n
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-unary-minus-operator |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Addition (`+`)
* Subtraction (`-`)
* Division (`/`)
* Multiplication (`*`)
* Remainder (`%`)
* Exponentiation (`**`)
* Increment (`++`)
* Decrement (`--`)
* Unary plus (`+`)


Unary plus (+) - JavaScript

Unary plus (+)
==============

 The **unary plus (`+`)** operator precedes its operand and evaluates to its
 operand but attempts to convert it into a number, if it isn't already.

Try it
------

Syntax
------

```js
+x
```

Description
-----------

Although unary negation (`-`) also can convert non-numbers, unary plus is the fastest and preferred way of converting something into a number, because it does not perform any other operations on the number.

Unary plus does the exact same steps as normal number coercion used by most built-in methods expecting numbers. It can convert string representations of integers and floats, as well as the non-string values `true`, `false`, and `null`. Integers in both decimal and hexadecimal (`0x`-prefixed) formats are supported. Negative numbers are supported (though not for hex). If it cannot parse a particular value, it will evaluate to `NaN`. Unlike other arithmetic operators, which work with both numbers and BigInts, using the `+` operator on BigInt values throws a `TypeError`.

Examples
--------

### Usage with numbers

```js
const x = 1;
const y = -1;

console.log(+x);
// 1
console.log(+y);
// -1
```

### Usage with non-numbers

```js
+true  // 1
+false // 0
+null  // 0
+[]    // 0
+function (val) { return val; } // NaN
+1n    // throws TypeError: Cannot convert BigInt value to number
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-unary-plus-operator |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Addition (`+`)
* Subtraction (`-`)
* Division (`/`)
* Multiplication (`*`)
* Remainder (`%`)
* Exponentiation (`**`)
* Increment (`++`)
* Decrement (`--`)
* Unary negation (`-`)


async function expression - JavaScript

async function expression
=========================

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.

* Learn more
* See full compatibility
* Report feedback
The **`async function`** keywords can be used to define an async function inside an expression.

You can also define async functions using the `async function` declaration or the arrow syntax.

Syntax
------

```js
async function (param0) {
  statements
}
async function (param0, param1) {
  statements
}
async function (param0, param1, /\* …, \*/ paramN) {
  statements
}

async function name(param0) {
  statements
}
async function name(param0, param1) {
  statements
}
async function name(param0, param1, /\* …, \*/ paramN) {
  statements
}
```

**Note:** An expression statement cannot begin with the keywords `async function` to avoid ambiguity with an `async function` declaration. The `async function` keywords only begin an expression when they appear in a context that cannot accept statements.

### Parameters

`name` Optional

The function name. Can be omitted, in which case the function is *anonymous*. The name is only local to the function body.

`paramN` Optional

The name of a formal parameter for the function. For the parameters' syntax, see the Functions reference.

`statements` Optional

The statements which comprise the body of the function.

Description
-----------

An `async function` expression is very similar to, and has almost the same syntax as, an `async function` declaration. The main difference between an `async function` expression and an `async function` declaration is the *function name*, which can be omitted in `async function` expressions to create *anonymous* functions. An `async function` expression can be used as an IIFE (Immediately Invoked Function Expression) which runs as soon as it is defined, allowing you to mimic top-level await. See also the chapter about functions for more information.

Examples
--------

### Using async function expression

```js
function resolveAfter2Seconds(x) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

// async function expression assigned to a variable
const add = async function (x) {
  const a = await resolveAfter2Seconds(20);
  const b = await resolveAfter2Seconds(30);
  return x + a + b;
};

add(10).then((v) => {
  console.log(v); // prints 60 after 4 seconds.
});

// async function expression used as an IIFE
(async function (x) {
  const p1 = resolveAfter2Seconds(20);
  const p2 = resolveAfter2Seconds(30);
  return x + (await p1) + (await p2);
})(10).then((v) => {
  console.log(v); // prints 60 after 2 seconds.
});
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-async-function-definitions |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Functions guide
* Functions
* `async function`
* `AsyncFunction`
* `await`


Subtraction assignment (-=) - JavaScript

Subtraction assignment (-=)
===========================

The **subtraction assignment (`-=`)** operator performs subtraction on the two operands and assigns the result to the left operand.

Try it
------

Syntax
------

```js
x -= y
```

Description
-----------

`x -= y` is equivalent to `x = x - y`, except that the expression `x` is only evaluated once.

Examples
--------

### Using subtraction assignment

```js
let bar = 5;

bar -= 2; // 3
bar -= "foo"; // NaN

let foo = 3n;
foo -= 2n; // 1n
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-assignment-operators |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Assignment operators in the JS guide
* Subtraction (`-`)


Nullish coalescing operator (??) - JavaScript

Nullish coalescing operator (??)
================================

 The **nullish coalescing (`??`)** operator is a logical
 operator that returns its right-hand side operand when its left-hand side operand is
 `null` or `undefined`, and otherwise returns its left-hand side
 operand.

Try it
------

Syntax
------

```js
leftExpr ?? rightExpr
```

Description
-----------

The nullish coalescing operator can be seen as a special case of the logical OR (`||`) operator. The latter returns the right-hand side operand if the left operand is *any* falsy value, not only `null` or `undefined`. In other words, if you use `||` to provide some default value to another variable `foo`, you may encounter unexpected behaviors if you consider some falsy values as usable (e.g., `''` or `0`). See below for more examples.

The nullish coalescing operator has the fifth-lowest operator precedence, directly lower than `||` and directly higher than the conditional (ternary) operator.

It is not possible to combine both the AND (`&&`) and OR operators (`||`) directly with `??`. A syntax error will be thrown in such cases.

```js
null || undefined ?? "foo"; // raises a SyntaxError
true && undefined ?? "foo"; // raises a SyntaxError
```

Instead, provide parenthesis to explicitly indicate precedence:

```js
(null || undefined) ?? "foo"; // returns "foo"
```

Examples
--------

### Using the nullish coalescing operator

In this example, we will provide default values but keep values other than `null` or `undefined`.

```js
const nullValue = null;
const emptyText = ""; // falsy
const someNumber = 42;

const valA = nullValue ?? "default for A";
const valB = emptyText ?? "default for B";
const valC = someNumber ?? 0;

console.log(valA); // "default for A"
console.log(valB); // "" (as the empty string is not null or undefined)
console.log(valC); // 42
```

### Assigning a default value to a variable

Earlier, when one wanted to assign a default value to a variable, a common pattern was to use the logical OR operator (`||`):

```js
let foo;

// foo is never assigned any value so it is still undefined
const someDummyText = foo || "Hello!";
```

However, due to `||` being a boolean logical operator, the left-hand-side operand was coerced to a boolean for the evaluation and any *falsy* value (including `0`, `''`, `NaN`, `false`, etc.) was not returned. This behavior may cause unexpected consequences if you consider `0`, `''`, or `NaN` as valid values.

```js
const count = 0;
const text = "";

const qty = count || 42;
const message = text || "hi!";
console.log(qty); // 42 and not 0
console.log(message); // "hi!" and not ""
```

The nullish coalescing operator avoids this pitfall by only returning the second operand when the first one evaluates to either `null` or `undefined` (but no other falsy values):

```js
const myText = ""; // An empty string (which is also a falsy value)

const notFalsyText = myText || "Hello world";
console.log(notFalsyText); // Hello world

const preservingFalsy = myText ?? "Hi neighborhood";
console.log(preservingFalsy); // '' (as myText is neither undefined nor null)
```

### Short-circuiting

Like the OR and AND logical operators, the right-hand side expression is not evaluated if the left-hand side proves to be neither `null` nor `undefined`.

```js
function a() {
  console.log("a was called");
  return undefined;
}
function b() {
  console.log("b was called");
  return false;
}
function c() {
  console.log("c was called");
  return "foo";
}

console.log(a() ?? c());
// Logs "a was called" then "c was called" and then "foo"
// as a() returned undefined so both expressions are evaluated

console.log(b() ?? c());
// Logs "b was called" then "false"
// as b() returned false (and not null or undefined), the right
// hand side expression was not evaluated
```

### Relationship with the optional chaining operator (?.)

The nullish coalescing operator treats `undefined` and `null` as specific values. So does the optional chaining operator (`?.`), which is useful to access a property of an object which may be `null` or `undefined`. Combining them, you can safely access a property of an object which may be nullish and provide a default value if it is.

```js
const foo = { someFooProp: "hi" };

console.log(foo.someFooProp?.toUpperCase() ?? "not available"); // "HI"
console.log(foo.someBarProp?.toUpperCase() ?? "not available"); // "not available"
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # prod-CoalesceExpression |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Nullish coalescing assignment (`??=`)
* Optional chaining (`?.`)
* Logical OR (`||`)
* Default parameters