Operator precedence - JavaScript

Operator precedence
===================

**Operator precedence** determines how operators are parsed concerning each other. Operators with higher precedence become the operands of operators with lower precedence.

Try it
------

Precedence and associativity
----------------------------

Consider an expression describable by the representation below, where both `OP1` and `OP2` are fill-in-the-blanks for OPerators.
```

a OP1 b OP2 c
```

The combination above has two possible interpretations:
```

(a OP1 b) OP2 c
a OP1 (b OP2 c)
```

Which one the language decides to adopt depends on the identity of `OP1` and `OP2`.

If `OP1` and `OP2` have different precedence levels (see the table below), the operator with the higher *precedence* goes first and associativity does not matter. Observe how multiplication has higher precedence than addition and executed first, even though addition is written first in the code.

```js
console.log(3 + 10 \* 2); // 23
console.log(3 + (10 \* 2)); // 23, because parentheses here are superfluous
console.log((3 + 10) \* 2); // 26, because the parentheses change the order
```

Within operators of the same precedence, the language groups them by *associativity*. *Left-associativity* (left-to-right) means that it is interpreted as `(a OP1 b) OP2 c`, while *right-associativity* (right-to-left) means it is interpreted as `a OP1 (b OP2 c)`. Assignment operators are right-associative, so you can write:

```js
a = b = 5; // same as writing a = (b = 5);
```

with the expected result that `a` and `b` get the value 5. This is because the assignment operator returns the value that is assigned. First, `b` is set to 5. Then the `a` is also set to 5 — the return value of `b = 5`, a.k.a. right operand of the assignment.

As another example, the unique exponentiation operator has right-associativity, whereas other arithmetic operators have left-associativity.

```js
const a = 4 \*\* 3 \*\* 2; // Same as 4 \*\* (3 \*\* 2); evaluates to 262144
const b = 4 / 3 / 2; // Same as (4 / 3) / 2; evaluates to 0.6666...
```

Operators are first grouped by precedence, and then, for adjacent operators that have the same precedence, by associativity. So, when mixing division and exponentiation, the exponentiation always comes before the division. For example, `2 ** 3 / 3 ** 2` results in 0.8888888888888888 because it is the same as `(2 ** 3) / (3 ** 2)`.

For prefix unary operators, suppose we have the following pattern:
```

OP1 a OP2 b
```

where `OP1` is a prefix unary operator and `OP2` is a binary operator. If `OP1` has higher precedence than `OP2`, then it would be grouped as `(OP1 a) OP2 b`; otherwise, it would be `OP1 (a OP2 b)`.

```js
const a = 1;
const b = 2;
typeof a + b; // Equivalent to (typeof a) + b; result is "number2"
```

If the unary operator is on the second operand:
```

a OP2 OP1 b
```

Then the binary operator `OP2` must have lower precedence than the unary operator `OP1` for it to be grouped as `a OP2 (OP1 b)`. For example, the following is invalid:

```js
function\* foo() {
  a + yield 1;
}
```

Because `+` has higher precedence than `yield`, this would become `(a + yield) 1` — but because `yield` is a reserved word in generator functions, this would be a syntax error. Luckily, most unary operators have higher precedence than binary operators and do not suffer from this pitfall.

If we have two prefix unary operators:
```

OP1 OP2 a
```

Then the unary operator closer to the operand, `OP2`, must have higher precedence than `OP1` for it to be grouped as `OP1 (OP2 a)`. It's possible to get it the other way and end up with `(OP1 OP2) a`:

```js
async function\* foo() {
  await yield 1;
}
```

Because `await` has higher precedence than `yield`, this would become `(await yield) 1`, which is awaiting an identifier called `yield`, and a syntax error. Similarly, if you have `new !A;`, because `!` has lower precedence than `new`, this would become `(new !) A`, which is obviously invalid. (This code looks nonsensical to write anyway, since `!A` always produces a boolean, not a constructor function.)

For postfix unary operators (namely, `++` and `--`), the same rules apply. Luckily, both operators have higher precedence than any binary operator, so the grouping is always what you would expect. Moreover, because `++` evaluates to a *value*, not a *reference*, you can't chain multiple increments together either, as you may do in C.

```js
let a = 1;
a++++; // SyntaxError: Invalid left-hand side in postfix operation.
```

Operator precedence will be handled *recursively*. For example, consider this expression:

```js
1 + 2 \*\* 3 \* 4 / 5 >> 6
```

First, we group operators with different precedence by decreasing levels of precedence.

1. The `**` operator has the highest precedence, so it's grouped first.
2. Looking around the `**` expression, it has `*` on the right and `+` on the left. `*` has higher precedence, so it's grouped first. `*` and `/` have the same precedence, so we group them together for now.
3. Looking around the `*`/`/` expression grouped in 2, because `+` has higher precedence than `>>`, the former is grouped.

```js
   (1 + ( (2 \*\* 3) \* 4 / 5) ) >> 6
// │ │ └─ 1. ─┘ │ │
// │ └────── 2. ───────┘ │
// └────────── 3. ──────────┘
```

Within the `*`/`/` group, because they are both left-associative, the left operand would be grouped.

```js
   (1 + ( ( (2 \*\* 3) \* 4 ) / 5) ) >> 6
// │ │ │ └─ 1. ─┘ │ │ │
// │ └─│─────── 2. ───│────┘ │
// └──────│───── 3. ─────│──────┘
// └───── 4. ─────┘
```

Note that operator precedence and associativity only affect the order of evaluation of *operators* (the implicit grouping), but not the order of evaluation of *operands*. The operands are always evaluated from left-to-right. The higher-precedence expressions are always evaluated first, and their results are then composed according to the order of operator precedence.

```js
function echo(name, num) {
  console.log(`Evaluating the ${name} side`);
  return num;
}
// Exponentiation operator (\*\*) is right-associative,
// but all call expressions (echo()), which have higher precedence,
// will be evaluated before \*\* does
console.log(echo("left", 4) \*\* echo("middle", 3) \*\* echo("right", 2));
// Evaluating the left side
// Evaluating the middle side
// Evaluating the right side
// 262144

// Exponentiation operator (\*\*) has higher precedence than division (/),
// but evaluation always starts with the left operand
console.log(echo("left", 4) / echo("middle", 3) \*\* echo("right", 2));
// Evaluating the left side
// Evaluating the middle side
// Evaluating the right side
// 0.4444444444444444
```

If you are familiar with binary trees, think about it as a post-order traversal.
```

                /
       ┌────────┴────────┐
echo("left", 4)         **
                ┌────────┴────────┐
        echo("middle", 3)  echo("right", 2)
```

After all operators have been properly grouped, the binary operators would form a binary tree. Evaluation starts from the outermost group — which is the operator with the lowest precedence (`/` in this case). The left operand of this operator is first evaluated, which may be composed of higher-precedence operators (such as a call expression `echo("left", 4)`). After the left operand has been evaluated, the right operand is evaluated in the same fashion. Therefore, all leaf nodes — the `echo()` calls — would be visited left-to-right, regardless of the precedence of operators joining them.

Short-circuiting
----------------

In the previous section, we said "the higher-precedence expressions are always evaluated first" — this is generally true, but it has to be amended with the acknowledgement of *short-circuiting*, in which case an operand may not be evaluated at all.

Short-circuiting is jargon for conditional evaluation. For example, in the expression `a && (b + c)`, if `a` is falsy, then the sub-expression `(b + c)` will not even get evaluated, even if it is grouped and therefore has higher precedence than `&&`. We could say that the logical AND operator (`&&`) is "short-circuited". Along with logical AND, other short-circuited operators include logical OR (`||`), nullish coalescing (`??`), and optional chaining (`?.`).

```js
a || (b \* c); // evaluate `a` first, then produce `a` if `a` is "truthy"
a && (b < c); // evaluate `a` first, then produce `a` if `a` is "falsy"
a ?? (b || c); // evaluate `a` first, then produce `a` if `a` is not `null` and not `undefined`
a?.b.c; // evaluate `a` first, then produce `undefined` if `a` is `null` or `undefined`
```

When evaluating a short-circuited operator, the left operand is always evaluated. The right operand will only be evaluated if the left operand cannot determine the result of the operation.

**Note:** The behavior of short-circuiting is baked in these operators. Other operators would *always* evaluate both operands, regardless if that's actually useful — for example, `NaN * foo()` will always call `foo`, even when the result would never be something other than `NaN`.

The previous model of a post-order traversal still stands. However, after the left subtree of a short-circuiting operator has been visited, the language will decide if the right operand needs to be evaluated. If not (for example, because the left operand of `||` is already truthy), the result is directly returned without visiting the right subtree.

Consider this case:

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

console.log(C() || B() && A());

