Standard built-in objects - JavaScript

Standard built-in objects
=========================

This chapter documents all of JavaScript's standard, built-in objects, including their methods and properties.

The term "global objects" (or standard built-in objects) here is not to be confused with **the global object**. Here, "global objects" refer to **objects in the global scope**.

The **global object** itself can be accessed using the `this` operator in the global scope. In fact, the global scope **consists of** the properties of the global object, including inherited properties, if any.

Other objects in the global scope are either created by the user script or provided by the host application. The host objects available in browser contexts are documented in the API reference.

For more information about the distinction between the DOM and core JavaScript, see JavaScript technologies overview.

Standard objects by category
----------------------------

### Value properties

These global properties return a simple value. They have no properties or methods.

* `globalThis`
* `Infinity`
* `NaN`
* `undefined`
### Function properties

These global functions—functions which are called globally, rather than on an object—directly return their results to the caller.

* `eval()`
* `isFinite()`
* `isNaN()`
* `parseFloat()`
* `parseInt()`
* `decodeURI()`
* `decodeURIComponent()`
* `encodeURI()`
* `encodeURIComponent()`
* `escape()`
Deprecated
* `unescape()`
Deprecated
### Fundamental objects

These objects represent fundamental language constructs.

* `Object`
* `Function`
* `Boolean`
* `Symbol`
### Error objects

Error objects are a special type of fundamental object. They include the basic `Error` type, as well as several specialized error types.

* `Error`
* `AggregateError`
* `EvalError`
* `RangeError`
* `ReferenceError`
* `SyntaxError`
* `TypeError`
* `URIError`
* `InternalError`
Non-standard
### Numbers and dates

These are the base objects representing numbers, dates, and mathematical calculations.

* `Number`
* `BigInt`
* `Math`
* `Date`
### Text processing

These objects represent strings and support manipulating them.

* `String`
* `RegExp`
### Indexed collections

These objects represent collections of data which are ordered by an index value. This includes (typed) arrays and array-like constructs.

* `Array`
* `Int8Array`
* `Uint8Array`
* `Uint8ClampedArray`
* `Int16Array`
* `Uint16Array`
* `Int32Array`
* `Uint32Array`
* `BigInt64Array`
* `BigUint64Array`
* `Float32Array`
* `Float64Array`
### Keyed collections

These objects represent collections which use keys. The iterable collections (`Map` and `Set`) contain elements which are easily iterated in the order of insertion.

* `Map`
* `Set`
* `WeakMap`
* `WeakSet`
### Structured data

These objects represent and interact with structured data buffers and data coded using JavaScript Object Notation (JSON).

* `ArrayBuffer`
* `SharedArrayBuffer`
* `DataView`
* `Atomics`
* `JSON`
### Managing memory

These objects interact with the garbage collection mechanism.

* `WeakRef`
* `FinalizationRegistry`
### Control abstraction objects

Control abstractions can help to structure code, especially async code (without using deeply nested callbacks, for example).

* `Iterator`
* `AsyncIterator`
* `Promise`
* `GeneratorFunction`
* `AsyncGeneratorFunction`
* `Generator`
* `AsyncGenerator`
* `AsyncFunction`
### Reflection

* `Reflect`
* `Proxy`
### Internationalization

Additions to the ECMAScript core for language-sensitive functionalities.

* `Intl`
* `Intl.Collator`
* `Intl.DateTimeFormat`
* `Intl.DisplayNames`
* `Intl.DurationFormat`
* `Intl.ListFormat`
* `Intl.Locale`
* `Intl.NumberFormat`
* `Intl.PluralRules`
* `Intl.RelativeTimeFormat`
* `Intl.Segmenter`


Trailing commas - JavaScript

Trailing commas
===============

**Trailing commas** (sometimes called "final commas") can be useful when adding new elements, parameters, or properties to JavaScript code. If you want to add a new property, you can add a new line without modifying the previously last line if that line already uses a trailing comma. This makes version-control diffs cleaner and editing code might be less troublesome.

JavaScript has allowed trailing commas in array literals since the beginning. Trailing commas are now also allowed in object literals, function parameters, named imports, named exports, and more.

JSON, however, disallows all trailing commas.

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

JavaScript allows trailing commas wherever a comma-separated list of values is accepted and more values may be expected after the last item. This includes:

* Array literals
* Object literals
* Parameter definitions
* Function calls
* Named imports
* Named exports
* Array and object destructuring

In all these cases, the trailing comma is entirely optional and doesn't change the program's semantics in any way.

It is particular useful when adding, removing, or reordering items in a list that spans multiple lines, because it reduces the number of lines that need to be changed, which helps with both editing and reviewing the diff.

```diff
  [
  "foo",
+ "baz",
  "bar",
- "baz",
  ]
```

Examples
--------

### Trailing commas in literals

#### Arrays

JavaScript ignores trailing commas in arrays literals:

```js
const arr = [
  1,
  2,
  3,
];

arr; // [1, 2, 3]
arr.length; // 3
```

If more than one trailing comma is used, an elision (or hole) is produced. An array with holes is called *sparse* (a *dense* array has no holes). When iterating arrays for example with `Array.prototype.forEach()` or `Array.prototype.map()`, array holes are skipped. Sparse arrays are generally unfavorable, so you should avoid having multiple trailing commas.

```js
const arr = [1, 2, 3, , ,];
arr.length; // 5
```

#### Objects

Trailing commas in object literals are legal as well:

```js
const object = {
  foo: "bar",
  baz: "qwerty",
  age: 42,
};
```

### Trailing commas in functions

Trailing commas are also allowed in function parameter lists.

#### Parameter definitions

The following function definition pairs are legal and equivalent to each other. Trailing commas don't affect the `length` property of function declarations or their `arguments` object.

```js
function f(p) {}
function f(p,) {}

(p) => {};
(p,) => {};
```

The trailing comma also works with method definitions for classes or objects:

```js
class C {
  one(a,) {}
  two(a, b,) {}
}

const obj = {
  one(a,) {},
  two(a, b,) {},
};
```

#### Function calls

The following function invocation pairs are legal and equivalent to each other.

```js
f(p);
f(p,);

Math.max(10, 20);
Math.max(10, 20,);
```

#### Illegal trailing commas

Function parameter definitions or function invocations only containing a comma will throw a `SyntaxError`. Furthermore, when using rest parameters, trailing commas are not allowed:

```js
function f(,) {} // SyntaxError: missing formal parameter
(,) => {};       // SyntaxError: expected expression, got ','
f(,)             // SyntaxError: expected expression, got ','

function f(...p,) {} // SyntaxError: parameter after rest parameter
(...p,) => {}        // SyntaxError: expected closing parenthesis, got ','
```

### Trailing commas in destructuring

A trailing comma is also allowed on the left-hand side when using destructuring assignment:

```js
// array destructuring with trailing comma
[a, b,] = [1, 2];

// object destructuring with trailing comma
const o = {
  p: 42,
  q: true,
};
const { p, q, } = o;
```

Again, when using a rest element, a `SyntaxError` will be thrown:

```js
const [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma
```

### Trailing commas in JSON

As JSON is based on a very restricted subset of JavaScript syntax, **trailing commas are not allowed in JSON**.

Both lines will throw a `SyntaxError`:

```js
JSON.parse("[1, 2, 3, 4, ]");
JSON.parse('{"foo" : 1, }');
// SyntaxError JSON.parse: unexpected character
// at line 1 column 14 of the JSON data
```

Omit the trailing commas to parse the JSON correctly:

```js
JSON.parse("[1, 2, 3, 4 ]");
JSON.parse('{"foo" : 1 }');
```

### Trailing commas in named imports and named exports

Trailing commas are valid in named imports and named exports.

#### Named imports

```js
import {
  A,
  B,
  C,
} from "D";

import { X, Y, Z, } from "W";

import { A as B, C as D, E as F, } from "Z";
```

#### Named exports

```js
export {
  A,
  B,
  C,
};

export { A, B, C, };

export { A as B, C as D, E as F, };
```

### Quantifier prefix

**Note:** The trailing comma in a quantifier actually changes its semantics from matching "exactly `n`" to matching "at least `n`".

```js
/x{2}/; // Exactly 2 occurrences of "x"; equivalent to /xx/
/x{2,}/; // At least 2 occurrences of "x"; equivalent to /xx+/
/x{2,4}/; // 2 to 4 occurrences of "x"; equivalent to /xxx?x?/
```

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-Elision |
| ECMAScript Language Specification # prod-ObjectLiteral |
| ECMAScript Language Specification # prod-ArrayLiteral |
| ECMAScript Language Specification # prod-Arguments |
| ECMAScript Language Specification # prod-FormalParameters |
| ECMAScript Language Specification # prod-CoverParenthesizedExpressionAndArrowParameterList |
| ECMAScript Language Specification # prod-NamedImports |
| ECMAScript Language Specification # prod-NamedExports |
| ECMAScript Language Specification # prod-QuantifierPrefix |
| ECMAScript Language Specification # prod-annexB-InvalidBracedQuantifier |

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

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

See also
--------

* Grammar and types guide


await - JavaScript

await
=====

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 **`await`** operator is used to wait for a `Promise` and get its fulfillment value. It can only be used inside an async function or at the top level of a module.

Syntax
------

```js
await expression
```

### Parameters

`expression`

A `Promise`, a thenable object, or any value to wait for.

### Return value

The fulfillment value of the promise or thenable object, or, if the expression is not thenable, the expression's own value.

### Exceptions

Throws the rejection reason if the promise or thenable object is rejected.

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

`await` is usually used to unwrap promises by passing a `Promise` as the `expression`. Using `await` pauses the execution of its surrounding `async` function until the promise is settled (that is, fulfilled or rejected). When execution resumes, the value of the `await` expression becomes that of the fulfilled promise.

If the promise is rejected, the `await` expression throws the rejected value. The function containing the `await` expression will appear in the stack trace of the error. Otherwise, if the rejected promise is not awaited or is immediately returned, the caller function will not appear in the stack trace.

The `expression` is resolved in the same way as `Promise.resolve()`: it's always converted to a native `Promise` and then awaited. If the `expression` is a:

* Native `Promise` (which means `expression` belongs to `Promise` or a subclass, and `expression.constructor === Promise`): The promise is directly used and awaited natively, without calling `then()`.
* Thenable object (including non-native promises, polyfill, proxy, child class, etc.): A new promise is constructed with the native `Promise()` constructor by calling the object's `then()` method and passing in a handler that calls the `resolve` callback.
* Non-thenable value: An already-fulfilled `Promise` is constructed and used.

Even when the used promise is already fulfilled, the async function's execution still pauses until the next tick. In the meantime, the caller of the async function resumes execution. See example below.

Because `await` is only valid inside async functions and modules, which themselves are asynchronous and return promises, the `await` expression never blocks the main thread and only defers execution of code that actually depends on the result, i.e. anything after the `await` expression.

Examples
--------

### Awaiting a promise to be fulfilled

If a `Promise` is passed to an `await` expression, it waits for the `Promise` to be fulfilled and returns the fulfilled value.

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

async function f1() {
  const x = await resolveAfter2Seconds(10);
  console.log(x); // 10
}

f1();
```

### Thenable objects

Thenable objects are resolved just the same as actual `Promise` objects.

```js
async function f() {
  const thenable = {
    then(resolve, \_reject) {
      resolve("resolved!");
    },
  };
  console.log(await thenable); // "resolved!"
}

f();
```

They can also be rejected:

```js
async function f() {
  const thenable = {
    then(resolve, reject) {
      reject(new Error("rejected!"));
    },
  };
  await thenable; // Throws Error: rejected!
}

f();
```

### Conversion to promise

If the value is not a `Promise`, `await` converts the value to a resolved `Promise`, and waits for it. The awaited value's identity doesn't change as long as it doesn't have a `then` property that's callable.

```js
async function f3() {
  const y = await 20;
  console.log(y); // 20

  const obj = {};
  console.log((await obj) === obj); // true
}

f3();
```

### Handling rejected promises

If the `Promise` is rejected, the rejected value is thrown.

```js
async function f4() {
  try {
    const z = await Promise.reject(30);
  } catch (e) {
    console.error(e); // 30
  }
}

f4();
```

You can handle rejected promises without a `try` block by chaining a `catch()` handler before awaiting the promise.

```js
const response = await promisedFunction().catch((err) => {
  console.error(err);
  return "default response";
});
// response will be "default response" if the promise is rejected
```

This is built on the assumption that `promisedFunction()` never synchronously throws an error, but always returns a rejected promise. This is the case for most properly-designed promise-based functions, which usually look like:

```js
function promisedFunction() {
  // Immediately return a promise to minimize chance of an error being thrown
  return new Promise((resolve, reject) => {
    // do something async
  });
}
```

However, if `promisedFunction()` does throw an error synchronously, the error won't be caught by the `catch()` handler. In this case, the `try...catch` statement is necessary.

### Top level await

You can use the `await` keyword on its own (outside of an async function) at the top level of a module. This means that modules with child modules that use `await` will wait for the child modules to execute before they themselves run, all while not blocking other child modules from loading.

Here is an example of a simple module using the Fetch API and specifying await within the `export` statement. Any modules that include this will wait for the fetch to resolve before running any code.

```js
// fetch request
const colors = fetch("../data/colors.json").then((response) => response.json());

export default await colors;
```

### Control flow effects of await

When an `await` is encountered in code (either in an async function or in a module), the awaited expression is executed, while all code that depends on the expression's value is paused and pushed into the microtask queue. The main thread is then freed for the next task in the event loop. This happens even if the awaited value is an already-resolved promise or not a promise. For example, consider the following code:

```js
async function foo(name) {
  console.log(name, "start");
  console.log(name, "middle");
  console.log(name, "end");
}

foo("First");
foo("Second");

// First start
// First middle
// First end
// Second start
// Second middle
// Second end
```

In this case, the two async functions are synchronous in effect, because they don't contain any `await` expression. The three statements happen in the same tick. In promise terms, the function corresponds to:

```js
function foo(name) {
  return new Promise((resolve) => {
    console.log(name, "start");
    console.log(name, "middle");
    console.log(name, "end");
    resolve();
  });
}
```

However, as soon as there's one `await`, the function becomes asynchronous, and execution of following statements is deferred to the next tick.

```js
async function foo(name) {
  console.log(name, "start");
  await console.log(name, "middle");
  console.log(name, "end");
}

foo("First");
foo("Second");

// First start
// First middle
// Second start
// Second middle
// First end
// Second end
```

This corresponds to:

```js
function foo(name) {
  return new Promise((resolve) => {
    console.log(name, "start");
    resolve(console.log(name, "middle"));
  }).then(() => {
    console.log(name, "end");
  });
}
```

While the extra `then()` handler is not necessary, and the handler can be merged with the executor passed to the constructor, the `then()` handler's existence means the code will take one extra tick to complete. The same happens for `await`. Therefore, make sure to use `await` only when necessary (to unwrap promises into their values).

Other microtasks can execute before the async function resumes. This example uses `queueMicrotask()` to demonstrate how the microtask queue is processed when each `await` expression is encountered.

```js
let i = 0;

queueMicrotask(function test() {
  i++;
  console.log("microtask", i);
  if (i < 3) {
    queueMicrotask(test);
  }
});

(async () => {
  console.log("async function start");
  for (let i = 1; i < 3; i++) {
    await null;
    console.log("async function resume", i);
  }
  await null;
  console.log("async function end");
})();

queueMicrotask(() => {
  console.log("queueMicrotask() after calling async function");
});

console.log("script sync part end");

// Logs:
// async function start
// script sync part end
// microtask 1
// async function resume 1
// queueMicrotask() after calling async function
// microtask 2
// async function resume 2
// microtask 3
// async function end
```

In this example, the `test()` function is always called before the async function resumes, so the microtasks they each schedule are always executed in an intertwined fashion. On the other hand, because both `await` and `queueMicrotask()` schedule microtasks, the order of execution is always based on the order of scheduling. This is why the "queueMicrotask() after calling async function" log happens after the async function resumes for the first time.

### Improving stack trace

Sometimes, the `await` is omitted when a promise is directly returned from an async function.

```js
async function noAwait() {
  // Some actions...

  return /\* await \*/ lastAsyncTask();
}
```

However, consider the case where `lastAsyncTask` asynchronously throws an error.

```js
async function lastAsyncTask() {
  await null;
  throw new Error("failed");
}

async function noAwait() {
  return lastAsyncTask();
}

noAwait();

// Error: failed
// at lastAsyncTask
```

Only `lastAsyncTask` appears in the stack trace, because the promise is rejected after it has already been returned from `noAwait` — in some sense, the promise is unrelated to `noAwait`. To improve the stack trace, you can use `await` to unwrap the promise, so that the exception gets thrown into the current function. The exception will then be immediately wrapped into a new rejected promise, but during error creation, the caller will appear in the stack trace.

```js
async function lastAsyncTask() {
  await null;
  throw new Error("failed");
}

async function withAwait() {
  return await lastAsyncTask();
}

withAwait();