// Logs:
// called C
// true
```

Only `C()` is evaluated, despite `&&` having higher precedence. This does not mean that `||` has higher precedence in this case — it's exactly *because* `(B() && A())` has higher precedence that causes it to be neglected as a whole. If it's re-arranged as:

```js
console.log(A() && C() || B());
// Logs:
// called A
// called B
// false
```

Then the short-circuiting effect of `&&` would only prevent `C()` from being evaluated, but because `A() && C()` as a whole is `false`, `B()` would still be evaluated.

However, note that short-circuiting does not change the final evaluation outcome. It only affects the evaluation of *operands*, not how *operators* are grouped — if evaluation of operands doesn't have side effects (for example, logging to the console, assigning to variables, throwing an error), short-circuiting would not be observable at all.

The assignment counterparts of these operators (`&&=`, `||=`, `??=`) are short-circuited as well. They are short-circuited in a way that the assignment does not happen at all.

Table
-----

The following table lists operators in order from highest precedence (18) to lowest precedence (1).

Several general notes about the table:

1. Not all syntax included here are "operators" in the strict sense. For example, spread `...` and arrow `=>` are typically not regarded as operators. However, we still included them to show how tightly they bind compared to other operators/expressions.
2. Some operators have certain operands that require expressions narrower than those produced by higher-precedence operators. For example, the right-hand side of member access `.` (precedence 17) must be an identifier instead of a grouped expression. The left-hand side of arrow `=>` (precedence 2) must be an arguments list or a single identifier instead of some random expression.
3. Some operators have certain operands that accept expressions wider than those produced by higher-precedence operators. For example, the bracket-enclosed expression of bracket notation `[ … ]` (precedence 17) can be any expression, even comma (precedence 1) joined ones. These operators act as if that operand is "automatically grouped". In this case we will omit the associativity.

| Precedence | Associativity | Individual operators | Notes |
| --- | --- | --- | --- |
| 18: grouping | n/a | Grouping`(x)` | [1] |
| 17: access and call | left-to-right | Member access`x.y` | [2] |
| Optional chaining`x?.y` |
| n/a | Computed member access`x[y]` | [3] |
| `new` with argument list`new x(y)` | [4] |
| Function call`x(y)` |
| `import(x)` |
| 16: new | n/a | `new` without argument list`new x` |
| 15: postfix operators | n/a | Postfix increment`x++` | [5] |
| Postfix decrement`x--` |
| 14: prefix operators | n/a | Prefix increment`++x` | [6] |
| Prefix decrement`--x` |
| Logical NOT`!x` |
| Bitwise NOT`~x` |
| Unary plus`+x` |
| Unary negation`-x` |
| `typeof x` |
| `void x` |
| `delete x` | [7] |
| `await x` |
| 13: exponentiation | right-to-left | Exponentiation`x ** y` | [8] |
| 12: multiplicative operators | left-to-right | Multiplication`x * y` |
| Division`x / y` |
| Remainder`x % y` |
| 11: additive operators | left-to-right | Addition`x + y` |
| Subtraction`x - y` |
| 10: bitwise shift | left-to-right | Left shift`x << y` |
| Right shift`x >> y` |
| Unsigned right shift`x >>> y` |
| 9: relational operators | left-to-right | Less than`x < y` |
| Less than or equal`x <= y` |
| Greater than`x > y` |
| Greater than or equal`x >= y` |
| `x in y` |
| `x instanceof y` |
| 8: equality operators | left-to-right | Equality`x == y` |
| Inequality`x != y` |
| Strict equality`x === y` |
| Strict inequality`x !== y` |
| 7: bitwise AND | left-to-right | Bitwise AND`x & y` |
| 6: bitwise XOR | left-to-right | Bitwise XOR`x ^ y` |
| 5: bitwise OR | left-to-right | Bitwise OR`x | y` |
| 4: logical AND | left-to-right | Logical AND`x && y` |
| 3: logical OR, nullish coalescing | left-to-right | Logical OR`x || y` |
| Nullish coalescing operator`x ?? y` | [9] |
| 2: assignment and miscellaneous | right-to-left | Assignment`x = y` | [10] |
| Addition assignment`x += y` |
| Subtraction assignment`x -= y` |
| Exponentiation assignment`x **= y` |
| Multiplication assignment`x *= y` |
| Division assignment`x /= y` |
| Remainder assignment`x %= y` |
| Left shift assignment`x <<= y` |
| Right shift assignment`x >>= y` |
| Unsigned right shift assignment`x >>>= y` |
| Bitwise AND assignment`x &= y` |
| Bitwise XOR assignment`x ^= y` |
| Bitwise OR assignment`x |= y` |
| Logical AND assignment`x &&= y` |
| Logical OR assignment`x ||= y` |
| Nullish coalescing assignment`x ??= y` |
| right-to-left | Conditional (ternary) operator`x ? y : z` | [11] |
| right-to-left | Arrow`x => y` | [12] |
| n/a | `yield x` |
| `yield* x` |
| Spread`...x` | [13] |
| 1: comma | left-to-right | Comma operator`x, y` |

Notes:

1. The operand can be any expression.
2. The "right-hand side" must be an identifier.
3. The "right-hand side" can be any expression.
4. The "right-hand side" is a comma-separated list of any expression with precedence > 1 (i.e. not comma expressions).
5. The operand must be a valid assignment target (identifier or property access). Its precedence means `new Foo++` is `(new Foo)++` (a syntax error) and not `new (Foo++)` (a TypeError: (Foo++) is not a constructor).
6. The operand must be a valid assignment target (identifier or property access).
7. The operand cannot be an identifier or a private property access.
8. The left-hand side cannot have precedence 14.
9. The operands cannot be a logical OR `||` or logical AND `&&` operator without grouping.
10. The "left-hand side" must be a valid assignment target (identifier or property access).
11. The associativity means the two expressions after `?` are implicitly grouped.
12. The "left-hand side" is a single identifier or a parenthesized parameter list.
13. Only valid inside object literals, array literals, or argument lists.


Remainder (%) - JavaScript

Remainder (%)
=============

The **remainder (`%`)** operator returns the remainder left over when one operand is divided by a second operand. It always takes the sign of the dividend.

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

For the operation `n % d`, `n` is called the dividend and `d` is called the divisor. The operation returns `NaN` if one of the operands is `NaN`, `n` is ±Infinity, or if `d` is ±0. Otherwise, if `d` is ±Infinity or if `n` is ±0, the dividend `n` is returned.

When both operands are non-zero and finite, the remainder `r` is calculated as `r := n - d * q` where `q` is the integer such that `r` has the same sign as the dividend `n` while being as close to 0 as possible.

Note that while in most languages, '%' is a remainder operator, in some (e.g. Python, Perl) it is a modulo operator. Modulo is defined as `k := n - d * q` where `q` is the integer such that `k` has the same sign as the divisor `d` while being as close to 0 as possible. For two values of the same sign, the two are equivalent, but when the operands are of different signs, the modulo result always has the same sign as the *divisor*, while the remainder has the same sign as the *dividend*, which can make them differ by one unit of `d`. To obtain a modulo in JavaScript, in place of `n % d`, use `((n % d) + d) % d`. In JavaScript, the modulo operation (which doesn't have a dedicated operator) is used to normalize the second operand of bitwise shift operators (`<<`, `>>`, etc.), making the offset always a positive value.

For BigInt division, a `RangeError` is thrown if the divisor `y` is `0n`. This is because number remainder by zero returns `NaN`, but BigInt has no concept of `NaN`.

Examples
--------

### Remainder with positive dividend

```js
13 % 5; // 3
1 % -2; // 1
1 % 2; // 1
2 % 3; // 2
5.5 % 2; // 1.5

3n % 2n; // 1n
```

### Remainder with negative dividend

```js
-13 % 5; // -3
-1 % 2; // -1
-4 % 2; // -0

-3n % 2n; // -1n
```

### Remainder with NaN

```js
NaN % 2; // NaN
```

### Remainder with Infinity

```js
Infinity % 2; // NaN
Infinity % 0; // NaN
Infinity % Infinity; // NaN
2 % Infinity; // 2
0 % Infinity; // 0
```

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

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

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

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

See also
--------

* Addition (`+`)
* Subtraction (`-`)
* Division (`/`)
* Multiplication (`*`)
* Exponentiation (`**`)
* Increment (`++`)
* Decrement (`--`)
* Unary negation (`-`)
* Unary plus (`+`)
* Remainder operator vs. modulo operator by Dr. Axel Rauschmayer (2019)


Right shift (>>) - JavaScript

Right shift (>>)
================

The **right shift (`>>`)** operator returns a number or BigInt whose binary representation is the first operand shifted by the specified number of bits to the right. Excess bits shifted off to the right are discarded, and copies of the leftmost bit are shifted in from the left. This operation is also called "sign-propagating right shift" or "arithmetic right shift", because the sign of the resulting number is the same as the sign of the first operand.

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 right shift if both operands become BigInts; otherwise, it converts both operands to 32-bit integers and performs number right shift. A `TypeError` is thrown if one operand becomes a BigInt but the other becomes a number.

Since the new leftmost bit has the same value as the previous leftmost bit, the sign bit (the leftmost bit) does not change. Hence the name "sign-propagating".

The operator operates on the left operand's bit representation in two's complement. Consider the 32-bit binary representations of the decimal (base 10) numbers `9` and `-9`:
```

     9 (base 10): 00000000000000000000000000001001 (base 2)
    -9 (base 10): 11111111111111111111111111110111 (base 2)
```

The binary representation under two's complement of the negative decimal (base 10) number `-9` is formed by inverting all the bits of its opposite number, which is `9` and `00000000000000000000000000001001` in binary, and adding `1`.

In both cases, the sign of the binary number is given by its leftmost bit: for the positive decimal number `9`, the leftmost bit of the binary representation is `0`, and for the negative decimal number `-9`, the leftmost bit of the binary representation is `1`.

Given those binary representations of the decimal (base 10) numbers `9`, and `-9`:

`9 >> 2` yields 2:
```

     9 (base 10): 00000000000000000000000000001001 (base 2)
                  --------------------------------
9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
```

Notice how two rightmost bits, `01`, have been shifted off, and two copies of the leftmost bit, `0` have been shifted in from the left.

`-9 >> 2` yields `-3`:
```

     -9 (base 10): 11111111111111111111111111110111 (base 2)
                   --------------------------------
-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
```

Notice how two rightmost bits, `11`, have been shifted off. But as far as the leftmost bits: in this case, the leftmost bit is `1`. So two copies of that leftmost `1` bit have been shifted in from the left — which preserves the negative sign.

The binary representation `11111111111111111111111111111101` is equal to the negative decimal (base 10) number `-3`, because all negative integers are stored as two's complements, and this one can be calculated by inverting all the bits of the binary representation of the positive decimal (base 10) number `3`, which is `00000000000000000000000000000011`, and then adding one.

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

Before: 11100110111110100000000000000110000000000001
After:              10100000000000000110000000000001
```

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

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

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

Examples
--------

### Using right shift