// Error: failed
// at lastAsyncTask
// at async withAwait
```

However, there's a little performance penalty coming with `return await` because the promise has to be unwrapped and wrapped again.

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

* `async function`
* `async function` expression
* `AsyncFunction`
* Top-level await on v8.dev (2019)


Optional chaining (?.) - JavaScript

Optional chaining (?.)
======================

The **optional chaining (`?.`)** operator accesses an object's property or calls a function. If the object accessed or function called using this operator is `undefined` or `null`, the expression short circuits and evaluates to `undefined` instead of throwing an error.

Try it
------

Syntax
------

```js
obj.val?.prop
obj.val?.[expr]
obj.func?.(args)
```

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

The `?.` operator is like the `.` chaining operator, except that instead of causing an error if a reference is nullish (`null` or `undefined`), the expression short-circuits with a return value of `undefined`. When used with function calls, it returns `undefined` if the given function does not exist.

This results in shorter and simpler expressions when accessing chained properties when the possibility exists that a reference may be missing. It can also be helpful while exploring the content of an object when there's no known guarantee as to which properties are required.

 For example, consider an object `obj` which has a nested structure. Without
 optional chaining, looking up a deeply-nested subproperty requires validating the
 references in between, such as:

```js
const nestedProp = obj.first && obj.first.second;
```

 The value of `obj.first` is confirmed to be non-`null` (and
 non-`undefined`) before accessing the value of
 `obj.first.second`. This prevents the error that would occur if you accessed
 `obj.first.second` directly without testing `obj.first`.

This is an idiomatic pattern in JavaScript, but it gets verbose when the chain is long, and it's not safe. For example, if `obj.first` is a Falsy value that's not `null` or `undefined`, such as `0`, it would still short-circuit and make `nestedProp` become `0`, which may not be desirable.

 With the optional chaining operator (`?.`), however, you don't have to
 explicitly test and short-circuit based on the state of `obj.first` before
 trying to access `obj.first.second`:

```js
const nestedProp = obj.first?.second;
```

 By using the `?.` operator instead of just `.`, JavaScript knows
 to implicitly check to be sure `obj.first` is not `null` or
 `undefined` before attempting to access `obj.first.second`. If
 `obj.first` is `null` or `undefined`, the expression
 automatically short-circuits, returning `undefined`.

 This is equivalent to the following, except that the temporary variable is in fact not
 created:

```js
const temp = obj.first;
const nestedProp =
  temp === null || temp === undefined ? undefined : temp.second;
```

Optional chaining cannot be used on a non-declared root object, but can be used with a root object with value `undefined`.

```js
undeclaredVar?.prop; // ReferenceError: undeclaredVar is not defined
```

### Optional chaining with function calls

 You can use optional chaining when attempting to call a method which may not exist.
 This can be helpful, for example, when using an API in which a method might be
 unavailable, either due to the age of the implementation or because of a feature which
 isn't available on the user's device.

 Using optional chaining with function calls causes the expression to automatically
 return `undefined` instead of throwing an exception if the method isn't
 found:

```js
const result = someInterface.customMethod?.();
```

However, if there is a property with such a name which is not a function, using `?.` will still raise a `TypeError` exception "someInterface.customMethod is not a function".

**Note:** If `someInterface` itself is `null` or
 `undefined`, a `TypeError` exception will still be
 raised ("someInterface is null"). If you expect that
 `someInterface` itself may be `null` or `undefined`,
 you have to use `?.` at this position as
 well: `someInterface?.customMethod?.()`.

`eval?.()` is the shortest way to enter *indirect eval* mode.

### Optional chaining with expressions

You can also use the optional chaining operator with bracket notation, which allows passing an expression as the property name:

```js
const nestedProp = obj?.["prop" + "Name"];
```

This is particularly useful for arrays, since array indices must be accessed with square brackets.

```js
function printMagicIndex(arr) {
  console.log(arr?.[42]);
}

printMagicIndex([0, 1, 2, 3, 4, 5]); // undefined
printMagicIndex(); // undefined; if not using ?., this would throw an error: "Cannot read properties of undefined (reading '42')"
```

### Optional chaining not valid on the left-hand side of an assignment

It is invalid to try to assign to the result of an optional chaining expression:

```js
const object = {};
object?.property = 1; // SyntaxError: Invalid left-hand side in assignment
```

### Short-circuiting

When using optional chaining with expressions, if the left operand is `null` or `undefined`, the expression will not be evaluated. For instance:

```js
const potentiallyNullObj = null;
let x = 0;
const prop = potentiallyNullObj?.[x++];

console.log(x); // 0 as x was not incremented
```

Subsequent property accesses will not be evaluated either.

```js
const potentiallyNullObj = null;
const prop = potentiallyNullObj?.a.b;
// This does not throw, because evaluation has already stopped at
// the first optional chain
```

This is equivalent to:

```js
const potentiallyNullObj = null;
const prop =
  potentiallyNullObj === null || potentiallyNullObj === undefined
    ? undefined
    : potentiallyNullObj.a.b;
```

However, this short-circuiting behavior only happens along one continuous "chain" of property accesses. If you group one part of the chain, then subsequent property accesses will still be evaluated.

```js
const potentiallyNullObj = null;
const prop = (potentiallyNullObj?.a).b;
// TypeError: Cannot read properties of undefined (reading 'b')
```

This is equivalent to:

```js
const potentiallyNullObj = null;
const temp = potentiallyNullObj?.a;
const prop = temp.b;
```

Except the `temp` variable isn't created.

Examples
--------

### Basic example

 This example looks for the value of the `name` property for the member
 `bar` in a map when there is no such member. The result is therefore
 `undefined`.

```js
const myMap = new Map();
myMap.set("foo", { name: "baz", desc: "inga" });

const nameBar = myMap.get("bar")?.name;
```

### Dealing with optional callbacks or event handlers

 If you use callbacks or fetch methods from an object with
 a destructuring assignment, you may have non-existent values that you cannot call as
 functions unless you have tested their existence. Using `?.`, you can avoid this extra test:

```js
// Code written without optional chaining
function doSomething(onContent, onError) {
  try {
    // Do something with the data
  } catch (err) {
    // Testing if onError really exists
    if (onError) {
      onError(err.message);
    }
  }
}
```

```js
// Using optional chaining with function calls
function doSomething(onContent, onError) {
  try {
    // Do something with the data
  } catch (err) {
    onError?.(err.message); // No exception if onError is undefined
  }
}
```

### Stacking the optional chaining operator

With nested structures, it is possible to use optional chaining multiple times:

```js
const customer = {
  name: "Carl",
  details: {
    age: 82,
    location: "Paradise Falls", // Detailed address is unknown
  },
};
const customerCity = customer.details?.address?.city;

// This also works with optional chaining function call
const customerName = customer.name?.getName?.(); // Method does not exist, customerName is undefined
```

### Combining with the nullish coalescing operator

The nullish coalescing operator may be used after optional chaining in order to build a default value when none was found:

```js
function printCustomerCity(customer) {
  const customerCity = customer?.city ?? "Unknown city";
  console.log(customerCity);
}

printCustomerCity({
  name: "Nathan",
  city: "Paris",
}); // "Paris"
printCustomerCity({
  name: "Carl",
  details: { age: 82 },
}); // "Unknown city"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-OptionalExpression |

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

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

See also
--------

* Nullish coalescing operator (`??`)


Increment (++) - JavaScript

Increment (++)
==============

The **increment (`++`)** operator increments (adds one to) its operand and returns the value before or after the increment, depending on where the operator is placed.

Try it
------

Syntax
------

```js
x++
++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 increment if the operand becomes a BigInt; otherwise, it performs number increment.

If used postfix, with operator after operand (for example, `x++`), the increment operator increments and returns the value before incrementing.

If used prefix, with operator before operand (for example, `++x`), the increment operator increments and returns the value after incrementing.

The increment operator can only be applied on operands that are references (variables and object properties; i.e. valid assignment targets). `++x` itself evaluates to a value, not a reference, so you cannot chain multiple increment operators together.

```js
++(++x); // SyntaxError: Invalid left-hand side expression in prefix operation
```

Examples
--------

### Postfix increment

```js
let x = 3;
const y = x++;
// x is 4; y is 3

let x2 = 3n;
const y2 = x2++;
// x2 is 4n; y2 is 3n
```

### Prefix increment

```js
let x = 3;
const y = ++x;
// x is 4; y is 4

let x2 = 3n;
const y2 = ++x2;
// x2 is 4n; y2 is 4n
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-postfix-increment-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 (`**`)
* Decrement (`--`)
* Unary negation (`-`)
* Unary plus (`+`)


Decrement (--) - JavaScript

Decrement (--)
==============

The **decrement (`--`)** operator decrements (subtracts one from) its operand and returns the value before or after the decrement, depending on where the operator is placed.

Try it
------

Syntax
------

```js
x--
--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 decrement if the operand becomes a BigInt; otherwise, it performs number decrement.

If used postfix, with operator after operand (for example, `x--`), the decrement operator decrements and returns the value before decrementing.

If used prefix, with operator before operand (for example, `--x`), the decrement operator decrements and returns the value after decrementing.

The decrement operator can only be applied on operands that are references (variables and object properties; i.e. valid assignment targets). `--x` itself evaluates to a value, not a reference, so you cannot chain multiple decrement operators together.

```js
--(--x); // SyntaxError: Invalid left-hand side expression in prefix operation
```

Examples
--------

### Postfix decrement

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

let x2 = 3n;
const y2 = x2--;
// x2 is 2n; y2 is 3n
```

### Prefix decrement

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

let x2 = 3n;
const y2 = --x2;
// x2 is 2n; y2 is 2n
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-postfix-decrement-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 (`++`)
* Unary negation (`-`)
* Unary plus (`+`)


Left shift assignment (<<=) - JavaScript

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

The **left shift assignment (`<<=`)** operator performs left shift 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 left shift assignment

```js
let a = 5;
// 00000000000000000000000000000101

a <<= 2; // 20
// 00000000000000000000000000010100

let b = 5n;
b <<= 2n; // 20n
```

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
* Left shift (`<<`)


yield - JavaScript

yield
=====

The **`yield`** operator is used to pause and resume a generator function.

Try it
------

Syntax
------

```js
yield
yield expression
```

### Parameters

`expression` Optional

The value to yield from the generator function via the iterator protocol. If omitted, `undefined` is yielded.

### Return value

Returns the optional value passed to the generator's `next()` method to resume its execution.

**Note:** This means `next()` is asymmetric: it always sends a value to the currently suspended `yield`, but returns the operand of the next `yield`. The argument passed to the first `next()` call cannot be retrieved because there's no currently suspended `yield`.

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

The `yield` keyword pauses generator function execution and the value of the expression following the `yield` keyword is returned to the generator's caller. It can be thought of as a generator-based version of the `return` keyword.

`yield` can only be used directly within the generator function that contains it. It cannot be used within nested functions.

Calling a generator function constructs a `Generator` object. Each time the generator's `next()` method is called, the generator resumes execution, and runs until it reaches one of the following:

* A `yield` expression. In this case, the generator pauses, and the `next()` method return an iterator result object with two properties: `value` and `done`. The `value` property is the value of the expression after the `yield` operator, and `done` is `false`, indicating that the generator function has not fully completed.
* The end of the generator function. In this case, execution of the generator ends, and the `next()` method returns an iterator result object where the `value` is `undefined` and `done` is `true`.
* A `return` statement. In this case, execution of the generator ends, and the `next()` method returns an iterator result object where the `value` is the specified return value and `done` is `true`.
* A `throw` statement. In this case, execution of the generator halts entirely, and the `next()` method throws the specified exception.

Once paused on a `yield` expression, the generator's code execution remains paused until the generator's `next()` method is called again. If an optional value is passed to the generator's `next()` method, that value becomes the value returned by the generator's current `yield` operation. The first `next()` call does not have a corresponding suspended `yield` operation, so there's no way to get the argument passed to the first `next()` call.

If the generator's `return()` or `throw()` method is called, it acts as if a `return` or `throw` statement was executed at the paused `yield` expression. You can use `try...catch...finally` within the generator function body to handle these early completions. If the `return()` or `throw()` method is called but there's no suspended `yield` expression (because `next()` has not been called yet, or because the generator has already completed), then the early completions cannot be handled and always terminate the generator.

Examples
--------

### Using yield

The following code is the declaration of an example generator function.

```js
function\* countAppleSales() {
  const saleList = [3, 7, 5];
  for (let i = 0; i < saleList.length; i++) {
    yield saleList[i];
  }
}
```

Once a generator function is defined, it can be used by constructing an iterator as shown.

```js
const appleStore = countAppleSales(); // Generator { }
console.log(appleStore.next()); // { value: 3, done: false }
console.log(appleStore.next()); // { value: 7, done: false }
console.log(appleStore.next()); // { value: 5, done: false }
console.log(appleStore.next()); // { value: undefined, done: true }
```

You can also send a value with `next(value)` into the generator. `step` evaluates as a return value of the `yield` expression — although the value passed to the generator's `next()` method the first time `next()` is called is ignored.

```js
function\* counter(value) {
  while (true) {
    const step = yield value++;

    if (step) {
      value += step;
    }
  }
}

const generatorFunc = counter(0);
console.log(generatorFunc.next().value); // 0
console.log(generatorFunc.next().value); // 1
console.log(generatorFunc.next().value); // 2
console.log(generatorFunc.next().value); // 3
console.log(generatorFunc.next(10).value); // 14
console.log(generatorFunc.next().value); // 15
console.log(generatorFunc.next(10).value); // 26
```

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-YieldExpression |

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*`


Logical AND (&&) - JavaScript

Logical AND (&&)
================

The **logical AND (`&&`)** (logical conjunction) operator for a set of boolean operands will be `true` if and only if all the operands are `true`. Otherwise it will be `false`.

More generally, the operator returns the value of the first falsy operand encountered when evaluating from left to right, or the value of the last operand if they are all truthy.

Try it
------

Syntax
------

```js
x && y
```

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

Logical AND (`&&`) evaluates operands from left to right, returning immediately with the value of the first falsy operand it encounters; if all values are truthy, the value of the last operand is returned.

If a value can be converted to `true`, the value is so-called truthy. If a value can be converted to `false`, the value is so-called falsy.

Examples of expressions that can be converted to false are:

* `false`;
* `null`;
* `NaN`;
* `0`;
* empty string (`""` or `''` or ````);
* `undefined`.

The AND operator preserves non-Boolean values and returns them as they are:

```js
result = "" && "foo"; // result is assigned "" (empty string)
result = 2 && 0; // result is assigned 0
result = "foo" && 4; // result is assigned 4
```

 Even though the `&&` operator can be used with non-Boolean operands, it is still considered a boolean operator since its return value can always be
 converted to a boolean primitive.
 To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double `NOT operator` or the `Boolean` constructor.

### Short-circuit evaluation

 The logical AND expression is a short-circuit operator.
 As each operand is converted to a boolean, if the result of one conversion is found to be `false`, the AND operator stops and returns the original value of that falsy operand; it does **not** evaluate any of the remaining operands.

Consider the pseudocode below.
```

(some falsy expression) && expr
```

 The `expr` part is **never evaluated** because the first operand `(some falsy expression)` is evaluated as falsy.
 If `expr` is a function, the function is never called.
 See the example below:

```js
function A() {
  console.log("called A");
  return false;
}
function B() {
  console.log("called B");
  return true;
}

console.log(A() && B());
// Logs "called A" to the console due to the call for function A,
// && evaluates to false (function A returns false), then false is logged to the console;
// the AND operator short-circuits here and ignores function B
```

### Operator precedence

The AND operator has a higher precedence than the OR operator, meaning the `&&` operator is executed before the `||` operator (see operator precedence).

```js
true || false && false; // true
true && (false || false); // false
(2 === 3) || (4 < 0) && (1 === 1); // false
```

Examples
--------

### Using AND

 The following code shows examples of the `&&` (logical AND)
 operator.

```js
a1 = true && true; // t && t returns true
a2 = true && false; // t && f returns false
a3 = false && true; // f && t returns false
a4 = false && 3 === 4; // f && f returns false
a5 = "Cat" && "Dog"; // t && t returns "Dog"
a6 = false && "Cat"; // f && t returns false
a7 = "Cat" && false; // t && f returns false
a8 = "" && false; // f && f returns ""
a9 = false && ""; // f && f returns false
```

### Conversion rules for booleans

#### Converting AND to OR

The following operation involving **booleans**:

```js
bCondition1 && bCondition2
```

is always equal to:

```js
!(!bCondition1 || !bCondition2)
```

#### Converting OR to AND

The following operation involving **booleans**:

```js
bCondition1 || bCondition2
```

is always equal to:

```js
!(!bCondition1 && !bCondition2)
```

### Removing nested parentheses

As logical expressions are evaluated left to right, it is always possible to remove parentheses from a complex expression provided that certain rules are followed.

The following composite operation involving **booleans**:

```js
bCondition1 || (bCondition2 && bCondition3)
```

is always equal to:

```js
bCondition1 || bCondition2 && bCondition3
```

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-LogicalANDExpression |

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

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

See also
--------

* `Boolean`
* Truthy
* Falsy


Exponentiation assignment (**=) - JavaScript

Exponentiation assignment (\*\*=)
=================================

The \*\*exponentiation assignment (`**=`)\*\* operator performs exponentiation 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 exponentiation assignment

```js
let bar = 5;

bar \*\*= 2; // 25
bar \*\*= "foo"; // NaN