```js
9 >> 2; // 2
-9 >> 2; // -3

9n >> 2n; // 2n
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-signed-right-shift-operator |

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

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

See also
--------

* Bitwise operators in the JS guide
* Right shift assignment (`>>=`)
* Unsigned right shift (`>>>`)


instanceof - JavaScript

instanceof
==========

The **`instanceof`** operator tests to see if the `prototype` property of a constructor appears anywhere in the prototype chain of an object. The return value is a boolean value. Its behavior can be customized with `Symbol.hasInstance`.

Try it
------

Syntax
------

```js
object instanceof constructor
```

### Parameters

`object`

The object to test.

`constructor`

Constructor to test against.

### Exceptions

`TypeError`

Thrown if `constructor` is not an object. If `constructor` doesn't have a `@@hasInstance` method, it must also be a function.

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

The `instanceof` operator tests the presence of `constructor.prototype` in `object`'s prototype chain. This usually (though not always) means `object` was constructed with `constructor`.

```js
// defining constructors
function C() {}
function D() {}

const o = new C();

// true, because: Object.getPrototypeOf(o) === C.prototype
o instanceof C;

// false, because D.prototype is nowhere in o's prototype chain
o instanceof D;

o instanceof Object; // true, because:
C.prototype instanceof Object; // true

// Re-assign `constructor.prototype`: you should
// rarely do this in practice.
C.prototype = {};
const o2 = new C();

o2 instanceof C; // true

// false, because C.prototype is nowhere in
// o's prototype chain anymore
o instanceof C;

D.prototype = new C(); // add C to [[Prototype]] linkage of D
const o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true since C.prototype is now in o3's prototype chain
```

Note that the value of an `instanceof` test can change if `constructor.prototype` is re-assigned after creating the object (which is usually discouraged). It can also be changed by changing `object`'s prototype using `Object.setPrototypeOf`.

Classes behave in the same way, because classes also have the `prototype` property.

```js
class A {}
class B extends A {}

const o1 = new A();
// true, because Object.getPrototypeOf(o1) === A.prototype
o1 instanceof A;
// false, because B.prototype is nowhere in o1's prototype chain
o1 instanceof B;

const o2 = new B();
// true, because Object.getPrototypeOf(Object.getPrototypeOf(o2)) === A.prototype
o2 instanceof A;
// true, because Object.getPrototypeOf(o2) === B.prototype
o2 instanceof B;
```

For bound functions, `instanceof` looks up for the `prototype` property on the target function, since bound functions don't have `prototype`.

```js
class Base {}
const BoundBase = Base.bind(null, 1, 2);
console.log(new Base() instanceof BoundBase); // true
```

### instanceof and @@hasInstance

If `constructor` has a `Symbol.hasInstance` method, the method will be called in priority, with `object` as its only argument and `constructor` as `this`.

```js
// This class allows plain objects to be disguised as this class's instance,
// as long as the object has a particular flag as its property.
class Forgeable {
  static isInstanceFlag = Symbol("isInstanceFlag");

  static [Symbol.hasInstance](obj) {
    return Forgeable.isInstanceFlag in obj;
  }
}

const obj = { [Forgeable.isInstanceFlag]: true };
console.log(obj instanceof Forgeable); // true
```

Because all functions inherit from `Function.prototype` by default, most of the time, the `Function.prototype[@@hasInstance]` method specifies the behavior of `instanceof` when the right-hand side is a function. See the `Symbol.hasInstance` page for the exact algorithm of `instanceof`.

### instanceof and multiple realms

JavaScript execution environments (windows, frames, etc.) are each in their own *realm*. This means that they have different built-ins (different global object, different constructors, etc.). This may result in unexpected results. For instance, `[] instanceof window.frames[0].Array` will return `false`, because `Array.prototype !== window.frames[0].Array.prototype` and arrays in the current realm inherit from the former.

This may not make sense at first, but for scripts dealing with multiple frames or windows, and passing objects from one context to another via functions, this will be a valid and strong issue. For instance, you can securely check if a given object is in fact an Array using `Array.isArray()`, neglecting which realm it comes from.

For example, to check if a `Node` is an `SVGElement` in a different context, you can use `myNode instanceof myNode.ownerDocument.defaultView.SVGElement`.

Examples
--------

### Using instanceof with String

The following example shows the behavior of `instanceof` with `String` objects.

```js
const literalString = "This is a literal string";
const stringObject = new String("String created with constructor");

literalString instanceof String; // false, string primitive is not a String
stringObject instanceof String; // true

literalString instanceof Object; // false, string primitive is not an Object
stringObject instanceof Object; // true

stringObject instanceof Date; // false
```

### Using instanceof with Date

The following example shows the behavior of `instanceof` with `Date` objects.

```js
const myDate = new Date();

myDate instanceof Date; // true
myDate instanceof Object; // true
myDate instanceof String; // false
```

### Objects created using Object.create()

The following example shows the behavior of `instanceof` with objects created using `Object.create()`.

```js
function Shape() {}

function Rectangle() {
  Shape.call(this); // call super constructor.
}

Rectangle.prototype = Object.create(Shape.prototype);

Rectangle.prototype.constructor = Rectangle;

const rect = new Rectangle();

rect instanceof Object; // true
rect instanceof Shape; // true
rect instanceof Rectangle; // true
rect instanceof String; // false

const literalObject = {};
const nullObject = Object.create(null);
nullObject.name = "My object";

literalObject instanceof Object; // true, every object literal has Object.prototype as prototype
({}) instanceof Object; // true, same case as above
nullObject instanceof Object; // false, prototype is end of prototype chain (null)
```

### Demonstrating that mycar is of type Car and type Object

The following code creates an object type `Car` and an instance of that object type, `mycar`. The `instanceof` operator demonstrates that the `mycar` object is of type `Car` and of type `Object`.

```js
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const mycar = new Car("Honda", "Accord", 1998);
const a = mycar instanceof Car; // returns true
const b = mycar instanceof Object; // returns true
```

### Not an instanceof

To test if an object is not an `instanceof` a specific constructor, you can do:

```js
if (!(mycar instanceof Car)) {
  // Do something, like:
  // mycar = new Car(mycar)
}
```

This is really different from:

```js
if (!mycar instanceof Car) {
  // unreachable code
}
```

This will always be `false`. (`!mycar` will be evaluated before `instanceof`, so you always try to know if a boolean is an instance of `Car`).

### Overriding the behavior of instanceof

A common pitfall of using `instanceof` is believing that, if `x instanceof C`, then `x` was created using `C` as constructor. This is not true, because `x` could be directly assigned with `C.prototype` as its prototype. In this case, if your code reads private fields of `C` from `x`, it would still fail:

```js
class C {
  #value = "foo";
  static getValue(x) {
    return x.#value;
  }
}

const x = { \_\_proto\_\_: C.prototype };

if (x instanceof C) {
  console.log(C.getValue(x)); // TypeError: Cannot read private member #value from an object whose class did not declare it
}
```

To avoid this, you can override the behavior of `instanceof` by adding a `Symbol.hasInstance` method to `C`, so that it does a branded check with `in`:

```js
class C {
  #value = "foo";

  static [Symbol.hasInstance](x) {
    return #value in x;
  }

  static getValue(x) {
    return x.#value;
  }
}

const x = { \_\_proto\_\_: C.prototype };

if (x instanceof C) {
  // Doesn't run, because x is not a C
  console.log(C.getValue(x));
}
```

Note that you may want to limit this behavior to the current class; otherwise, it could lead to false positives for subclasses:

```js
class D extends C {}
console.log(new C() instanceof D); // true; because D inherits @@hasInstance from C
```

You could do this by checking that `this` is the current constructor:

```js
class C {
  #value = "foo";

  static [Symbol.hasInstance](x) {
    return this === C && #value in x;
  }
}

class D extends C {}
console.log(new C() instanceof D); // false
console.log(new C() instanceof C); // true
console.log({ \_\_proto\_\_: C.prototype } instanceof C); // 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
--------

* `typeof`
* `Symbol.hasInstance`
* `Object.prototype.isPrototypeOf`


Right shift assignment (>>=) - JavaScript

Right shift assignment (>>=)
============================

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

```js
let a = 5; // (00000000000000000000000000000101)
a >>= 2; // 1 (00000000000000000000000000000001)

let b = -5; // (-00000000000000000000000000000101)
b >>= 2; // -2 (-00000000000000000000000000000010)

let c = 5n;
c >>= 2n; // 1n
```

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

| Specification |
| --- |
| ECMAScript 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
* Right shift (`>>`)


Grouping operator ( ) - JavaScript

Grouping operator ( )
=====================

The **grouping `( )`** operator controls the precedence of evaluation in expressions. It also acts as a container for arbitrary expressions in certain syntactic constructs, where ambiguity or syntax errors would otherwise occur.

Try it
------

Syntax
------

```js
(expression)
```

### Parameters

`expression`

Any expression to be evaluated, including comma-joined expressions.

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

The grouping operator consists of a pair of parentheses around an expression that groups the contents. The operator overrides the normal operator precedence, so that operators with lower precedence (as low as the comma operator) can be evaluated before an operator with higher precedence.

Examples
--------

### Using the grouping operator

Evaluating addition and subtraction before multiplication and division.

```js
const a = 1;
const b = 2;
const c = 3;

// default precedence
a + b \* c; // 7
// evaluated by default like this
a + (b \* c); // 7

// now overriding precedence
// addition before multiplication
(a + b) \* c; // 9

// which is equivalent to
a \* c + b \* c; // 9
```

Notice in these examples that the order in which the *operators* evaluate has changed, but the order in which the *operands* evaluate has not. For example, in this code, the function invocations `a()`, `b()`, and `c()` are evaluated left-to-right (the normal order of evaluation) before the operator order is considered.

```js
a() \* (b() + c());
```

The function `a` will be called before the function `b`, which will be called before the function `c`. For more on operator precedence, see its reference page.

### Using the grouping operator to eliminate parsing ambiguity

An expression statement cannot start with the keyword `function`, because the parser would see it as the start of a function declaration. This means the following IIFE syntax is invalid:

```js
function () {
  // code
}();
```

The grouping operator can be used to eliminate this ambiguity, since when the parser sees the left parenthesis, it knows that what follows must be an expression instead of a declaration.

```js
(function () {
  // code
})();
```

You may also use the `void` operator to eliminate ambiguity.