let foo = 3n;
foo \*\*= 2n; // 9n
```

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
* Exponentiation (`**`)


Conditional (ternary) operator - JavaScript

Conditional (ternary) operator
==============================

 The **conditional (ternary) operator** is the only JavaScript operator that takes three operands:
 a condition followed by a question mark (`?`), then an expression to execute if the condition is truthy followed by a colon (`:`), and finally the expression to execute if the condition is falsy.
 This operator is frequently used as an alternative to an `if...else` statement.

Try it
------

Syntax
------

```js
condition ? exprIfTrue : exprIfFalse
```

### Parameters

`condition`

An expression whose value is used as a condition.

`exprIfTrue`

An expression which is executed if the `condition` evaluates to a truthy value (one which equals or can be converted to `true`).

`exprIfFalse`

An expression which is executed if the `condition` is falsy (that is, has a value which can be converted to `false`).

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

 Besides `false`, possible falsy expressions are: `null`, `NaN`, `0`, the empty string (`""`), and `undefined`.
 If `condition` is any of these, the result of the conditional expression will be the result of executing the expression `exprIfFalse`.

Examples
--------

### A simple example

```js
const age = 26;
const beverage = age >= 21 ? "Beer" : "Juice";
console.log(beverage); // "Beer"
```

### Handling null values

One common usage is to handle a value that may be `null`:

```js
const greeting = (person) => {
  const name = person ? person.name : "stranger";
  return `Howdy, ${name}`;
};

console.log(greeting({ name: "Alice" })); // "Howdy, Alice"
console.log(greeting(null)); // "Howdy, stranger"
```

### Conditional chains

The ternary operator is right-associative, which means it can be "chained" in the following way, similar to an `if … else if … else if … else` chain:

```js
function example() {
  return condition1 ? value1
    : condition2 ? value2
    : condition3 ? value3
    : value4;
}
```

This is equivalent to the following `if...else` chain.

```js
function example() {
  if (condition1) {
    return value1;
  } else if (condition2) {
    return value2;
  } else if (condition3) {
    return value3;
  } else {
    return value4;
  }
}
```

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

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

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

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

See also
--------

* `if...else`
* Nullish coalescing operator (`??`)
* Optional chaining (`?.`)
* Making decisions in your code — conditionals
* Expressions and operators guide


Division (/) - JavaScript

Division (/)
============

The **division (`/`)** operator produces the quotient of its operands where the left operand is the dividend and the right operand is the divisor.

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 division if both operands become BigInts; otherwise, it performs number division. A `TypeError` is thrown if one operand becomes a BigInt but the other becomes a number.

For BigInt division, the result is the quotient of the two operands truncated towards zero, and the remainder is discarded. A `RangeError` is thrown if the divisor `y` is `0n`. This is because number division by zero returns `Infinity` or `-Infinity`, but BigInt has no concept of infinity.

Examples
--------

### Basic division

```js
1 / 2; // 0.5

Math.floor(3 / 2); // 1

1.0 / 2.0; // 0.5

1n / 2n; // 0n
5n / 3n; // 1n
-1n / 3n; // 0n
1n / -3n; // 0n

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

// To do division with a BigInt and a non-BigInt, convert either operand
2n / BigInt(2); // 1n
Number(2n) / 2; // 1
```

### Division by zero

```js
2.0 / 0; // Infinity

2.0 / 0.0; // Infinity, because 0.0 === 0

2.0 / -0.0; // -Infinity

2n / 0n; // RangeError: Division by zero
```

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 (`-`)
* Multiplication (`*`)
* Remainder (`%`)
* Exponentiation (`**`)
* Increment (`++`)
* Decrement (`--`)
* Unary negation (`-`)
* Unary plus (`+`)


Division assignment (/=) - JavaScript

Division assignment (/=)
========================

The **division assignment (`/=`)** operator performs division 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 division assignment

```js
let bar = 5;

bar /= 2; // 2.5
bar /= 2; // 1.25
bar /= 0; // Infinity
bar /= "foo"; // NaN

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

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
* Division (`/`)


function expression - JavaScript

function expression
===================

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

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

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. See also the chapter about functions for more information.

### Function expression hoisting

Function expressions in JavaScript are not hoisted, unlike function declarations. You can't use function expressions before you create them:

```js
console.log(notHoisted); // undefined
// Even though the variable name is hoisted,
// the definition isn't. so it's undefined.
notHoisted(); // TypeError: notHoisted is not a function

var notHoisted = function () {
  console.log("bar");
};
```

### Named function expression

If you want to refer to the current function inside the function body, you need to create a named function expression. This name is then local only to the function body (scope). This avoids using the deprecated `arguments.callee` property to call the function recursively.

```js
const math = {
  factit: function factorial(n) {
    console.log(n);
    if (n <= 1) {
      return 1;
    }
    return n \* factorial(n - 1);
  },
};

math.factit(3); //3;2;1;
```

If a function expression is named, the `name` property of the function is set to that name, instead of the implicit name inferred from syntax (such as the variable the function is assigned to).

Unlike declarations, the name of the function expressions is read-only.

```js
function foo() {
  foo = 1;
}
foo();
console.log(foo); // 1
(function foo() {
  foo = 1; // TypeError: Assignment to constant variable.
})();
```

Examples
--------

### Using function expression

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

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

### Using a function as a callback

More commonly it is used as a callback:

```js
button.addEventListener("click", function (event) {
  console.log("button is clicked!");
});
```

### Using an Immediately Invoked Function Expression (IIFE)

An anonymous function is created and called:

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

// or

!function () {
  console.log("Code runs!");
}();
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-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`
* `Function`
* Arrow functions


Strict equality (===) - JavaScript

Strict equality (===)
=====================

 The **strict equality (`===`)** operator checks whether its two operands are
 equal, returning a Boolean result. Unlike the equality operator,
 the strict equality operator always considers operands of different types to be
 different.

Try it
------

Syntax
------

```js
x === y
```

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

The strict equality operators (`===` and `!==`) provide the IsStrictlyEqual semantic.

* If the operands are of different types, return `false`.
* If both operands are objects, return `true` only if they refer to the
 same object.
* If both operands are `null` or both operands are `undefined`,
 return `true`.
* If either operand is `NaN`, return `false`.
* Otherwise, compare the two operand's values:
    + Numbers must have the same numeric values. `+0` and `-0`
     are considered to be the same value.
    + Strings must have the same characters in the same order.
    + Booleans must be both `true` or both `false`.

 The most notable difference between this operator and the equality
 (`==`) operator is that if the operands are of different types, the
 `==` operator attempts to convert them to the same type before comparing.

Examples
--------

### Comparing operands of the same type

```js
"hello" === "hello"; // true
"hello" === "hola"; // false

3 === 3; // true
3 === 4; // false

true === true; // true
true === false; // false

null === null; // true
```

### Comparing operands of different types

```js
"3" === 3; // false
true === 1; // false
null === undefined; // false
3 === new Number(3); // false
```

### Comparing objects

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

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

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

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

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

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

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

See also
--------

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


async function* expression - JavaScript

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

The **`async function*`** keywords can be used to define an async generator function inside an expression.

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

Try it
------

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 create an ad-hoc async iterable object. See also the chapter about functions for more information.

Examples
--------

### Using async function\* expression

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

```js
const x = async function\* (y) {
  yield Promise.resolve(y \* y);
};
x(6)
  .next()
  .then((res) => console.log(res.value)); // 36
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-async-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
* `async function*`
* `AsyncGeneratorFunction`
* Iteration protocols
* `yield`
* `yield*`