In an arrow function expression body (one that directly returns an expression without the keyword `return`), the grouping operator can be used to return an object literal expression, because otherwise the left curly brace would be interpreted as the start of the function body.

```js
const f = () => ({ a: 1 });
```

If a property is accessed on a number literal, the property accessor dot `.` may be ambiguous with a decimal point, unless the number already has a decimal point. You can wrap integer literals in parentheses to eliminate this ambiguity.

```js
(1).toString(); // "1"
```

### Grouping operator and automatic semicolon insertion

The grouping operator can mitigate automatic semicolon insertion (ASI) pitfalls. For example, the `return` keyword and the returned expression cannot have a line break in between:

```js
function sum(a, b) {
  return
    a + b;
}
```

This code will return `undefined`, because a semicolon is inserted directly after the `return` keyword, which causes the function to return immediately without evaluating `a + b`. In case the returned expression is long and you want to keep it well-formatted, you may use the grouping operator to signify that the `return` keyword is followed by an expression and prevent semicolon insertion:

```js
function sum(a, b) {
  return (
    a + b
  );
}
```

However, grouping may also *introduce* ASI hazards. When a line starts with a left parenthesis and the previous line ends with an expression, the parser will not insert a semicolon before the line break, because it could be the middle of a function call. For example:

```js
const a = 1
(1).toString()
```

This code would be parsed as:

```js
const a = 1(1).toString();
```

Which throws "TypeError: 1 is not a function". If your coding style does not use semicolons, remember that when a line starts with a left parenthesis, *prefix* it with a semicolon. This practice is recommended by several formatters and/or style guides, including Prettier and standard.

```js
const a = 1
;(1).toString()
```

For more advice on working with ASI, see its reference section.

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

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

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

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

See also
--------

* Operator precedence
* `delete`
* `typeof`


Logical OR (

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

 The **logical OR (`||`)** (logical disjunction) operator for a set of operands
 is true if and only if one or more of its operands is true. It is typically used with
 boolean (logical) values. When it is, it returns a Boolean value. However,
 the `||` operator actually returns the value of one of the specified
 operands, so if this operator is used with non-Boolean values, it will return a
 non-Boolean value.

Try it
------

Syntax
------

```js
x || y
```

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

 If `x` can be converted to `true`, returns
 `x`; else, returns `y`.

 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.

### Short-circuit evaluation

 The logical OR expression is evaluated left to right, it is tested for possible
 "short-circuit" evaluation using the following rule:

`(some truthy expression) || expr` is short-circuit evaluated to
 the truthy expression.

 Short circuit means that the `expr` part above is **not
evaluated**, hence any side effects of doing so do not take effect (e.g., if
 `expr` is a function call, the calling never takes place). This
 happens because the value of the operator is already determined after the evaluation of
 the first operand. See example:

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

console.log(B() || A());
// Logs "called B" due to the function call,
// then logs true (which is the resulting value of the operator)
```

### Operator precedence

 The following expressions might seem equivalent, but they are not, because the
 `&&` operator is executed before the `||` operator
 (see operator precedence).

```js
true || false && false; // returns true, because && is executed first
(true || false) && false; // returns false, because grouping has the highest precedence
```

Examples
--------

### Using OR

The following code shows examples of the `||` (logical OR) operator.

```js
true || true; // t || t returns true
false || true; // f || t returns true
true || false; // t || f returns true
false || 3 === 4; // f || f returns false
"Cat" || "Dog"; // t || t returns "Cat"
false || "Cat"; // f || t returns "Cat"
"Cat" || false; // t || f returns "Cat"
"" || false; // f || f returns false
false || ""; // f || f returns ""
false || varObject; // f || object returns varObject
```

**Note:** If you use this operator to provide a default value to some
 variable, be aware that any *falsy* value will not be used. If you only need to
 filter out `null` or `undefined`, consider using
 the nullish coalescing operator.

### 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 following some rules.

The following composite operation involving **booleans**:

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

is always equal to:

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

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-LogicalORExpression |

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

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

See also
--------

* Nullish coalescing operator (`??`)
* `Boolean`
* Truthy
* Falsy


Nullish coalescing assignment (??=) - JavaScript

Nullish coalescing assignment (??=)
===================================

The **nullish coalescing assignment (`??=`)** operator, also known as the **logical nullish assignment** operator, only evaluates the right operand and assigns to the left if the left operand is nullish (`null` or `undefined`).

Try it
------

Syntax
------

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

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

Nullish coalescing 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 nullish, due to short-circuiting of the nullish coalescing 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 nullish, `y` is not evaluated at all.

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

Examples
--------

### Using nullish coalescing assignment

You can use the nullish coalescing assignment operator to apply default values to object properties. Compared to using destructuring and default values, `??=` also applies the default value if the property has value `null`.

```js
function config(options) {
  options.duration ??= 100;
  options.speed ??= 25;
  return options;
}

config({ duration: 125 }); // { duration: 125, speed: 25 }
config({}); // { duration: 100, speed: 25 }
```

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

* Nullish coalescing operator (`??`)
* Nullish
* Truthy
* Falsy


Destructuring assignment - JavaScript

Destructuring assignment
========================

The **destructuring assignment** syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

Try it
------

Syntax
------

```js
const [a, b] = array;
const [a, , b] = array;
const [a = aDefault, b] = array;
const [a, b, ...rest] = array;
const [a, , b, ...rest] = array;
const [a, b, ...{ pop, push }] = array;
const [a, b, ...[c, d]] = array;

const { a, b } = obj;
const { a: a1, b: b1 } = obj;
const { a: a1 = aDefault, b = bDefault } = obj;
const { a, b, ...rest } = obj;
const { a: a1, b: b1, ...rest } = obj;
const { [key]: a } = obj;

let a, b, a1, b1, c, d, rest, pop, push;
[a, b] = array;
[a, , b] = array;
[a = aDefault, b] = array;
[a, b, ...rest] = array;
[a, , b, ...rest] = array;
[a, b, ...{ pop, push }] = array;
[a, b, ...[c, d]] = array;

({ a, b } = obj); // parentheses are required
({ a: a1, b: b1 } = obj);
({ a: a1 = aDefault, b = bDefault } = obj);
({ a, b, ...rest } = obj);
({ a: a1, b: b1, ...rest } = obj);
```

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

The object and array literal expressions provide an easy way to create *ad hoc* packages of data.

```js
const x = [1, 2, 3, 4, 5];
```

The destructuring assignment uses similar syntax but uses it on the left-hand side of the assignment instead. It defines which values to unpack from the sourced variable.

```js
const x = [1, 2, 3, 4, 5];
const [y, z] = x;
console.log(y); // 1
console.log(z); // 2
```

Similarly, you can destructure objects on the left-hand side of the assignment.

```js
const obj = { a: 1, b: 2 };
const { a, b } = obj;
// is equivalent to:
// const a = obj.a;
// const b = obj.b;
```

This capability is similar to features present in languages such as Perl and Python.

For features specific to array or object destructuring, refer to the individual examples below.

### Binding and assignment

For both object and array destructuring, there are two kinds of destructuring patterns: *binding pattern* and *assignment pattern*, with slightly different syntaxes.

In binding patterns, the pattern starts with a declaration keyword (`var`, `let`, or `const`). Then, each individual property must either be bound to a variable or further destructured.

```js
const obj = { a: 1, b: { c: 2 } };
const {
  a,
  b: { c: d },
} = obj;
// Two variables are bound: `a` and `d`
```

All variables share the same declaration, so if you want some variables to be re-assignable but others to be read-only, you may have to destructure twice — once with `let`, once with `const`.

```js
const obj = { a: 1, b: { c: 2 } };
const { a } = obj; // a is constant
let {
  b: { c: d },
} = obj; // d is re-assignable
```

In many other syntaxes where the language binds a variable for you, you can use a binding destructuring pattern. These include:

* The looping variable of `for...in` `for...of`, and `for await...of` loops;
* Function parameters;
* The `catch` binding variable.

In assignment patterns, the pattern does not start with a keyword. Each destructured property is assigned to a target of assignment — which may either be declared beforehand with `var` or `let`, or is a property of another object — in general, anything that can appear on the left-hand side of an assignment expression.

```js
const numbers = [];
const obj = { a: 1, b: 2 };
({ a: numbers[0], b: numbers[1] } = obj);
// The properties `a` and `b` are assigned to properties of `numbers`
```

**Note:** The parentheses `( ... )` around the assignment statement are required when using object literal destructuring assignment without a declaration.

`{ a, b } = { a: 1, b: 2 }` is not valid stand-alone syntax, as the `{ a, b }` on the left-hand side is considered a block and not an object literal according to the rules of expression statements. However, `({ a, b } = { a: 1, b: 2 })` is valid, as is `const { a, b } = { a: 1, b: 2 }`.

If your coding style does not include trailing semicolons, the `( ... )` expression needs to be preceded by a semicolon, or it may be used to execute a function on the previous line.

Note that the equivalent *binding pattern* of the code above is not valid syntax:

```js
const numbers = [];
const obj = { a: 1, b: 2 };
const { a: numbers[0], b: numbers[1] } = obj;

// This is equivalent to:
// const numbers[0] = obj.a;
// const numbers[1] = obj.b;
// Which definitely is not valid.
```

You can only use assignment patterns as the left-hand side of the assignment operator. You cannot use them with compound assignment operators such as `+=` or `*=`.

### Default value

Each destructured property can have a *default value*. The default value is used when the property is not present, or has value `undefined`. It is not used if the property has value `null`.

```js
const [a = 1] = []; // a is 1
const { b = 2 } = { b: undefined }; // b is 2
const { c = 2 } = { c: null }; // c is null
```

The default value can be any expression. It will only be evaluated when necessary.

```js
const { b = console.log("hey") } = { b: 2 };
// Does not log anything, because `b` is defined and there's no need
// to evaluate the default value.
```

### Rest property

You can end a destructuring pattern with a rest property `...rest`. This pattern will store all remaining properties of the object or array into a new object or array.

```js
const { a, ...others } = { a: 1, b: 2, c: 3 };
console.log(others); // { b: 2, c: 3 }

const [first, ...others2] = [1, 2, 3];
console.log(others2); // [2, 3]
```

The rest property must be the last in the pattern, and must not have a trailing comma.

```js
const [a, ...b,] = [1, 2, 3];

// SyntaxError: rest element may not have a trailing comma
// Always consider using rest operator as the last element
```

Examples
--------

### Array destructuring

#### Basic variable assignment

```js
const foo = ["one", "two", "three"];

const [red, yellow, green] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // "three"
```

#### Destructuring with more elements than the source

In an array destructuring from an array of length *N* specified on the right-hand side of the assignment, if the number of variables specified on the left-hand side of the assignment is greater than *N*, only the first *N* variables are assigned values. The values of the remaining variables will be undefined.

```js
const foo = ["one", "two"];

const [red, yellow, green, blue] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // undefined
console.log(blue); // undefined
```

#### Swapping variables

Two variables values can be swapped in one destructuring expression.

Without destructuring assignment, swapping two values requires a temporary variable (or, in some low-level languages, the XOR-swap trick).

```js
let a = 1;
let b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

const arr = [1, 2, 3];
[arr[2], arr[1]] = [arr[1], arr[2]];
console.log(arr); // [1, 3, 2]
```

#### Parsing an array returned from a function

It's always been possible to return an array from a function. Destructuring can make working with an array return value more concise.

In this example, `f()` returns the values `[1, 2]` as its output, which can be parsed in a single line with destructuring.

```js
function f() {
  return [1, 2];
}

const [a, b] = f();
console.log(a); // 1
console.log(b); // 2
```

#### Ignoring some returned values

You can ignore return values that you're not interested in:

```js
function f() {
  return [1, 2, 3];
}

const [a, , b] = f();
console.log(a); // 1
console.log(b); // 3

const [c] = f();
console.log(c); // 1
```

You can also ignore all returned values:

```js
[, ,] = f();
```

#### Using a binding pattern as the rest property

The rest property of array destructuring assignment can be another array or object binding pattern. The inner destructuring destructures from the array created after collecting the rest elements, so you cannot access any properties present on the original iterable in this way.

```js
const [a, b, ...{ length }] = [1, 2, 3];
console.log(a, b, length); // 1 2 1
```

```js
const [a, b, ...[c, d]] = [1, 2, 3, 4];
console.log(a, b, c, d); // 1 2 3 4
```

These binding patterns can even be nested, as long as each rest property is the last in the list.

```js
const [a, b, ...[c, d, ...[e, f]]] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c, d, e, f); // 1 2 3 4 5 6
```

On the other hand, object destructuring can only have an identifier as the rest property.

```js
const { a, ...{ b } } = { a: 1, b: 2 };
// SyntaxError: `...` must be followed by an identifier in declaration contexts