Bitwise OR assignment (

Bitwise OR assignment (|=)
==========================

The **bitwise OR assignment (`|=`)** operator performs bitwise OR 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 bitwise OR assignment

```js
let a = 5;
a |= 2; // 7
// 5: 00000000000000000000000000000101
// 2: 00000000000000000000000000000010
// -----------------------------------
// 7: 00000000000000000000000000000111

let b = 5n;
b |= 2n; // 7n
```

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
* Bitwise OR (`|`)
* Logical OR assignment (`||=`)


Bitwise XOR (^) - JavaScript

Bitwise XOR (^)
===============

The **bitwise XOR (`^`)** operator returns a number or BigInt whose binary representation has a `1` in each bit position for which the corresponding bits of either but not 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 XOR if both operands become BigInts; otherwise, it converts both operands to 32-bit integers and performs number bitwise XOR. 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 XOR operation is:

| x | y | x XOR y |
| --- | --- | --- |
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
```

     9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (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 XORing any number `x` with `0` returns `x` converted to a 32-bit integer. Do not use `^ 0` to truncate numbers to integers; use `Math.trunc()` instead.

Examples
--------

### Using bitwise XOR

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

14 ^ 9;
// 7 (00000000000000000000000000000111)

14n ^ 9n; // 7n
```

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-BitwiseXORExpression |

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 XOR assignment (`^=`)


Strict inequality (!==) - JavaScript

Strict inequality (!==)
=======================

 The **strict inequality (`!==`)** operator checks whether its two operands are
 not equal, returning a Boolean result. Unlike the inequality
 operator, the strict inequality operator always considers operands of different types to
 be different.

Try it
------

Syntax
------

```js
x !== y
```

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

 The strict inequality operator checks whether its operands are not equal.
 It is the negation of the
 strict equality operator
 so the following two lines will always give the same result:

```js
x !== y;

!(x === y);
```

 For details of the comparison algorithm, see the page for the
 strict equality operator.

 Like the strict equality operator, the strict inequality operator will always consider
 operands of different types to be different:

```js
3 !== "3"; // true
```

Examples
--------

### Comparing operands of the same type

```js
"hello" !== "hello"; // false
"hello" !== "hola"; // true

3 !== 3; // false
3 !== 4; // true

true !== true; // false
true !== false; // true

null !== null; // false
```

### Comparing operands of different types

```js
"3" !== 3; // true
true !== 1; // true
null !== undefined; // true
```

### Comparing objects

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

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

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

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

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


Bitwise NOT (~) - JavaScript

Bitwise NOT (~)
===============

The **bitwise NOT (`~`)** operator returns a number or BigInt whose binary representation has a `1` in each bit position for which the corresponding bit of the operand is `0`, and a `0` otherwise.

Try it
------

Syntax
------

```js
~x
```

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 the operand to a numeric value and tests the type of it. It performs BigInt NOT if the operand becomes a BigInt; otherwise, it converts the operand to a 32-bit integer and performs number bitwise NOT.

The operator operates on the operands' bit representations in two's complement. The operator is applied to each bit, and the result is constructed bitwise.

The truth table for the NOT operation is:

| x | NOT x |
| --- | --- |
| 0 | 1 |
| 1 | 0 |
```

 9 (base 10) = 00000000000000000000000000001001 (base 2)
               --------------------------------
~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (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 NOTing any 32-bit integer `x` yields `-(x + 1)`. For example, `~-5` yields `4`.

Bitwise NOTing any number `x` twice returns `x` converted to a 32-bit integer. Do not use `~~x` to truncate numbers to integers; use `Math.trunc()` instead. Due to using 32-bit representation for numbers, both `~-1` and `~4294967295` (232 - 1) result in `0`.

Examples
--------

### Using bitwise NOT

```js
~0; // -1
~-1; // 0
~1; // -2

~0n; // -1n
~4294967295n; // -4294967296n
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-bitwise-not-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


Addition assignment (+=) - JavaScript

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

The **addition assignment (`+=`)** operator performs addition (which is either numeric addition or string concatenation) 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 addition assignment

```js
let baz = true;

// Boolean + Number -> addition
baz += 1; // 2

// Number + Boolean -> addition
baz += false; // 2
```

```js
let foo = "foo";

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

// String + String -> concatenation
foo += "bar"; // "foofalsebar"
```

```js
let bar = 5;

// Number + Number -> addition
bar += 2; // 7

// Number + String -> concatenation
bar += "foo"; // "7foo"
```

```js
let x = 1n;

// BigInt + BigInt -> addition
x += 2n; // 3n

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

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
* Addition (`+`)


new - JavaScript

new
===

The **`new`** operator lets developers create an instance of a user-defined object type or of one of the built-in object types that has a constructor function.

Try it
------

Syntax
------

```js
new constructor
new constructor()
new constructor(arg1)
new constructor(arg1, arg2)
new constructor(arg1, arg2, /\* …, \*/ argN)
```

### Parameters

`constructor`

A class or function that specifies the type of the object instance.

`arg1`, `arg2`, …, `argN`

A list of values that the `constructor` will be called with. `new Foo` is equivalent to `new Foo()`, i.e. if no argument list is specified, `Foo` is called without arguments.

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

When a function is called with the **`new`** keyword, the function will be used as a constructor. `new` will do the following things:

1. Creates a blank, plain JavaScript object. For convenience, let's call it `newInstance`.
2. Points `newInstance`'s [[Prototype]] to the constructor function's `prototype` property, if the `prototype` is an `Object`. Otherwise, `newInstance` stays as a plain object with `Object.prototype` as its [[Prototype]].

**Note:** Properties/objects added to the constructor function's `prototype` property are therefore accessible to all instances created from the constructor function.
3. Executes the constructor function with the given arguments, binding `newInstance` as the `this` context (i.e. all references to `this` in the constructor function now refer to `newInstance`).
4. If the constructor function returns a non-primitive, this return value becomes the result of the whole `new` expression. Otherwise, if the constructor function doesn't return anything or returns a primitive, `newInstance` is returned instead. (Normally constructors don't return a value, but they can choose to do so to override the normal object creation process.)

Classes can only be instantiated with the `new` operator — attempting to call a class without `new` will throw a `TypeError`.

Creating an object with a user-defined constructor function requires two steps:

1. Define the object type by writing a function that specifies its name and properties.
 For example, a constructor function to create an object `Foo` might look like this:

```js
function Foo(bar1, bar2) {
  this.bar1 = bar1;
  this.bar2 = bar2;
}
```

2. Create an instance of the object with `new`.

```js
const myFoo = new Foo("Bar 1", 2021);
```

**Note:** An object can have a property that is itself another object. See the examples below.

You can always add a property to a previously defined object instance. For example, the statement `car1.color = "black"` adds a property `color` to `car1`, and assigns it a value of `"black"`.

However, this does not affect any other objects. To add the new property to all objects of the same type, you must add the property to the constructor's `prototype` property. This defines a property that is shared by all objects created with that function, rather than by just one instance of the object type. The following code adds a `color` property with value `"original color"` to all objects of type `Car`, and then overwrites that value with the string `"black"` only in the instance object `car1`. For more information, see prototype.

```js
function Car() {}
const car1 = new Car();
const car2 = new Car();

console.log(car1.color); // undefined

Car.prototype.color = "original color";
console.log(car1.color); // 'original color'

car1.color = "black";
console.log(car1.color); // 'black'

console.log(Object.getPrototypeOf(car1).color); // 'original color'
console.log(Object.getPrototypeOf(car2).color); // 'original color'
console.log(car1.color); // 'black'
console.log(car2.color); // 'original color'
```

**Note:** While the constructor function can be invoked like any regular function (i.e. without the `new` operator),
 in this case a new object is not created and the value of `this` is also different.

A function can know whether it is invoked with `new` by checking `new.target`. `new.target` is only `undefined` when the function is invoked without `new`. For example, you can have a function that behaves differently when it's called versus when it's constructed:

```js
function Car(color) {
  if (!new.target) {
    // Called as function.
    return `${color} car`;
  }
  // Called with new.
  this.color = color;
}

const a = Car("red"); // a is "red car"
const b = new Car("red"); // b is `Car { color: "red" }`
```

Prior to ES6, which introduced classes, most JavaScript built-ins are both callable and constructible, although many of them exhibit different behaviors. To name a few:

* `Array()`, `Error()`, and `Function()` behave the same when called as a function or a constructor.
* `Boolean()`, `Number()`, and `String()` coerce their argument to the respective primitive type when called, and return wrapper objects when constructed.
* `Date()` returns a string representing the current date when called, equivalent to `new Date().toString()`.

After ES6, the language is stricter about which are constructors and which are functions. For example:

* `Symbol()` and `BigInt()` can only be called without `new`. Attempting to construct them will throw a `TypeError`.
* `Proxy` and `Map` can only be constructed with `new`. Attempting to call them will throw a `TypeError`.
Examples
--------

### Object type and object instance

 Suppose you want to create an object type for cars. You want this type of object to be
 called `Car`, and you want it to have properties for make, model, and year.
 To do this, you would write the following function:

```js
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
```

Now you can create an object called `myCar` as follows:

```js
const myCar = new Car("Eagle", "Talon TSi", 1993);
```

 This statement creates `myCar` and assigns it the specified values for its
 properties. Then the value of `myCar.make` is the string "Eagle",
 `myCar.year` is the integer 1993, and so on.

 You can create any number of `car` objects by calls to `new`. For
 example:

```js
const kensCar = new Car("Nissan", "300ZX", 1992);
```

### Object property that is itself another object

Suppose you define an object called `Person` as follows:

```js
function Person(name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}
```

And then instantiate two new `Person` objects as follows:

```js
const rand = new Person("Rand McNally", 33, "M");
const ken = new Person("Ken Jones", 39, "M");
```

 Then you can rewrite the definition of `Car` to include an
 `owner` property that takes a `Person` object, as follows:

```js
function Car(make, model, year, owner) {
  this.make = make;
  this.model = model;
  this.year = year;
  this.owner = owner;
}
```

To instantiate the new objects, you then use the following:

```js
const car1 = new Car("Eagle", "Talon TSi", 1993, rand);
const car2 = new Car("Nissan", "300ZX", 1992, ken);
```

 Instead of passing a literal string or integer value when creating the new objects, the
 above statements pass the objects `rand` and `ken` as the
 parameters for the owners. To find out the name of the owner of `car2`, you
 can access the following property:

```js
car2.owner.name;
```

### Using `new` with classes

```js
class Person {
  constructor(name) {
    this.name = name;
  }
  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

const p = new Person("Caroline");
p.greet(); // Hello, my name is Caroline
```

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

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

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

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

See also
--------

* `Function`
* `Reflect.construct()`
* `Object`


Less than (<) - JavaScript

Less than (<)
=============

The **less than (`<`)** operator returns `true` if the left operand is less than the right operand, and `false` otherwise.

Try it
------

Syntax
------

```js
x < y
```

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

The operands are compared with multiple rounds of coercion, which can be summarized as follows:

* First, objects are converted to primitives by calling its `[@@toPrimitive]()` (with `"number"` as hint), `valueOf()`, and `toString()` methods, in that order. The left operand is always coerced before the right one. Note that although `[@@toPrimitive]()` is called with the `"number"` hint (meaning there's a slight preference for the object to become a number), the return value is not converted to a number, since strings are still specially handled.
* If both values are strings, they are compared as strings, based on the values of the UTF-16 code units (not Unicode code points) they contain.
* Otherwise JavaScript attempts to convert non-numeric types to numeric values:
    + Boolean values `true` and `false` are converted to 1 and 0 respectively.
    + `null` is converted to 0.
    + `undefined` is converted to `NaN`.
    + Strings are converted based on the values they contain, and are converted as `NaN` if they do not contain numeric values.
* If either value is `NaN`, the operator returns `false`.
* Otherwise the values are compared as numeric values. BigInt and number values can be compared together.

Other operators, including `>`, `>=`, and `<=`, use the same algorithm as `<`. There are two cases where all four operators return `false`:

* If one of the operands gets converted to a BigInt, while the other gets converted to a string that cannot be converted to a BigInt value (it throws a syntax error when passed to `BigInt()`).
* If one of the operands gets converted to `NaN`. (For example, strings that cannot be converted to numbers, or `undefined`.)

For all other cases, the four operators have the following relationships:

```js
x < y === !(x >= y);
x <= y === !(x > y);
x > y === y < x;
x >= y === y <= x;
```

**Note:** One observable difference between `<` and `>` is the order of coercion, especially if the coercion to primitive has side effects. All comparison operators coerce the left operand before the right operand.

Examples
--------

### String to string comparison

```js
"a" < "b"; // true
"a" < "a"; // false
"a" < "3"; // false

"\uD855\uDE51" < "\uFF3A"; // true
```

### String to number comparison

```js
"5" < 3; // false
"3" < 3; // false
"3" < 5; // true

"hello" < 5; // false
5 < "hello"; // false

"5" < 3n; // false
"3" < 5n; // true
```

### Number to Number comparison

```js
5 < 3; // false
3 < 3; // false
3 < 5; // true
```

### Number to BigInt comparison

```js
5n < 3; // false
3 < 5n; // true
```

### Comparing Boolean, null, undefined, NaN

```js
true < false; // false
false < true; // true

0 < true; // true
true < 1; // false

null < 0; // false
null < 1; // true

undefined < 3; // false
3 < undefined; // false

3 < NaN; // false
NaN < 3; // false
```

### Comparison with side effects

Comparisons always coerce their operands to primitives. This means the same object may end up having different values within one comparison expression. For example, you may have two values that are both greater than and less than the other.

```js
class Mystery {
  static #coercionCount = -1;
  valueOf() {
    Mystery.#coercionCount++;
    // The left operand is coerced first, so this will return 0
    // Then it returns 1 for the right operand
    return Mystery.#coercionCount % 2;
  }
}

const l = new Mystery();
const r = new Mystery();
console.log(l < r && r < l);
// true
```

**Warning:** This can be a source of confusion. If your objects provide custom primitive conversion logic, make sure it is *idempotent*: multiple coercions should return the same value.

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

* Greater than (`>`)
* Greater than or equal (`>=`)
* Less than or equal (`<=`)


Bitwise OR (

Bitwise OR (|)
==============

The **bitwise OR (`|`)** operator returns a number or BigInt whose binary representation has a `1` in each bit position for which the corresponding bits of either or 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 OR if both operands become BigInts; otherwise, it converts both operands to 32-bit integers and performs number bitwise OR. 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 OR operation is:

| x | y | x OR y |
| --- | --- | --- |
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
```

     9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (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 ORing any number `x` with `0` returns `x` converted to a 32-bit integer. Do not use `| 0` to truncate numbers to integers; use `Math.trunc()` instead.

Examples
--------

### Using bitwise OR

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

14 | 9;
// 15 (00000000000000000000000000001111)

14n | 9n; // 15n
```

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-BitwiseORExpression |

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 OR assignment (`|=`)


Greater than or equal (>=) - JavaScript

Greater than or equal (>=)
==========================

 The **greater than or equal (`>=`)** operator returns `true` if
 the left operand is greater than or equal to the right operand, and `false`
 otherwise.

Try it
------

Syntax
------

```js
x >= y
```

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

The operands are compared using the same algorithm as the Less than operator, with the result negated. `x >= y` is generally equivalent to `!(x < y)`, except for two cases where `x >= y` and `x < y` are both `false`:

* If one of the operands gets converted to a BigInt, while the other gets converted to a string that cannot be converted to a BigInt value (it throws a syntax error when passed to `BigInt()`).
* If one of the operands gets converted to `NaN`. (For example, strings that cannot be converted to numbers, or `undefined`.)

`x >= y` is generally equivalent to `x > y || x == y`, except for a few cases:

* When one of `x` or `y` is `null`, and the other is something that's not `null` and becomes 0 when coerced to numeric (including `0`, `0n`, `false`, `""`, `"0"`, `new Date(0)`, etc.): `x >= y` is `true`, while `x > y || x == y` is `false`.
* When one of `x` or `y` is `undefined`, and the other is one of `null` or `undefined`: `x >= y` is `false`, while `x == y` is `true`.
* When `x` and `y` are the same object that becomes `NaN` after the first step of Less than (such as `new Date(NaN)`): `x >= y` is `false`, while `x == y` is `true`.
* When `x` and `y` are different objects that become the same value after the first step of Less than: `x >= y` is `true`, while `x > y || x == y` is `false`.
Examples
--------

### String to string comparison

```js
"a" >= "b"; // false
"a" >= "a"; // true
"a" >= "3"; // true
```

### String to number comparison

```js
"5" >= 3; // true
"3" >= 3; // true
"3" >= 5; // false

"hello" >= 5; // false
5 >= "hello"; // false
```

### Number to Number comparison

```js
5 >= 3; // true
3 >= 3; // true
3 >= 5; // false
```

### Number to BigInt comparison

```js
5n >= 3; // true
3 >= 3n; // true
3 >= 5n; // false
```

### Comparing Boolean, null, undefined, NaN

```js
true >= false; // true
true >= true; // true
false >= true; // false

true >= 0; // true
true >= 1; // true

null >= 0; // true
1 >= null; // true

undefined >= 3; // false
3 >= undefined; // false

3 >= NaN; // false
NaN >= 3; // false
```

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

* Greater than (`>`)
* Less than (`<`)
* Less than or equal (`<=`)


Multiplication assignment (*=) - JavaScript

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

The **multiplication assignment (`*=`)** operator performs multiplication 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 multiplication assignment

```js
let bar = 5;

bar \*= 2; // 10
bar \*= "foo"; // NaN

let foo = 3n;
foo \*= 2n; // 6n
```

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
* Multiplication (`*`)


Logical NOT (!) - JavaScript

Logical NOT (!)
===============

 The **logical NOT (`!`)** (logical complement, negation) operator takes truth to
 falsity and vice versa. It is typically used with boolean (logical)
 values. When used with non-Boolean values, it returns `false` if its single
 operand can be converted to `true`; otherwise, returns `true`.

Try it
------

Syntax
------

```js
!x
```

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

 Returns `false` if its single operand can be converted to `true`;
 otherwise, returns `true`.

 If a value can be converted to `true`, the value is so-called
 truthy. If a value can be converted to `false`, the value is
 so-called falsy.

Examples of expressions that can be converted to false are:

* `null`;
* `NaN`;
* `0`;
* empty string (`""` or `''` or ````);
* `undefined`.

Even though the `!` operator can be used with operands that are not Boolean values, it can still be considered a boolean operator since its return value can always be converted to a boolean primitive. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double NOT operator (`!!`) or the `Boolean` constructor.

Examples
--------

### Using NOT

The following code shows examples of the `!` (logical NOT) operator.

```js
!true; // !t returns false
!false; // !f returns true
!""; // !f returns true
!"Cat"; // !t returns false
```

### Double NOT (`!!`)

 It is possible to use a couple of NOT operators in series to explicitly force the
 conversion of any value to the corresponding boolean primitive.
 The conversion is based on the "truthyness" or "falsyness" of the value (see
 truthy and falsy).

The same conversion can be done through the `Boolean()` function.

```js
!!true; // !!truthy returns true
!!{}; // !!truthy returns true: any object is truthy...
!!new Boolean(false); // ...even Boolean objects with a false .valueOf()!
!!false; // !!falsy returns false
!!""; // !!falsy returns false
!!Boolean(false); // !!falsy returns false
```

### Converting between NOTs

The following operation involving **booleans**:

```js
!!bCondition
```

is always equal to:

```js
bCondition
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-logical-not-operator |

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

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

See also
--------

* `Boolean`
* Truthy
* Falsy


Property accessors - JavaScript

Property accessors
==================

**Property accessors** provide access to an object's properties by using the dot notation or the bracket notation.

Try it
------

Syntax
------

```js
object.propertyName
object[expression]
```

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

One can think of an object as an *associative array* (a.k.a. *map*, *dictionary*, *hash*, *lookup table*). The *keys* in this array are the names of the object's properties.

There are two ways to access properties: *dot notation* and *bracket notation*.

### Dot notation

In the `object.propertyName` syntax, the `propertyName` must be a valid JavaScript identifier which can also be a reserved word. For example, `object.$1` is valid, while `object.1` is not.

```js
const variable = object.propertyName;
object.propertyName = value;
```

```js
const object = {};
object.$1 = "foo";
console.log(object.$1); // 'foo'
```

```js
const object = {};
object.1 = 'bar'; // SyntaxError
console.log(object.1); // SyntaxError
```

Here, the method named `createElement` is retrieved from `document` and is called.

```js
document.createElement("pre");
```

If you use a method for a numeric literal, and the numeric literal has no exponent and no decimal point, you should leave white-space(s) before the dot preceding the method call, so that the dot is not interpreted as a decimal point.

```js
77 .toExponential();
// or
77
.toExponential();
// or
(77).toExponential();
// or
77..toExponential();
// or
77.0.toExponential();
// because 77. === 77.0, no ambiguity
```

### Bracket notation

In the `object[expression]` syntax, the `expression` should evaluate to a string or Symbol that represents the property's name. So, it can be any string literal, for example, including `'1foo'`, `'!bar!'`, or even `' '` (a space).

```js
const variable = object[propertyName];
object[propertyName] = value;
```

This does the exact same thing as the previous example.

```js
document["createElement"]("pre");
```

A space before bracket notation is allowed.

```js
document ["createElement"]("pre");
```

Passing expressions that evaluate to property name will do the same thing as directly passing the property name.

```js
const key = "name";
const getKey = () => "name";
const Obj = { name: "Michel" };

Obj["name"]; // returns "Michel"
Obj[key]; // evaluates to Obj["name"], and returns "Michel"
Obj[getKey()]; // evaluates to Obj["name"], and returns "Michel"
```

However, beware of using square brackets to access properties whose names are given by external input. This may make your code susceptible to object injection attacks.

### Property names

Each property name is a string or a Symbol. Any other value, including a number, is coerced to a string. This outputs `'value'`, since `1` is coerced into `'1'`.

```js
const object = {};
object["1"] = "value";
console.log(object[1]);
```

This also outputs `'value'`, since both `foo` and `bar` are converted to the same string (`"[object Object]"`).

```js
const foo = { uniqueProp: 1 };
const bar = { uniqueProp: 2 };
const object = {};
object[foo] = "value";
console.log(object[bar]);
```

### Method binding

It's typical when speaking of an object's properties to make a distinction between properties and methods. However, the property/method distinction is little more than a convention. A method is a property that can be called (for example, if it has a reference to a `Function` instance as its value).

A method is not bound to the object that it is a property of. Specifically, `this` is not fixed in a method and does not necessarily refer to the object containing the method. Instead, `this` is "passed" by the function call. See the reference for `this`.

Examples
--------

### Bracket notation vs. eval()

JavaScript novices often make the mistake of using `eval()` where the bracket notation can be used instead.

For example, the following syntax is often seen in many scripts.

```js
const x = eval(`document.forms.form\_name.elements.${strFormControl}.value`);
```

`eval()` is slow and should be avoided whenever possible. Also, `strFormControl` would have to hold an identifier, which is not required for names and `id`s of form controls. It is better to use bracket notation instead:

```js
const x = document.forms.form_name.elements[strFormControl].value;
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-property-accessors |

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

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

See also
--------

* `Object`
* `Object.defineProperty()`
* Optional chaining (`?.`)


import.meta - JavaScript

import.meta
===========

The **`import.meta`** meta-property exposes context-specific metadata to a JavaScript module. It contains information about the module, such as the module's URL.

Syntax
------

```js
import.meta
```

### Value

The `import.meta` object is created by the host environment, as an extensible `null`-prototype object where all properties are writable, configurable, and enumerable. The spec doesn't specify any properties to be defined on it, but hosts usually implement the following properties:

`url`

The full URL to the module, includes query parameters and/or hash (following the `?` or `#`). In browsers, this is either the URL from which the script was obtained (for external scripts), or the URL of the containing document (for inline scripts). In Node.js, this is the file path (including the `file://` protocol).

`resolve`

Resolves a module specifier to a URL using the current module's URL as base.

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

The `import.meta` syntax consists of the keyword `import`, a dot, and the identifier `meta`. Because `import` is a reserved word, not an identifier, this is not a property accessor, but a special expression syntax.

The `import.meta` meta-property is available in JavaScript modules; using `import.meta` outside of a module (including direct `eval()` within a module) is a syntax error.

Examples
--------

### Passing query parameters

Using query parameters in the `import` specifier allows module-specific argument passing, which may be complementary to reading parameters from the application-wide `window.location` (or on Node.js, through `process.argv`). For example, with the following HTML:

```html
<script type="module">
 import "./index.mjs?someURLInfo=5";
</script>
```

The `index.mjs` module is able to retrieve the `someURLInfo` parameter through `import.meta`:

```js
// index.mjs
new URL(import.meta.url).searchParams.get("someURLInfo"); // 5
```

The same applies when a module imports another:

```js
// index.mjs
import "./index2.mjs?someURLInfo=5";

// index2.mjs
new URL(import.meta.url).searchParams.get("someURLInfo"); // 5
```

The ES module implementation in Node.js supports resolving module specifiers containing query parameters (or the hash), as in the latter example. However, you cannot use queries or hashes when the module is specified through the CLI command (like `node index.mjs?someURLInfo=5`), because the CLI entrypoint uses a more CommonJS-like resolution mode, treating the path as a file path rather than a URL. To pass parameters to the entrypoint module, use CLI arguments and read them through `process.argv` instead (like `node index.mjs --someURLInfo=5`).

### Resolving a file relative to the current one

In Node.js CommonJS modules, there's a `__dirname` variable that contains the absolute path to the folder containing current module, which is useful for resolving relative paths. However, ES modules cannot have contextual variables except for `import.meta`. Therefore, to resolve a relative file you can use `import.meta.url`. Note that this uses URLs rather than filesystem paths.

Before (CommonJS):

```js
const fs = require("fs/promises");
const path = require("path");

const filePath = path.join(__dirname, "someFile.txt");
fs.readFile(filePath, "utf8").then(console.log);
```

After (ES modules):

```js
import fs from "node:fs/promises";

const fileURL = new URL("./someFile.txt", import.meta.url);
fs.readFile(fileURL, "utf8").then(console.log);
```

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-ImportMeta |
| HTML Standard # hostgetimportmetaproperties |

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

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

See also
--------

* `import`
* `export`


Logical OR assignment (

Logical OR assignment (||=)
===========================

The **logical OR assignment (`||=`)** operator only evaluates the right operand and assigns to the left if the left operand is falsy.

Try it
------

Syntax
------

```js
x ||= y
```

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

Logical OR assignment *short-circuits*, meaning that `x ||= y` is equivalent to `x || (x = y)`, except that the expression `x` is only evaluated once.

No assignment is performed if the left-hand side is not falsy, due to short-circuiting of the logical OR operator. For example, the following does not throw an error, despite `x` being `const`:

```js
const x = 1;
x ||= 2;
```

Neither would the following trigger the setter:

```js
const x = {
  get value() {
    return 1;
  },
  set value(v) {
    console.log("Setter called");
  },
};

x.value ||= 2;
```

In fact, if `x` is not falsy, `y` is not evaluated at all.

```js
const x = 1;
x ||= console.log("y evaluated");
// Logs nothing
```

Examples
--------

### Setting default content

If the "lyrics" element is empty, display a default value:

```js
document.getElementById("lyrics").textContent ||= "No lyrics.";
```

Here the short-circuit is especially beneficial, since the element will not be updated unnecessarily and won't cause unwanted side-effects such as additional parsing or rendering work, or loss of focus, etc.

 Note: Pay attention to the value returned by the API you're checking against. If an empty string is returned (a falsy value), `||=` must be used, so that "No lyrics." is displayed instead of a blank space. However, if the API returns `null` or
 `undefined` in case of blank content, `??=` should be used instead.

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

* Logical OR (`||`)
* Nullish coalescing operator (`??`)
* Bitwise OR assignment (`|=`)
* Truthy
* Falsy