let a, b;
({ a, ...{ b } } = { a: 1, b: 2 });
// SyntaxError: `...` must be followed by an assignable reference in assignment contexts
```

#### Unpacking values from a regular expression match

When the regular expression `exec()` method finds a match, it returns an array containing first the entire matched portion of the string and then the portions of the string that matched each parenthesized group in the regular expression. Destructuring assignment allows you to unpack the parts out of this array easily, ignoring the full match if it is not needed.

```js
function parseProtocol(url) {
  const parsedURL = /^(\w+):\/\/([^/]+)\/(.\*)$/.exec(url);
  if (!parsedURL) {
    return false;
  }
  console.log(parsedURL);
  // ["https://developer.mozilla.org/en-US/docs/Web/JavaScript",
  // "https", "developer.mozilla.org", "en-US/docs/Web/JavaScript"]

  const [, protocol, fullhost, fullpath] = parsedURL;
  return protocol;
}

console.log(
  parseProtocol("https://developer.mozilla.org/en-US/docs/Web/JavaScript"),
);
// "https"
```

#### Using array destructuring on any iterable

Array destructuring calls the iterable protocol of the right-hand side. Therefore, any iterable, not necessarily arrays, can be destructured.

```js
const [a, b] = new Map([
  [1, 2],
  [3, 4],
]);
console.log(a, b); // [1, 2] [3, 4]
```

Non-iterables cannot be destructured as arrays.

```js
const obj = { 0: "a", 1: "b", length: 2 };
const [a, b] = obj;
// TypeError: obj is not iterable
```

Iterables are only iterated until all bindings are assigned.

```js
const obj = {
  \*[Symbol.iterator]() {
    for (const v of [0, 1, 2, 3]) {
      console.log(v);
      yield v;
    }
  },
};
const [a, b] = obj; // Only logs 0 and 1
```

The rest binding is eagerly evaluated and creates a new array, instead of using the old iterable.

```js
const obj = {
  \*[Symbol.iterator]() {
    for (const v of [0, 1, 2, 3]) {
      console.log(v);
      yield v;
    }
  },
};
const [a, b, ...rest] = obj; // Logs 0 1 2 3
console.log(rest); // [2, 3] (an array)
```

### Object destructuring

#### Basic assignment

```js
const user = {
  id: 42,
  isVerified: true,
};

const { id, isVerified } = user;

console.log(id); // 42
console.log(isVerified); // true
```

#### Assigning to new variable names

A property can be unpacked from an object and assigned to a variable with a different name than the object property.

```js
const o = { p: 42, q: true };
const { p: foo, q: bar } = o;

console.log(foo); // 42
console.log(bar); // true
```

Here, for example, `const { p: foo } = o` takes from the object `o` the property named `p` and assigns it to a local variable named `foo`.

#### Assigning to new variable names and providing default values

A property can be both

* Unpacked from an object and assigned to a variable with a different name.
* Assigned a default value in case the unpacked value is `undefined`.

```js
const { a: aa = 10, b: bb = 5 } = { a: 3 };

console.log(aa); // 3
console.log(bb); // 5
```

#### Unpacking properties from objects passed as a function parameter

 Objects passed into function parameters can also be unpacked into variables, which may then be accessed within the function body.
 As for object assignment, the destructuring syntax allows for the new variable to have the same name or a different name than the original property, and to assign default values for the case when the original object does not define the property.

Consider this object, which contains information about a user.

```js
const user = {
  id: 42,
  displayName: "jdoe",
  fullName: {
    firstName: "Jane",
    lastName: "Doe",
  },
};
```

 Here we show how to unpack a property of the passed object into a variable with the same name.
 The parameter value `{ id }` indicates that the `id` property of the object passed to the function should be unpacked into a variable with the same name, which can then be used within the function.

```js
function userId({ id }) {
  return id;
}

console.log(userId(user)); // 42
```

 You can define the name of the unpacked variable.
 Here we unpack the property named `displayName`, and rename it to `dname` for use within the function body.

```js
function userDisplayName({ displayName: dname }) {
  return dname;
}

console.log(userDisplayName(user)); // "jdoe"
```

 Nested objects can also be unpacked.
 The example below shows the property `fullname.firstName` being unpacked into a variable called `name`.

```js
function whois({ displayName, fullName: { firstName: name } }) {
  return `${displayName} is ${name}`;
}

console.log(whois(user)); // "jdoe is Jane"
```

#### Setting a function parameter's default value

Default values can be specified using `=`, and will be used as variable values if a specified property does not exist in the passed object.

Below we show a function where the default size is `'big'`, default co-ordinates are `x: 0, y: 0` and default radius is 25.

```js
function drawChart({
  size = "big",
  coords = { x: 0, y: 0 },
  radius = 25,
} = {}) {
  console.log(size, coords, radius);
  // do some chart drawing
}

drawChart({
  coords: { x: 18, y: 30 },
  radius: 30,
});
```

In the function signature for `drawChart` above, the destructured left-hand side has a default value of an empty object `= {}`.

You could have also written the function without that default. However, if you leave out that default value, the function will look for at least one argument to be supplied when invoked, whereas in its current form, you can call `drawChart()` without supplying any parameters. Otherwise, you need to at least supply an empty object literal.

For more information, see Default parameters > Destructured parameter with default value assignment.

#### Nested object and array destructuring

```js
const metadata = {
  title: "Scratchpad",
  translations: [
    {
      locale: "de",
      localizationTags: [],
      lastEdit: "2014-04-14T08:43:37",
      url: "/de/docs/Tools/Scratchpad",
      title: "JavaScript-Umgebung",
    },
  ],
  url: "/en-US/docs/Tools/Scratchpad",
};

const {
  title: englishTitle, // rename
  translations: [
    {
      title: localeTitle, // rename
    },
  ],
} = metadata;

console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"
```

#### For of iteration and destructuring

```js
const people = [
  {
    name: "Mike Smith",
    family: {
      mother: "Jane Smith",
      father: "Harry Smith",
      sister: "Samantha Smith",
    },
    age: 35,
  },
  {
    name: "Tom Jones",
    family: {
      mother: "Norah Jones",
      father: "Richard Jones",
      brother: "Howard Jones",
    },
    age: 25,
  },
];

for (const {
  name: n,
  family: { father: f },
} of people) {
  console.log(`Name: ${n}, Father: ${f}`);
}

// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"
```

#### Computed object property names and destructuring

Computed property names, like on object literals, can be used with destructuring.

```js
const key = "z";
const { [key]: foo } = { z: "bar" };

console.log(foo); // "bar"
```

#### Invalid JavaScript identifier as a property name

Destructuring can be used with property names that are not valid JavaScript identifiers by providing an alternative identifier that is valid.

```js
const foo = { "fizz-buzz": true };
const { "fizz-buzz": fizzBuzz } = foo;

console.log(fizzBuzz); // true
```

### Destructuring primitive values

Object destructuring is almost equivalent to property accessing. This means if you try to destruct a primitive value, the value will get wrapped into the corresponding wrapper object and the property is accessed on the wrapper object.

```js
const { a, toFixed } = 1;
console.log(a, toFixed); // undefined ƒ toFixed() { [native code] }
```

Same as accessing properties, destructuring `null` or `undefined` throws a `TypeError`.

```js
const { a } = undefined; // TypeError: Cannot destructure property 'a' of 'undefined' as it is undefined.
const { b } = null; // TypeError: Cannot destructure property 'b' of 'null' as it is null.
```

This happens even when the pattern is empty.

```js
const {} = null; // TypeError: Cannot destructure 'null' as it is null.
```

#### Combined array and object destructuring

Array and object destructuring can be combined. Say you want the third element in the array `props` below, and then you want the `name` property in the object, you can do the following:

```js
const props = [
  { id: 1, name: "Fizz" },
  { id: 2, name: "Buzz" },
  { id: 3, name: "FizzBuzz" },
];

const [, , { name }] = props;

console.log(name); // "FizzBuzz"
```

#### The prototype chain is looked up when the object is deconstructed

When deconstructing an object, if a property is not accessed in itself, it will continue to look up along the prototype chain.

```js
const obj = {
  self: "123",
  \_\_proto\_\_: {
    prot: "456",
  },
};
const { self, prot } = obj;

console.log(self); // "123"
console.log(prot); // "456"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-destructuring-assignment |
| ECMAScript Language Specification # sec-destructuring-binding-patterns |

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

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

See also
--------

* Assignment operators
* ES6 in Depth: Destructuring on hacks.mozilla.org (2015)


Exponentiation (**) - JavaScript

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

The **exponentiation (`**`)** operator returns the result of raising the first operand to the power of the second operand. It is equivalent to `Math.pow()`, except it also accepts BigInts as operands.

Try it
------

Syntax
------

```js
x \*\* y
```

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

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

For both numbers and BigInts, `0` raised to a positive power returns `0`, and `0` raised to a power of `0` returns `1`. For numbers, `0` raised to a negative number returns `Infinity`, while `-0` raised to a negative number returns `-Infinity`.

`NaN ** 0` (and the equivalent `Math.pow(NaN, 0)`) is the only case where `NaN` doesn't propagate through mathematical operations — it returns `1` despite the operand being `NaN`. In addition, the behavior where `base` is 1 and `exponent` is non-finite (±Infinity or `NaN`) is different from IEEE 754, which specifies that the result should be 1, whereas JavaScript returns `NaN` to preserve backward compatibility with its original behavior.

For BigInt exponentiation, a `RangeError` is thrown if the exponent `y` is negative. This is because any negative exponent would likely result in a value between 0 and 1 (unless the base is `1`, `-1`, or `0`), which is rounded to zero, and is likely a developer mistake.

The exponentiation operator is right-associative: `a ** b ** c` is equal to `a ** (b ** c)`.

In most languages, such as PHP, Python, and others that have an exponentiation operator (`**`), the exponentiation operator is defined to have a higher precedence than unary operators, such as unary `+` and unary `-`, but there are a few exceptions. For example, in Bash, the `**` operator is defined to have a lower precedence than unary operators.

In JavaScript, it is impossible to write an ambiguous exponentiation expression. That is, you cannot put a unary operator (with precedence 14, including `+`/`-`/`~`/`!`/`++`/`--`/`delete`/`void`/`typeof`/`await`) immediately before the base number; doing so will cause a SyntaxError.

For example, `-2 ** 2` is 4 in Bash, but is -4 in other languages (such as Python). This is invalid in JavaScript, as the operation is ambiguous. You have to parenthesize either side — for example, as `-(2 ** 2)` — to make the intention unambiguous.

Note that some programming languages use the caret symbol `^` for exponentiation, but JavaScript uses that symbol for the bitwise XOR operator.

Examples
--------

### Basic exponentiation

```js
2 \*\* 3; // 8
3 \*\* 2; // 9
3 \*\* 2.5; // 15.588457268119896
10 \*\* -1; // 0.1
2 \*\* 1024; // Infinity
NaN \*\* 2; // NaN
NaN \*\* 0; // 1
1 \*\* Infinity; // NaN

2n \*\* 3n; // 8n
2n \*\* 1024n; // A very large number, but not Infinity

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

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

### Associativity

```js
2 \*\* 3 \*\* 2; // 512
2 \*\* (3 \*\* 2); // 512
(2 \*\* 3) \*\* 2; // 64
```

### Usage with unary operators

To invert the sign of the result of an exponentiation expression:

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

To force the base of an exponentiation expression to be a negative number:

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

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

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


Bitwise XOR assignment (^=) - JavaScript

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

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

```js
let a = 5; // (00000000000000000000000000000101)
a ^= 3; // (00000000000000000000000000000011)

console.log(a); // 6 (00000000000000000000000000000110)

let b = 5; // (00000000000000000000000000000101)
b ^= 0; // (00000000000000000000000000000000)

console.log(b); // 5 (00000000000000000000000000000101)

let c = 5n;
c ^= 3n;
console.log(c); // 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
* Bitwise XOR (`^`)


Object initializer - JavaScript

Object initializer
==================

An **object initializer** is a comma-delimited list of zero or more pairs of property names and associated values of an object, enclosed in curly braces (`{}`). Objects can also be initialized using `Object.create()` or by invoking a constructor function with the `new` operator.

Try it
------

Syntax
------

```js
o = {
  a: "foo",
  b: 42,
  c: {},
  1: "number literal property",
  "foo:bar": "string literal property",

  shorthandProperty,

  method(parameters) {
    // …
  },

  get property() {},
  set property(value) {},

  [expression]: "computed property",

  \_\_proto\_\_: prototype,

  ...spreadProperty,
};
```

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

An object initializer is an expression that describes the initialization of an `Object`. Objects consist of *properties*, which are used to describe an object. The values of object properties can either contain primitive data types or other objects.

### Object literal syntax vs. JSON

The object literal syntax is not the same as the **J**ava**S**cript **O**bject **N**otation (JSON). Although they look similar, there are differences between them:

* JSON *only* permits property definition using the `"property": value` syntax. The property name must be double-quoted, and the definition cannot be a shorthand. Computed property names are not allowed either.
* JSON object property values can only be strings, numbers, `true`, `false`, `null`, arrays, or another JSON object. This means JSON cannot express methods or non-plain objects like `Date` or `RegExp`.
* In JSON, `"__proto__"` is a normal property key. In an object literal, it sets the object's prototype.

JSON is a *strict subset* of the object literal syntax, meaning that every valid JSON text can be parsed as an object literal, and would likely not cause syntax errors. The only exception is that the object literal syntax prohibits duplicate `__proto__` keys, which does not apply to `JSON.parse()`. The latter treats `__proto__` like a normal property and takes the last occurrence as the property's value. The only time when the object value they represent (a.k.a. their semantic) differ is also when the source contains the `__proto__` key — for object literals, it sets the object's prototype; for JSON, it's a normal property.

```js
console.log(JSON.parse('{ "\_\_proto\_\_": 0, "\_\_proto\_\_": 1 }')); // {\_\_proto\_\_: 1}
console.log({ "\_\_proto\_\_": 0, "\_\_proto\_\_": 1 }); // SyntaxError: Duplicate \_\_proto\_\_ fields are not allowed in object literals

console.log(JSON.parse('{ "\_\_proto\_\_": {} }')); // { \_\_proto\_\_: {} }
console.log({ "\_\_proto\_\_": {} }); // {} (with {} as prototype)
```

Examples
--------

### Creating objects

An empty object with no properties can be created like this:

```js
const object = {};
```

However, the advantage of the *literal* or *initializer* notation is, that you are able to quickly create objects with properties inside the curly braces. You notate a list of `key: value` pairs delimited by commas.

The following code creates an object with three properties and the keys are `"foo"`, `"age"` and `"baz"`. The values of these keys are a string `"bar"`, the number `42`, and another object.

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

### Accessing properties

Once you have created an object, you might want to read or change them. Object properties can be accessed by using the dot notation or the bracket notation. (See property accessors for detailed information.)

```js
object.foo; // "bar"
object["age"]; // 42
object.baz; // {myProp: 12}
object.baz.myProp; //12
```

### Property definitions

We have already learned how to notate properties using the initializer syntax. Oftentimes, there are variables in your code that you would like to put into an object. You will see code like this:

```js
const a = "foo";
const b = 42;
const c = {};

const o = {
  a: a,
  b: b,
  c: c,
};
```

There is a shorter notation available to achieve the same:

```js
const a = "foo";
const b = 42;
const c = {};

// Shorthand property names
const o = { a, b, c };

// In other words,
console.log(o.a === { a }.a); // true
```

#### Duplicate property names

When using the same name for your properties, the second property will overwrite the first.

```js
const a = { x: 1, x: 2 };
console.log(a); // {x: 2}
```

After ES2015, duplicate property names are allowed everywhere, including strict mode. You can also have duplicate property names in classes. The only exception is private properties, which must be unique in the class body.

### Method definitions

A property of an object can also refer to a function or a getter or setter method.

```js
const o = {
  property: function (parameters) {},
  get property() {},
  set property(value) {},
};
```

A shorthand notation is available, so that the keyword `function` is no longer necessary.

```js
// Shorthand method names
const o = {
  property(parameters) {},
};
```

There is also a way to concisely define generator methods.

```js
const o = {
  \*generator() {
    // …
  },
};
```

Which is equivalent to this ES5-like notation (but note that ECMAScript 5 has no generators):

```js
const o = {
  generator: function\* () {
    // …
  },
};
```

For more information and examples about methods, see method definitions.

### Computed property names

The object initializer syntax also supports computed property names. That allows you to put an expression in square brackets `[]`, that will be computed and used as the property name. This is reminiscent of the bracket notation of the property accessor syntax, which you may have used to read and set properties already.

Now you can use a similar syntax in object literals, too:

```js
// Computed property names
let i = 0;
const a = {
  [`foo${++i}`]: i,
  [`foo${++i}`]: i,
  [`foo${++i}`]: i,
};

console.log(a.foo1); // 1
console.log(a.foo2); // 2
console.log(a.foo3); // 3

const items = ["A", "B", "C"];
const obj = {
  [items]: "Hello",
};
console.log(obj); // A,B,C: "Hello"
console.log(obj["A,B,C"]); // "Hello"

const param = "size";
const config = {
  [param]: 12,
  [`mobile${param.charAt(0).toUpperCase()}${param.slice(1)}`]: 4,
};

console.log(config); // {size: 12, mobileSize: 4}
```

### Spread properties

Object literals support the spread syntax. It copies own enumerable properties from a provided object onto a new object.

Shallow-cloning (excluding `prototype`) or merging objects is now possible using a shorter syntax than `Object.assign()`.

```js
const obj1 = { foo: "bar", x: 42 };
const obj2 = { foo: "baz", y: 13 };

const clonedObj = { ...obj1 };
// { foo: "bar", x: 42 }

const mergedObj = { ...obj1, ...obj2 };
// { foo: "baz", x: 42, y: 13 }
```

**Warning:** Note that `Object.assign()` triggers setters, whereas the spread syntax doesn't!

### Prototype setter

A property definition of the form `__proto__: value` or `"__proto__": value` does not create a property with the name `__proto__`. Instead, if the provided value is an object or `null`, it points the `[[Prototype]]` of the created object to that value. (If the value is not an object or `null`, the object is not changed.)

Note that the `__proto__` key is standardized syntax, in contrast to the non-standard and non-performant `Object.prototype.__proto__` accessors. It sets the `[[Prototype]]` during object creation, similar to `Object.create` — instead of mutating the prototype chain.

```js
const obj1 = {};
console.log(Object.getPrototypeOf(obj1) === Object.prototype); // true

const obj2 = { \_\_proto\_\_: null };
console.log(Object.getPrototypeOf(obj2)); // null

const protoObj = {};
const obj3 = { "\_\_proto\_\_": protoObj };
console.log(Object.getPrototypeOf(obj3) === protoObj); // true

const obj4 = { \_\_proto\_\_: "not an object or null" };
console.log(Object.getPrototypeOf(obj4) === Object.prototype); // true
console.log(Object.hasOwn(obj4, "\_\_proto\_\_")); // false
```

Only a single prototype setter is permitted in an object literal. Multiple prototype setters are a syntax error.

Property definitions that do not use "colon" notation are not prototype setters. They are property definitions that behave identically to similar definitions using any other name.

```js
const __proto__ = "variable";

const obj1 = { __proto__ };
console.log(Object.getPrototypeOf(obj1) === Object.prototype); // true
console.log(Object.hasOwn(obj1, "\_\_proto\_\_")); // true
console.log(obj1.__proto__); // "variable"

const obj2 = { \_\_proto\_\_() { return "hello"; } };
console.log(obj2.\_\_proto\_\_()); // "hello"

const obj3 = { ["\_\_proto\_\_"]: 17 };
console.log(obj3.__proto__); // 17

// Mixing prototype setter with normal own properties with "\_\_proto\_\_" key
const obj4 = { ["\_\_proto\_\_"]: 17, \_\_proto\_\_: {} }; // {\_\_proto\_\_: 17} (with {} as prototype)
const obj5 = {
  ["\_\_proto\_\_"]: 17,
  \_\_proto\_\_: {},
  \_\_proto\_\_: null, // SyntaxError: Duplicate \_\_proto\_\_ fields are not allowed in object literals
};
const obj6 = {
  ["\_\_proto\_\_"]: 17,
  ["\_\_proto\_\_"]: "hello",
  \_\_proto\_\_: null,
}; // {\_\_proto\_\_: "hello"} (with null as prototype)
const obj7 =  {
  ["\_\_proto\_\_"]: 17,
  __proto__,
  \_\_proto\_\_: null,
}; // {\_\_proto\_\_: "variable"} (with null as prototype)
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object-initializer |

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

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

See also
--------

* Property accessors
* `get`
* `set`
* Method definitions
* Lexical grammar


Unsigned right shift assignment (>>>=) - JavaScript

Unsigned right shift assignment (>>>=)
======================================

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

```js
let a = 5; // (00000000000000000000000000000101)
a >>>= 2; // 1 (00000000000000000000000000000001)

let b = -5; // (-00000000000000000000000000000101)
b >>>= 2; // 1073741822 (00111111111111111111111111111110)

let c = 5n;
c >>>= 2n; // 1n
```

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

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

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

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

See also
--------

* Assignment operators in the JS guide
* Unsigned right shift (`>>>`)


Remainder assignment (%=) - JavaScript

Remainder assignment (%=)
=========================

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

```js
let bar = 5;

bar %= 2; // 1
bar %= "foo"; // NaN
bar %= 0; // NaN

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

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

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

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

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

See also
--------

* Assignment operators in the JS guide
* Remainder (`%`)


Greater than (>) - JavaScript

Greater than (>)
================

 The **greater than (`>`)** operator returns `true` if the left
 operand is greater than 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, except the two operands are swapped. `x > y` is generally equivalent to `y < x`, except that `x > y` coerces `x` to a primitive before `y`, while `y < x` coerces `y` to a primitive before `x`. Because coercion may have side effects, the order of the operands may matter.

Examples
--------

### String to string comparison

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

### String to number comparison

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

"hello" > 5; // false
5 > "hello"; // false

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

### Number to Number comparison

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

### Number to BigInt comparison

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

### Comparing Boolean, null, undefined, NaN

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

true > 0; // true
true > 1; // false

null > 0; // false
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 or equal (`>=`)
* Less than (`<`)
* Less than or equal (`<=`)


Spread syntax (...) - JavaScript

Spread syntax (...)
===================

The **spread (`...`)** syntax allows an iterable, such as an array or string, to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected. In an object literal, the spread syntax enumerates the properties of an object and adds the key-value pairs to the object being created.

Spread syntax looks exactly like rest syntax. In a way, spread syntax is the opposite of rest syntax. Spread syntax "expands" an array into its elements, while rest syntax collects multiple elements and "condenses" them into a single element. See rest parameters and rest property.

Try it
------

Syntax
------

```js
myFunction(a, ...iterableObj, b)
[1, ...iterableObj, '4', 'five', 6]
{ ...obj, key: 'value' }
```

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

Spread syntax can be used when all elements from an object or array need to be included in a new array or object, or should be applied one-by-one in a function call's arguments list. There are three distinct places that accept the spread syntax:

* Function arguments list (`myFunction(a, ...iterableObj, b)`)
* Array literals (`[1, ...iterableObj, '4', 'five', 6]`)
* Object literals (`{ ...obj, key: 'value' }`)

Although the syntax looks the same, they come with slightly different semantics.

Only iterable values, like `Array` and `String`, can be spread in array literals and argument lists. Many objects are not iterable, including all plain objects that lack a `Symbol.iterator` method:

```js
const obj = { key1: "value1" };
const array = [...obj]; // TypeError: obj is not iterable
```

On the other hand, spreading in object literals enumerates the own properties of the value. For typical arrays, all indices are enumerable own properties, so arrays can be spread into objects.

```js
const array = [1, 2, 3];
const obj = { ...array }; // { 0: 1, 1: 2, 2: 3 }
```

All primitives can be spread in objects. Only strings have enumerable own properties, and spreading anything else doesn't create properties on the new object.

```js
const obj = { ...true, ..."test", ...10 };
// { '0': 't', '1': 'e', '2': 's', '3': 't' }
```

When using spread syntax for function calls, be aware of the possibility of exceeding the JavaScript engine's argument length limit. See `Function.prototype.apply()` for more details.

Examples
--------

### Spread in function calls

#### Replace apply()

 It is common to use `Function.prototype.apply()` in cases where you want to
 use the elements of an array as arguments to a function.

```js
function myFunction(x, y, z) {}
const args = [0, 1, 2];
myFunction.apply(null, args);
```

With spread syntax the above can be written as:

```js
function myFunction(x, y, z) {}
const args = [0, 1, 2];
myFunction(...args);
```

 Any argument in the argument list can use spread syntax, and the spread syntax can be
 used multiple times.

```js
function myFunction(v, w, x, y, z) {}
const args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);
```

#### Apply for new operator

When calling a constructor with `new`, it's not possible to **directly** use an array and `apply()`, because `apply()` *calls* the target function instead of *constructing* it, which means, among other things, that `new.target` will be `undefined`. However, an array can be easily used with `new` thanks to spread syntax:

```js
const dateFields = [1970, 0, 1]; // 1 Jan 1970
const d = new Date(...dateFields);
```

### Spread in array literals

#### A more powerful array literal

Without spread syntax, the array literal syntax is no longer sufficient to create a new array using an existing array as one part of it. Instead, imperative code must be used using a combination of methods, including `push()`, `splice()`, `concat()`, etc. With spread syntax, this becomes much more succinct:

```js
const parts = ["shoulders", "knees"];
const lyrics = ["head", ...parts, "and", "toes"];
// ["head", "shoulders", "knees", "and", "toes"]
```

Just like spread for argument lists, `...` can be used anywhere in the array literal, and may be used more than once.

#### Copying an array

You can use spread syntax to make a shallow copy of an array. Each array element retains its identity without getting copied.

```js
const arr = [1, 2, 3];
const arr2 = [...arr]; // like arr.slice()

arr2.push(4);
// arr2 becomes [1, 2, 3, 4]
// arr remains unaffected
```

Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays. The same is true with `Object.assign()` — no native operation in JavaScript does a deep clone. The web API method `structuredClone()` allows deep copying values of certain supported types. See shallow copy for more details.

```js
const a = [[1], [2], [3]];
const b = [...a];

b.shift().shift();
// 1

// Oh no! Now array 'a' is affected as well:
console.log(a);
// [[], [2], [3]]
```

#### A better way to concatenate arrays

`Array.prototype.concat()` is often used to concatenate an array to the end of an existing array. Without spread syntax, this is done as:

```js
let arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];

// Append all items from arr2 onto arr1
arr1 = arr1.concat(arr2);
```

With spread syntax this becomes:

```js
let arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];

arr1 = [...arr1, ...arr2];
// arr1 is now [0, 1, 2, 3, 4, 5]
```

`Array.prototype.unshift()` is often used to insert an array of values at the start of an existing array. Without spread syntax, this is done as:

```js
const arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];

// Prepend all items from arr2 onto arr1
Array.prototype.unshift.apply(arr1, arr2);
console.log(arr1); // [3, 4, 5, 0, 1, 2]
```

With spread syntax, this becomes:

```js
let arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];

arr1 = [...arr2, ...arr1];
console.log(arr1); // [3, 4, 5, 0, 1, 2]
```

**Note:** Unlike `unshift()`, this creates a new `arr1`, instead of modifying the original `arr1` array in-place.

#### Conditionally adding values to an array

You can make an element present or absent in an array literal, depending on a condition, using a conditional operator.

```js
const isSummer = false;
const fruits = ["apple", "banana", ...(isSummer ? ["watermelon"] : [])];
// ['apple', 'banana']
```

When the condition is `false`, we spread an empty array, so that nothing gets added to the final array. Note that this is different from the following:

```js
const fruits = ["apple", "banana", isSummer ? "watermelon" : undefined];
// ['apple', 'banana', undefined]
```

In this case, an extra `undefined` element is added when `isSummer` is `false`, and this element will be visited by methods such as `Array.prototype.map()`.

### Spread in object literals

#### Copying and merging objects

You can use spread syntax to merge multiple objects into one new object.

```js
const obj1 = { foo: "bar", x: 42 };
const obj2 = { bar: "baz", y: 13 };

const mergedObj = { ...obj1, ...obj2 };
// { foo: "bar", x: 42, bar: "baz", y: 13 }
```

A single spread creates a shallow copy of the original object (but without non-enumerable properties and without copying the prototype), similar to copying an array.

```js
const clonedObj = { ...obj1 };
// { foo: "bar", x: 42 }
```

#### Overriding properties

When one object is spread into another object, or when multiple objects are spread into one object, and properties with identical names are encountered, the property takes the last value assigned while remaining in the position it was originally set.

```js
const obj1 = { foo: "bar", x: 42 };
const obj2 = { foo: "baz", y: 13 };

const mergedObj = { x: 41, ...obj1, ...obj2, y: 9 }; // { x: 42, foo: "baz", y: 9 }
```

#### Conditionally adding properties to an object

You can make an element present or absent in an object literal, depending on a condition, using a conditional operator.

```js
const isSummer = false;
const fruits = {
  apple: 10,
  banana: 5,
  ...(isSummer ? { watermelon: 30 } : {}),
};
// { apple: 10, banana: 5 }
```

The case where the condition is `false` is an empty object, so that nothing gets spread into the final object. Note that this is different from the following:

```js
const fruits = {
  apple: 10,
  banana: 5,
  watermelon: isSummer ? 30 : undefined,
};
// { apple: 10, banana: 5, watermelon: undefined }
```

In this case, the `watermelon` property is always present and will be visited by methods such as `Object.keys()`.

Because primitives can be spread into objects as well, and from the observation that all falsy values do not have enumerable properties, you can simply use a logical AND operator:

```js
const isSummer = false;
const fruits = {
  apple: 10,
  banana: 5,
  ...(isSummer && { watermelon: 30 }),
};
```

In this case, if `isSummer` is any falsy value, no property will be created on the `fruits` object.

#### Comparing with Object.assign()

Note that `Object.assign()` can be used to mutate an object, whereas spread syntax can't.

```js
const obj1 = { foo: "bar", x: 42 };
Object.assign(obj1, { x: 1337 });
console.log(obj1); // { foo: "bar", x: 1337 }
```

In addition, `Object.assign()` triggers setters on the target object, whereas spread syntax does not.

```js
const objectAssign = Object.assign(
  {
    set foo(val) {
      console.log(val);
    },
  },
  { foo: 1 },
);
// Logs "1"; objectAssign.foo is still the original setter

const spread = {
  set foo(val) {
    console.log(val);
  },
  ...{ foo: 1 },
};
// Nothing is logged; spread.foo is 1
```

You cannot naively re-implement the `Object.assign()` function through a single spreading:

```js
const obj1 = { foo: "bar", x: 42 };
const obj2 = { foo: "baz", y: 13 };
const merge = (...objects) => ({ ...objects });

const mergedObj1 = merge(obj1, obj2);
// { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }

const mergedObj2 = merge({}, obj1, obj2);
// { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }
```

In the above example, the spread syntax does not work as one might expect: it spreads an *array* of arguments into the object literal, due to the rest parameter. Here is an implementation of `merge` using the spread syntax, whose behavior is similar to `Object.assign()`, except that it doesn't trigger setters, nor mutates any object:

```js
const obj1 = { foo: "bar", x: 42 };
const obj2 = { foo: "baz", y: 13 };
const merge = (...objects) =>
  objects.reduce((acc, cur) => ({ ...acc, ...cur }));

const mergedObj1 = merge(obj1, obj2);
// { foo: 'baz', x: 42, y: 13 }
```

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-SpreadElement |
| ECMAScript Language Specification # prod-ArgumentList |
| ECMAScript Language Specification # prod-PropertyDefinition |

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

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

See also
--------

* Rest parameters
* Rest property
* `Function.prototype.apply()`


class expression - JavaScript

class expression
================

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

You can also define classes using the `class` declaration.

Try it
------

Syntax
------

```js
class {
  // class body
}
class name {
  // class body
}
```

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

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

A `class` expression is very similar to, and has almost the same syntax as, a `class` declaration. As with `class` declarations, the body of a `class` expression is executed in strict mode. The main difference between a `class` expression and a `class` declaration is the *class name*, which can be omitted in `class` expressions to create *anonymous* classes. Class expressions allow you to redefine classes, while redeclaring a class using `class` declarations throws a `SyntaxError`. See also the chapter about classes for more information.

Examples
--------

### A simple class expression

This is just a simple anonymous class expression which you can refer to using the variable `Foo`.

```js
const Foo = class {
  constructor() {}
  bar() {
    return "Hello World!";
  }
};

const instance = new Foo();
instance.bar(); // "Hello World!"
Foo.name; // "Foo"
```

### Named class expressions

If you want to refer to the current class inside the class body, you can create a *named class expression*. The name is only visible within the scope of the class expression itself.

```js
const Foo = class NamedFoo {
  constructor() {}
  whoIsThere() {
    return NamedFoo.name;
  }
};
const bar = new Foo();
bar.whoIsThere(); // "NamedFoo"
NamedFoo.name; // ReferenceError: NamedFoo is not defined
Foo.name; // "NamedFoo"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-class-definitions |

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

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

See also
--------

* `class`
* Classes


Assignment (=) - JavaScript

Assignment (=)
==============

The **assignment (`=`)** operator is used to assign a value to a variable or property. The assignment expression itself has a value, which is the assigned value. This allows multiple assignments to be chained in order to assign a single value to multiple variables.

Try it
------

Syntax
------

```js
x = y
```

### Parameters

`x`

A valid assignment target, including an identifier or a property accessor. It can also be a destructuring assignment pattern.

`y`

An expression specifying the value to be assigned to `x`.

### Return value

The value of `y`.

### Exceptions

`ReferenceError`

Thrown in strict mode if assigning to an identifier that is not declared in the scope.

`TypeError`

Thrown in strict mode if assigning to a property that is not modifiable.

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

The assignment operator is completely different from the equals (`=`) sign used as syntactic separators in other locations, which include:

* Initializers of `var`, `let`, and `const` declarations
* Default values of destructuring
* Default parameters
* Initializers of class fields

All these places accept an assignment expression on the right-hand side of the `=`, so if you have multiple equals signs chained together:

```js
const x = y = 5;
```

This is equivalent to:

```js
const x = (y = 5);
```

Which means `y` must be a pre-existing variable, and `x` is a newly declared `const` variable. `y` is assigned the value `5`, and `x` is initialized with the value of the `y = 5` expression, which is also `5`. If `y` is not a pre-existing variable, a global variable `y` is implicitly created in non-strict mode, or a `ReferenceError` is thrown in strict mode. To declare two variables within the same declaration, use:

```js
const x = 5,
  y = 5;
```

Examples
--------

### Simple assignment and chaining

```js
let x = 5;
let y = 10;
let z = 25;

x = y; // x is 10
x = y = z; // x, y and z are all 25
```

### Value of assignment expressions

The assignment expression itself evaluates to the value of the right-hand side, so you can log the value and assign to a variable at the same time.

```js
let x;
console.log(x); // undefined
console.log(x = 2); // 2
console.log(x); // 2
```

### Unqualified identifier assignment

The global object sits at the top of the scope chain. When attempting to resolve a name to a value, the scope chain is searched. This means that properties on the global object are conveniently visible from every scope, without having to qualify the names with `globalThis.` or `window.` or `global.`.

Because the global object has a `String` property (`Object.hasOwn(globalThis, "String")`), you can use the following code:

```js
function foo() {
  String("s"); // The function `String` is globally available
}
```

So the global object will ultimately be searched for unqualified identifiers. You don't have to type `globalThis.String`; you can just type the unqualified `String`. To make this feature more conceptually consistent, assignment to unqualified identifiers will assume you want to create a property with that name on the global object (with `globalThis.` omitted), if there is no variable of the same name declared in the scope chain.

```js
foo = "f"; // In non-strict mode, assumes you want to create a property named `foo` on the global object
Object.hasOwn(globalThis, "foo"); // true
```

In strict mode, assignment to an unqualified identifier in strict mode will result in a `ReferenceError`, to avoid the accidental creation of properties on the global object.

Note that the implication of the above is that, contrary to popular misinformation, JavaScript does not have implicit or undeclared variables. It just conflates the global object with the global scope and allows omitting the global object qualifier during property creation.

### Assignment with destructuring

The left-hand side of can also be an assignment pattern. This allows assigning to multiple variables at once.

```js
const result = /(a+)(b+)(c+)/.exec("aaabcc");
let a = "",
  b = "",
  c = "";
[, a, b, c] = result;
console.log(a, b, c); // "aaa" "b" "cc"
```

For more information, see Destructuring assignment.

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
* Destructuring assignment