const - JavaScript

const
=====

The **`const`** declaration declares block-scoped local variables. The value of a constant can't be changed through reassignment using the assignment operator, but if a constant is an object, its properties can be added, updated, or removed.

Try it
------

Syntax
------

```js
const name1 = value1;
const name1 = value1, name2 = value2;
const name1 = value1, name2 = value2, /\* …, \*/ nameN = valueN;
```

`nameN`

The name of the variable to declare. Each must be a legal JavaScript identifier or a destructuring binding pattern.

`valueN`

Initial value of the variable. It can be any legal expression.

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

The `const` declaration is very similar to `let`:

* `const` declarations are scoped to blocks as well as functions.
* `const` declarations can only be accessed after the place of declaration is reached (see temporal dead zone). For this reason, `const` declarations are commonly regarded as non-hoisted.
* `const` declarations do not create properties on `globalThis` when declared at the top level of a script.
* `const` declarations cannot be redeclared by any other declaration in the same scope.
* `const` begins *declarations*, not *statements*. That means you cannot use a lone `const` declaration as the body of a block (which makes sense, since there's no way to access the variable).

```js
if (true) const a = 1; // SyntaxError: Lexical declaration cannot appear in a single-statement context
```

An initializer for a constant is required. You must specify its value in the same declaration. (This makes sense, given that it can't be changed later.)

```js
const FOO; // SyntaxError: Missing initializer in const declaration
```

The `const` declaration creates an immutable reference to a value. It does *not* mean the value it holds is immutable — just that the variable identifier cannot be reassigned. For instance, in the case where the content is an object, this means the object's contents (e.g., its properties) can be altered. You should understand `const` declarations as "create a variable whose *identity* remains constant", not "whose *value* remains constant" — or, "create immutable bindings", not "immutable values".

Many style guides (including MDN's) recommend using `const` over `let` whenever a variable is not reassigned in its scope. This makes the intent clear that a variable's type (or value, in the case of a primitive) can never change. Others may prefer `let` for non-primitives that are mutated.

The list that follows the `const` keyword is called a *binding list* and is separated by commas, where the commas are *not* comma operators and the `=` signs are *not* assignment operators. Initializers of later variables can refer to earlier variables in the list.

Examples
--------

### Basic const usage

Constants can be declared with uppercase or lowercase, but a common convention is to use all-uppercase letters, especially for primitives because they are truly immutable.

```js
// define MY\_FAV as a constant and give it the value 7
const MY\_FAV = 7;

console.log("my favorite number is: " + MY\_FAV);
```

```js
// Re-assigning to a constant variable throws an error
MY\_FAV = 20; // TypeError: Assignment to constant variable

// Redeclaring a constant throws an error
const MY\_FAV = 20; // SyntaxError: Identifier 'MY\_FAV' has already been declared
var MY\_FAV = 20; // SyntaxError: Identifier 'MY\_FAV' has already been declared
let MY\_FAV = 20; // SyntaxError: Identifier 'MY\_FAV' has already been declared
```

### Block scoping

It's important to note the nature of block scoping.

```js
const MY\_FAV = 7;

if (MY\_FAV === 7) {
  // This is fine because it's in a new block scope
  const MY\_FAV = 20;
  console.log(MY\_FAV); // 20

  // var declarations are not scoped to blocks so this throws an error
  var MY\_FAV = 20; // SyntaxError: Identifier 'MY\_FAV' has already been declared
}

console.log(MY\_FAV); // 7
```

### const in objects and arrays

`const` also works on objects and arrays. Attempting to overwrite the object throws an error "Assignment to constant variable".

```js
const MY\_OBJECT = { key: "value" };
MY\_OBJECT = { OTHER\_KEY: "value" };
```

However, object keys are not protected, so the following statement is executed without problem.

```js
MY\_OBJECT.key = "otherValue";
```

You would need to use `Object.freeze()` to make an object immutable.

The same applies to arrays. Assigning a new array to the variable throws an error "Assignment to constant variable".

```js
const MY\_ARRAY = [];
MY\_ARRAY = ["B"];
```

Still, it's possible to push items into the array and thus mutate it.

```js
MY\_ARRAY.push("A"); // ["A"]
```

### Declaration with destructuring

The left-hand side of each `=` can also be a binding pattern. This allows creating multiple variables at once.

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

For more information, see Destructuring assignment.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-let-and-const-declarations |

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

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

See also
--------

* `var`
* `let`
* Constants in the JavaScript Guide


switch - JavaScript

switch
======

The **`switch`** statement evaluates an expression, matching the expression's value against a series of `case` clauses, and executes statements after the first `case` clause with a matching value, until a `break` statement is encountered. The `default` clause of a `switch` statement will be jumped to if no `case` matches the expression's value.

Try it
------

Syntax
------

```js
switch (expression) {
  case caseExpression1:
    statements
  case caseExpression2:
    statements
  // …
  case caseExpressionN:
    statements
  default:
    statements
}
```

`expression`

An expression whose result is matched against each `case` clause.

`case caseExpressionN` Optional

A `case` clause used to match against `expression`. If the value of `expression` matches the value of any `caseExpressionN`, execution starts from the first statement after that `case` clause until either the end of the `switch` statement or the first encountered `break`.

`default` Optional

A `default` clause; if provided, this clause is executed if the value of `expression` doesn't match any of the `case` clauses. A `switch` statement can only have one `default` clause.

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

A `switch` statement first evaluates its expression. It then looks for the first `case` clause whose expression evaluates to the same value as the result of the input expression (using the strict equality comparison) and transfers control to that clause, executing all statements following that clause.

The clause expressions are only evaluated when necessary — if a match is already found, subsequent `case` clause expressions will not be evaluated, even when they will be visited by fall-through.

```js
switch (undefined) {
  case console.log(1):
  case console.log(2):
}
// Only logs 1
```

If no matching `case` clause is found, the program looks for the optional `default` clause, and if found, transfers control to that clause, executing statements following that clause. If no `default` clause is found, the program continues execution at the statement following the end of `switch`. By convention, the `default` clause is the last clause, but it does not need to be so. A `switch` statement may only have one `default` clause; multiple `default` clauses will result in a `SyntaxError`.

### Breaking and fall-through

You can use the `break` statement within a `switch` statement's body to break out early, often when all statements between two `case` clauses have been executed. Execution will continue at the first statement following `switch`.

If `break` is omitted, execution will proceed to the next `case` clause, even to the `default` clause, regardless of whether the value of that clause's expression matches. This behavior is called "fall-through".

```js
const foo = 0;
switch (foo) {
  case -1:
    console.log("negative 1");
    break;
  case 0: // Value of foo matches this criteria; execution starts from here
    console.log(0);
  // Forgotten break! Execution falls through
  case 1: // no break statement in 'case 0:' so this case will run as well
    console.log(1);
    break; // Break encountered; will not continue into 'case 2:'
  case 2:
    console.log(2);
    break;
  default:
    console.log("default");
}
// Logs 0 and 1
```

In the appropriate context, other control-flow statements also have the effect of breaking out of the `switch` statement. For example, if the `switch` statement is contained in a function, then a `return` statement terminates the execution of the function body and therefore the `switch` statement. If the `switch` statement is contained in a loop, then a `continue` statement stops the `switch` statement and jumps to the next iteration of the loop.

### Lexical scoping

The `case` and `default` clauses are like labels: they indicate possible places that control flow may jump to. However, they don't create lexical scopes themselves (neither do they automatically break out — as demonstrated above). For example:

```js
const action = "say\_hello";
switch (action) {
  case "say\_hello":
    const message = "hello";
    console.log(message);
    break;
  case "say\_hi":
    const message = "hi";
    console.log(message);
    break;
  default:
    console.log("Empty action received.");
}
```

This example will output the error "Uncaught SyntaxError: Identifier 'message' has already been declared", because the first `const message = 'hello';` conflicts with the second `const message = 'hi';` declaration, even when they're within their own separate case clauses. Ultimately, this is due to both `const` declarations being within the same block scope created by the `switch` body.

To fix this, whenever you need to use `let` or `const` declarations in a `case` clause, wrap it in a block.

```js
const action = "say\_hello";
switch (action) {
  case "say\_hello": {
    const message = "hello";
    console.log(message);
    break;
  }
  case "say\_hi": {
    const message = "hi";
    console.log(message);
    break;
  }
  default: {
    console.log("Empty action received.");
  }
}
```

This code will now output `hello` in the console as it should, without any errors.

Examples
--------

### Using switch

In the following example, if `expr` evaluates to `Bananas`, the program matches the value with case `case 'Bananas'` and executes the associated statement. When `break` is encountered, the program breaks out of `switch` and executes the statement following `switch`. If `break` were omitted, the statement for the `case 'Cherries'` would also be executed.

```js
switch (expr) {
  case "Oranges":
    console.log("Oranges are $0.59 a pound.");
    break;
  case "Apples":
    console.log("Apples are $0.32 a pound.");
    break;
  case "Bananas":
    console.log("Bananas are $0.48 a pound.");
    break;
  case "Cherries":
    console.log("Cherries are $3.00 a pound.");
    break;
  case "Mangoes":
  case "Papayas":
    console.log("Mangoes and papayas are $2.79 a pound.");
    break;
  default:
    console.log(`Sorry, we are out of ${expr}.`);
}

console.log("Is there anything else you'd like?");
```

### Putting the default clause between two case clauses

If no match is found, execution will start from the `default` clause, and execute all statements after that.

```js
const foo = 5;
switch (foo) {
  case 2:
    console.log(2);
    break; // it encounters this break so will not continue into 'default:'
  default:
    console.log("default");
  // fall-through
  case 1:
    console.log("1");
}
```

It also works when you put `default` before all other `case` clauses.

### Taking advantage of fall-through

This method takes advantage of the fact that if there is no `break` below a `case` clause, execution will continue to the next `case` clause regardless if that `case` meets the criteria.

The following is an example of a single operation sequential `case` statement, where four different values perform exactly the same.

```js
const Animal = "Giraffe";
switch (Animal) {
  case "Cow":
  case "Giraffe":
  case "Dog":
  case "Pig":
    console.log("This animal is not extinct.");
    break;
  case "Dinosaur":
  default:
    console.log("This animal is extinct.");
}
```

The following is an example of a multiple-operation sequential `case` clause, where, depending on the provided integer, you can receive different output. This shows you that it will traverse in the order that you put the `case` clauses, and it does not have to be numerically sequential. In JavaScript, you can even mix in definitions of strings into these `case` statements as well.

```js
const foo = 1;
let output = "Output: ";
switch (foo) {
  case 0:
    output += "So ";
  case 1:
    output += "What ";
    output += "Is ";
  case 2:
    output += "Your ";
  case 3:
    output += "Name";
  case 4:
    output += "?";
    console.log(output);
    break;
  case 5:
    output += "!";
    console.log(output);
    break;
  default:
    console.log("Please pick a number from 0 to 5!");
}
```

The output from this example:

| Value | Log text |
| --- | --- |
| `foo` is `NaN` or not `1`, `2`, `3`, `4`, `5`, or `0` | Please pick a number from 0 to 5! |
| `0` | Output: So What Is Your Name? |
| `1` | Output: What Is Your Name? |
| `2` | Output: Your Name? |
| `3` | Output: Name? |
| `4` | Output: ? |
| `5` | Output: ! |

### An alternative to if...else chains

You may often find yourself doing a series of `if...else` matches.

```js
if ("fetch" in globalThis) {
  // Fetch a resource with fetch
} else if ("XMLHttpRequest" in globalThis) {
  // Fetch a resource with XMLHttpRequest
} else {
  // Fetch a resource with some custom AJAX logic
}
```

This pattern is not doing a sequence of `===` comparisons, but you can still convert it to a `switch` construct.

```js
switch (true) {
  case "fetch" in globalThis:
    // Fetch a resource with fetch
    break;
  case "XMLHttpRequest" in globalThis:
    // Fetch a resource with XMLHttpRequest
    break;
  default:
    // Fetch a resource with some custom AJAX logic
    break;
}
```

The `switch (true)` pattern as an alternative to `if...else` is especially useful if you want to utilize the fall-through behavior.

```js
switch (true) {
  case isSquare(shape):
    console.log("This shape is a square.");
  // Fall-through, since a square is a rectangle as well!
  case isRectangle(shape):
    console.log("This shape is a rectangle.");
  case isQuadrilateral(shape):
    console.log("This shape is a quadrilateral.");
    break;
  case isCircle(shape):
    console.log("This shape is a circle.");
    break;
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-switch-statement |

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

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

See also
--------

* `if...else`


class - JavaScript

class
=====

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2017.

* Learn more
* See full compatibility
* Report feedback
The **`class`** declaration creates a binding of a new class to a given name.

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

Try it
------

Syntax
------

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

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

The class body of a class declaration is executed in strict mode. The `class` declaration is very similar to `let`:

* `class` declarations are scoped to blocks as well as functions.
* `class` declarations can only be accessed after the place of declaration is reached (see temporal dead zone). For this reason, `class` declarations are commonly regarded as non-hoisted (unlike function declarations).
* `class` declarations do not create properties on `globalThis` when declared at the top level of a script (unlike function declarations).
* `class` declarations cannot be redeclared by any other declaration in the same scope.

Outside the class body, `class` declarations can be re-assigned like `let`, but you should avoid doing so. Within the class body, the binding is constant like `const`.

```js
class Foo {
  static {
    Foo = 1; // TypeError: Assignment to constant variable.
  }
}

class Foo2 {
  bar = (Foo2 = 1); // TypeError: Assignment to constant variable.
}

class Foo3 {}
Foo3 = 1;
console.log(Foo3); // 1
```

Examples
--------

### A simple class declaration

In the following example, we first define a class named `Rectangle`, then extend it to create a class named `FilledRectangle`.

Note that `super()`, used in the `constructor`, can only be used in constructors, and *must* be called *before* the `this` keyword can be used.

```js
class Rectangle {
  constructor(height, width) {
    this.name = "Rectangle";
    this.height = height;
    this.width = width;
  }
}

class FilledRectangle extends Rectangle {
  constructor(height, width, color) {
    super(height, width);
    this.name = "Filled rectangle";
    this.color = color;
  }
}
```

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

* `function`
* `class` expression
* Classes


Labeled statement - JavaScript

Labeled statement
=================

A **labeled statement** is any statement that is prefixed with an identifier. You can jump to this label using a `break` or `continue` statement nested within the labeled statement.

Try it
------

Syntax
------

```js
label:
  statement
```

`label`

Any JavaScript identifier that is not a reserved word.

`statement`

A JavaScript statement. `break` can be used within any labeled statement, and `continue` can be used within labeled looping statements.

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

You can use a label to identify a statement, and later refer to it using a `break` or `continue` statement. Note that JavaScript has *no* `goto` statement; you can only use labels with `break` or `continue`.

Any `break` or `continue` that references `label` must be contained within the `statement` that's labeled by `label`. Think about `label` as a variable that's only available in the scope of `statement`.

If a `break label;` statement is encountered when executing `statement`, execution of `statement` terminates, and execution continues at the statement immediately following the labeled statement.

`continue label;` can only be used if `statement` is one of the looping statements. If a `continue label;` statement is encountered when executing `statement`, execution of `statement` continues at the next iteration of the loop. `continue;` without a label can only continue the innermost loop, while `continue label;` allows continuing any given loop even when the statement is nested within other loops.

A statement can have multiple labels. In this case, the labels are all functionally equivalent.

Examples
--------

### Using a labeled continue with for loops

```js
// The first for statement is labeled "loop1"
loop1: for (let i = 0; i < 3; i++) {
  // The second for statement is labeled "loop2"
  loop2: for (let j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      continue loop1;
    }
    console.log(`i = ${i}, j = ${j}`);
  }
}

// Logs:
// i = 0, j = 0
// i = 0, j = 1
// i = 0, j = 2
// i = 1, j = 0
// i = 2, j = 0
// i = 2, j = 1
// i = 2, j = 2
```

Notice how it skips both "i = 1, j = 1" and "i = 1, j = 2".

### Using a labeled break with for loops

```js
let i, j;

// The first for statement is labeled "loop1"
loop1: for (i = 0; i < 3; i++) {
  // The second for statement is labeled "loop2"
  loop2: for (j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      break loop1;
    }
    console.log(`i = ${i}, j = ${j}`);
  }
}

// Logs:
// i = 0, j = 0
// i = 0, j = 1
// i = 0, j = 2
// i = 1, j = 0
```

Notice the difference with the previous `continue` example: when `break loop1` is encountered, the execution of the outer loop is terminated, so there are no further logs beyond "i = 1, j = 0"; when `continue loop1` is encountered, the execution of the outer loop continues at the next iteration, so only "i = 1, j = 1" and "i = 1, j = 2" are skipped.

### Using a labeled continue statement

Given an array of items and an array of tests, this example counts the number of items that pass all the tests.

```js
// Numbers from 1 to 100
const items = Array.from({ length: 100 }, (\_, i) => i + 1);
const tests = [
  { pass: (item) => item % 2 === 0 },
  { pass: (item) => item % 3 === 0 },
  { pass: (item) => item % 5 === 0 },
];
let itemsPassed = 0;

itemIteration: for (const item of items) {
  for (const test of tests) {
    if (!test.pass(item)) {
      continue itemIteration;
    }
  }

  itemsPassed++;
}
```

Note how the `continue itemIteration;` statement skips the rest of the tests for the current item as well as the statement that updates the `itemsPassed` counter, and continues with the next item. If you don't use a label, you would need to use a boolean flag instead.

```js
// Numbers from 1 to 100
const items = Array.from({ length: 100 }, (\_, i) => i + 1);
const tests = [
  { pass: (item) => item % 2 === 0 },
  { pass: (item) => item % 3 === 0 },
  { pass: (item) => item % 5 === 0 },
];
let itemsPassed = 0;

for (const item of items) {
  let passed = true;
  for (const test of tests) {
    if (!test.pass(item)) {
      passed = false;
      break;
    }
  }
  if (passed) {
    itemsPassed++;
  }
}
```

### Using a labeled break statement

Given an array of items and an array of tests, this example determines whether all items pass all tests.

```js
// Numbers from 1 to 100
const items = Array.from({ length: 100 }, (\_, i) => i + 1);
const tests = [
  { pass: (item) => item % 2 === 0 },
  { pass: (item) => item % 3 === 0 },
  { pass: (item) => item % 5 === 0 },
];
let allPass = true;

itemIteration: for (const item of items) {
  for (const test of tests) {
    if (!test.pass(item)) {
      allPass = false;
      break itemIteration;
    }
  }
}
```

Again, if you don't use a label, you would need to use a boolean flag instead.

```js
// Numbers from 1 to 100
const items = Array.from({ length: 100 }, (\_, i) => i + 1);
const tests = [
  { pass: (item) => item % 2 === 0 },
  { pass: (item) => item % 3 === 0 },
  { pass: (item) => item % 5 === 0 },
];
let allPass = true;

for (const item of items) {
  let passed = true;
  for (const test of tests) {
    if (!test.pass(item)) {
      passed = false;
      break;
    }
  }
  if (!passed) {
    allPass = false;
    break;
  }
}
```

### Using a labeled block with break

You can label statements other than loops, such as simple blocks, but only `break` statements can reference non-loop labels.

```js
foo: {
  console.log("face");
  break foo;
  console.log("this will not be executed");
}
console.log("swap");

// Logs:
// "face"
// "swap"
```

### Labeled function declarations

Labels can only be applied to statements, not declarations. There is a legacy grammar that allows function declarations to be labeled in non-strict code:

```js
L: function F() {}
```

In strict mode code, however, this will throw a `SyntaxError`:

```js
"use strict";
L: function F() {}
// SyntaxError: functions cannot be labelled
```

Non-plain functions, such as generator functions and async functions can neither be labeled in strict code, nor in non-strict code:

```js
L: function\* F() {}
// SyntaxError: generator functions cannot be labelled
```

The labeled function declaration syntax is deprecated and you should not use it, even in non-strict code. You cannot actually jump to this label within the function body.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-labelled-statements |

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

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

See also
--------

* `break`
* `continue`


var - JavaScript

var
===

The **`var`** statement declares function-scoped or globally-scoped variables, optionally initializing each to a value.

Try it
------

Syntax
------

```js
var name1;
var name1 = value1;
var name1 = value1, name2 = value2;
var name1, name2 = value2;
var name1 = value1, name2, /\* …, \*/ nameN = valueN;
```

`nameN`

The name of the variable to declare. Each must be a legal JavaScript identifier or a destructuring binding pattern.

`valueN` Optional

Initial value of the variable. It can be any legal expression. Default value is `undefined`.

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

The scope of a variable declared with `var` is one of the following curly-brace-enclosed syntaxes that most closely contains the `var` statement:

* Function body
* Static initialization block

Or if none of the above applies:

* The current module, for code running in module mode
* The global scope, for code running in script mode.

```js
function foo() {
  var x = 1;
  function bar() {
    var y = 2;
    console.log(x); // 1 (function `bar` closes over `x`)
    console.log(y); // 2 (`y` is in scope)
  }
  bar();
  console.log(x); // 1 (`x` is in scope)
  console.log(y); // ReferenceError, `y` is scoped to `bar`
}

foo();
```

Importantly, other block constructs, including block statements, `try...catch`, `switch`, headers of one of the `for` statements, do not create scopes for `var`, and variables declared with `var` inside such a block can continue to be referenced outside the block.

```js
for (var a of [1, 2, 3]);
console.log(a); // 3
```

In a script, a variable declared using `var` is added as a non-configurable property of the global object. This means its property descriptor cannot be changed and it cannot be deleted using `delete`. JavaScript has automatic memory management, and it would make no sense to be able to use the `delete` operator on a global variable.

```js
"use strict";
var x = 1;
Object.hasOwn(globalThis, "x"); // true
delete globalThis.x; // TypeError in strict mode. Fails silently otherwise.
delete x; // SyntaxError in strict mode. Fails silently otherwise.
```

In both NodeJS CommonJS modules and native ECMAScript modules, top-level variable declarations are scoped to the module, and are not added as properties to the global object.

The list that follows the `var` keyword is called a *binding list* and is separated by commas, where the commas are *not* comma operators and the `=` signs are *not* assignment operators. Initializers of later variables can refer to earlier variables in the list and get the initialized value.

### Hoisting

`var` declarations, wherever they occur in a script, are processed before any code within the script is executed. Declaring a variable anywhere in the code is equivalent to declaring it at the top. This also means that a variable can appear to be used before it's declared. This behavior is called *hoisting*, as it appears that the variable declaration is moved to the top of the function, static initialization block, or script source in which it occurs.

**Note:** `var` declarations are only hoisted to the top of the current script. If you have two `<script>` elements within one HTML, the first script cannot access variables declared by the second before the second script has been processed and executed.

```js
bla = 2;
var bla;
```

This is implicitly understood as:

```js
var bla;
bla = 2;
```

For that reason, it is recommended to always declare variables at the top of their scope (the top of global code and the top of function code) so it's clear which variables are scoped to the current function.

Only a variable's declaration is hoisted, not its initialization. The initialization happens only when the assignment statement is reached. Until then the variable remains `undefined` (but declared):

```js
function doSomething() {
  console.log(bar); // undefined
  var bar = 111;
  console.log(bar); // 111
}
```

This is implicitly understood as:

```js
function doSomething() {
  var bar;
  console.log(bar); // undefined
  bar = 111;
  console.log(bar); // 111
}
```

### Redeclarations

Duplicate variable declarations using `var` will not trigger an error, even in strict mode, and the variable will not lose its value, unless the declaration has an initializer.

```js
var a = 1;
var a = 2;
console.log(a); // 2
var a;
console.log(a); // 2; not undefined
```

`var` declarations can also be in the same scope as a `function` declaration. In this case, the `var` declaration's initializer always overrides the function's value, regardless of their relative position. This is because function declarations are hoisted before any initializer gets evaluated, so the initializer comes later and overrides the value.

```js
var a = 1;
function a() {}
console.log(a); // 1
```

`var` declarations cannot be in the same scope as a `let`, `const`, `class`, or `import` declaration.

```js
var a = 1;
let a = 2; // SyntaxError: Identifier 'a' has already been declared
```

Because `var` declarations are not scoped to blocks, this also applies to the following case:

```js
let a = 1;
{
  var a = 1; // SyntaxError: Identifier 'a' has already been declared
}
```

It does not apply to the following case, where `let` is in a child scope of `var`, not the same scope:

```js
var a = 1;
{
  let a = 2;
}
```

A `var` declaration within a function's body can have the same name as a parameter.

```js
function foo(a) {
  var a = 1;
  console.log(a);
}

foo(2); // Logs 1
```

A `var` declaration within a `catch` block can have the same name as the `catch`-bound identifier, but only if the `catch` binding is a simple identifier, not a destructuring pattern. This is a deprecated syntax and you should not rely on it. In this case, the declaration is hoisted to outside the `catch` block, but any value assigned within the `catch` block is not visible outside.

```js
try {
  throw 1;
} catch (e) {
  var e = 2; // Works
}
console.log(e); // undefined
```

Examples
--------

### Declaring and initializing two variables

```js
var a = 0,
  b = 0;
```

### Assigning two variables with single string value

```js
var a = "A";
var b = a;
```

This is equivalent to:

```js
var a, b = a = "A";
```

Be mindful of the order:

```js
var x = y,
  y = "A";
console.log(x, y); // undefined A
```

Here, `x` and `y` are declared before any code is executed, but the assignments occur later. At the time `x = y` is evaluated, `y` exists so no `ReferenceError` is thrown and its value is `undefined`. So, `x` is assigned the undefined value. Then, `y` is assigned the value `"A"`.

### Initialization of several variables

Be careful of the `var x = y = 1` syntax — `y` is not actually declared as a variable, so `y = 1` is an unqualified identifier assignment, which creates a global variable in non-strict mode.

```js
var x = 0;
function f() {
  var x = y = 1; // Declares x locally; declares y globally.
}
f();

console.log(x, y); // 0 1

// In non-strict mode:
// x is the global one as expected;
// y is leaked outside of the function, though!
```

The same example as above but with a strict mode:

```js
"use strict";

var x = 0;
function f() {
  var x = y = 1; // ReferenceError: y is not defined
}
f();

console.log(x, y);
```

### Implicit globals and outer function scope

Variables that appear to be implicit globals may be references to variables in an outer function scope:

```js
var x = 0; // Declares x within file scope, then assigns it a value of 0.

console.log(typeof z); // "undefined", since z doesn't exist yet

function a() {
  var y = 2; // Declares y within scope of function a, then assigns it a value of 2.

  console.log(x, y); // 0 2

  function b() {
    x = 3; // Assigns 3 to existing file scoped x.
    y = 4; // Assigns 4 to existing outer y.
    z = 5; // Creates a new global variable z, and assigns it a value of 5.
    // (Throws a ReferenceError in strict mode.)
  }

  b(); // Creates z as a global variable.
  console.log(x, y, z); // 3 4 5
}

a(); // Also calls b.
console.log(x, z); // 3 5
console.log(typeof y); // "undefined", as y is local to function a
```

### Declaration with destructuring

The left-hand side of each `=` can also be a binding pattern. This allows creating multiple variables at once.

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

For more information, see Destructuring assignment.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-variable-statement |

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

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

See also
--------

* `let`
* `const`


do...while - JavaScript

do...while
==========

 The **`do...while`** statement creates a loop that executes a
 specified statement until the test condition evaluates to false. The condition is
 evaluated after executing the statement, resulting in the specified statement executing
 at least once.

Try it
------

Syntax
------

```js
do
  statement
while (condition);
```

`statement`

 A statement that is executed at least once and is re-executed each time the
 condition evaluates to true. To execute multiple statements within the loop, use a
 block statement (`{ /* ... */ }`) to
 group those statements.

`condition`

 An expression evaluated after each pass through the loop. If `condition`
evaluates to true, the `statement` is re-executed. When
 `condition` evaluates to false, control passes to the statement following
 the `do...while`.

 Note: Use the `break` statement to stop a loop before `condition` evaluates
 to false.

Examples
--------

### Using `do...while`

 In the following example, the `do...while` loop iterates at least once and
 reiterates until `i` is no longer less than 5.

```js
let result = "";
let i = 0;
do {
  i += 1;
  result += `${i} `;
} while (i > 0 && i < 5);
// Despite i === 0 this will still loop as it starts off without the test

console.log(result);
```

### Using an assignment as a condition

In some cases, it can make sense to use an assignment as a condition, such as this:

```js
do {
  // …
} while ((match = regexp.exec(str)));
```

But when you do, there are readability tradeoffs. The `while` documentation has a Using an assignment as a condition section with our recommendations.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-do-while-statement |

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

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

See also
--------

* `while`
* `for`
* `break`
* `continue`


with - JavaScript

with
====

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

**Note:** Use of the `with` statement is not recommended, as it may be the source of confusing bugs and compatibility issues, makes optimization impossible, and is forbidden in strict mode. The recommended alternative is to assign the object whose properties you want to access to a temporary variable.

The **`with`** statement extends the scope chain for a statement.

Syntax
------

```js
with (expression)
  statement
```

`expression`

Adds the given expression to the scope chain used when evaluating the statement. The parentheses around the expression are required.

`statement`

Any statement. To execute multiple statements, use a block statement (`{ ... }`) to group those statements.

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

There are two types of identifiers: a *qualified* identifier and an *unqualified* identifier. An unqualified identifier is one that does not indicate where it comes from.

```js
foo; // unqualified identifier
foo.bar; // bar is a qualified identifier
```

Normally, an unqualified identifier is resolved by searching the scope chain for a variable with that name, while a qualified identifier is resolved by searching the prototype chain of an object for a property with that name.

```js
const foo = { bar: 1 };
console.log(foo.bar);
// foo is found in the scope chain as a variable;
// bar is found in foo as a property
```

One exception to this is the global object, which sits on top of the scope chain, and whose properties automatically become global variables that can be referred to without qualifiers.

```js
console.log(globalThis.Math === Math); // true
```

The `with` statement adds the given object to the head of this scope chain during the evaluation of its statement body. Every unqualified name would first be searched within the object (through a `in` check) before searching in the upper scope chain.

Note that if the unqualified reference refers to a method of the object, the method is called with the object as its `this` value.

```js
with ([1, 2, 3]) {
  console.log(toString()); // 1,2,3
}
```

The object may have an `@@unscopables` property, which defines a list of properties that should not be added to the scope chain (for backward compatibility). See the `Symbol.unscopables` documentation for more information.

The reasons to use a `with` statement include saving one temporary variable and reducing file size by avoiding repeating a lengthy object reference. However, there are far more reasons why `with` statements are not desirable:

* Performance: The `with` statement forces the specified object to be searched first for all name lookups. Therefore, all identifiers that aren't members of the specified object will be found more slowly in a `with` block. Moreover, the optimizer cannot make any assumptions about what each unqualified identifier refers to, so it must repeat the same property lookup every time the identifier is used.
* Readability: The `with` statement makes it hard for a human reader or JavaScript compiler to decide whether an unqualified name will be found along the scope chain, and if so, in which object. For example:

```js
function f(x, o) {
  with (o) {
    console.log(x);
  }
}
```

If you look just at the definition of `f`, it's impossible to tell what the `x` in the `with` body refers to. Only when `f` is called can `x` be determined to be `o.x` or `f`'s first formal parameter. If you forget to define `x` in the object you pass as the second parameter, you won't get an error — instead you'll just get unexpected results. It's also unclear what the actual intent of such code would be.
* Forward compatibility: Code using `with` may not be forward compatible, especially when used with something other than a plain object, which may gain more properties in the future. Consider this example:

```js
function f(foo, values) {
  with (foo) {
    console.log(values);
  }
}
```

If you call `f([1, 2, 3], obj)` in an ECMAScript 5 environment, the `values` reference inside the `with` statement will resolve to `obj`. However, ECMAScript 2015 introduces a `values` property on `Array.prototype` (so it will be available on every array). So, after upgrading the environment, the `values` reference inside the `with` statement resolves to `[1, 2, 3].values` instead, and is likely to cause bugs.
 In this particular example, `values` is defined as unscopable through `Array.prototype[@@unscopables]`, so it still correctly resolves to the `values` parameter. If it were not defined as unscopable, one can see how this would be a difficult issue to debug.
Examples
--------

### Using the with statement

The following `with` statement specifies that the `Math` object is the default object. The statements following the `with` statement refer to the `PI` property and the `cos` and `sin` methods, without specifying an object. JavaScript assumes the `Math` object for these references.

```js
let a, x, y;
const r = 10;

with (Math) {
  a = PI \* r \* r;
  x = r \* cos(PI);
  y = r \* sin(PI / 2);
}
```

### Avoiding the with statement by destructuring properties into the current scope

You can usually avoid using `with` through property destructuring. Here we create an extra block to mimic the behavior of `with` creating an extra scope — but in actual usage, this block can usually be omitted.

```js
let a, x, y;
const r = 10;

{
  const { PI, cos, sin } = Math;
  a = PI \* r \* r;
  x = r \* cos(PI);
  y = r \* sin(PI / 2);
}
```

### Avoiding the with statement by using an IIFE

If you're producing an expression that must reuse a long-named reference multiple times, and your goal is to eliminate that lengthy name within your expression, you can wrap the expression in an IIFE and provide the long name as an argument.

```js
const objectHavingAnEspeciallyLengthyName = { foo: true, bar: false };

if (((o) => o.foo && !o.bar)(objectHavingAnEspeciallyLengthyName)) {
  // This branch runs.
}
```

### Creating dynamic namespaces using the with statement and a proxy

`with` will transform every variable lookup to a property lookup, while Proxies allow trapping every property lookup call. You can create a dynamic namespace by combining them.

```js
const namespace = new Proxy(
  {},
  {
    has(target, key) {
      // Avoid trapping global properties like `console`
      if (key in globalThis) {
        return false;
      }
      // Trap all property lookups
      return true;
    },
    get(target, key) {
      return key;
    },
  },
);

with (namespace) {
  console.log(a, b, c); // "a" "b" "c"
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-with-statement |

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

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

See also
--------

* block
* Strict mode
* `Symbol.unscopables`
* `Array.prototype[@@unscopables]`


while - JavaScript

while
=====

 The **`while`** statement creates a loop that executes a specified statement
 as long as the test condition evaluates to true. The condition is evaluated before
 executing the statement.

Try it
------

Syntax
------

```js
while (condition)
  statement
```

`condition`

 An expression evaluated before each pass through the loop. If this condition
 evaluates to true, `statement` is executed. When condition
 evaluates to false, execution continues with the statement after the
 `while` loop.

`statement`

 An optional statement that is executed as long as the condition evaluates to true.
 To execute multiple statements within the loop, use a block statement
 (`{ /* ... */ }`) to group those statements.

 Note: Use the `break` statement to stop a loop before `condition` evaluates
 to true.

Examples
--------

### Using while

 The following `while` loop iterates as long as `n` is less than
 three.

```js
let n = 0;
let x = 0;

while (n < 3) {
  n++;
  x += n;
}
```

 Each iteration, the loop increments `n` and adds it to `x`.
 Therefore, `x` and `n` take on the following values:

* After the first pass: `n` = 1 and `x` = 1
* After the second pass: `n` = 2 and `x` = 3
* After the third pass: `n` = 3 and `x` = 6

 After completing the third pass, the condition `n` < 3 is no longer true,
 so the loop terminates.

### Using an assignment as a condition

In some cases, it can make sense to use an assignment as a condition. This comes with readability tradeoffs, so there are certain stylistic recommendations that would make the pattern more obvious for everyone.

Consider the following example, which iterates over a document's comments, logging them to the console.

```js
const iterator = document.createNodeIterator(document, NodeFilter.SHOW\_COMMENT);
let currentNode;
while (currentNode = iterator.nextNode()) {
  console.log(currentNode.textContent.trim());
}
```

That's not completely a good-practice example, due to the following line specifically:

```js
while (currentNode = iterator.nextNode()) {
```

The *effect* of that line is fine — in that, each time a comment node is found:

1. `iterator.nextNode()` returns that comment node, which gets assigned to `currentNode`.
2. The value of `currentNode = iterator.nextNode()` is therefore truthy.
3. So the `console.log()` call executes and the loop continues.

…and then, when there are no more comment nodes in the document:

1. `iterator.nextNode()` returns `null`.
2. The value of `currentNode = iterator.nextNode()` is therefore also `null`, which is falsy.
3. So the loop ends.

The problem with this line is: conditions typically use comparison operators such as `===`, but the `=` in that line isn't a comparison operator — instead, it's an assignment operator. So that `=` *looks like* it's a typo for `===` — even though it's *not* actually a typo.

Therefore, in cases like that one, some code-linting tools such as ESLint's `no-cond-assign` rule — in order to help you catch a possible typo so that you can fix it — will report a warning such as the following:

>
> Expected a conditional expression and instead saw an assignment.
>
>
>

Many style guides recommend more explicitly indicating the intention for the condition to be an assignment. You can do that minimally by putting additional parentheses as a grouping operator around the assignment:

```js
const iterator = document.createNodeIterator(document, NodeFilter.SHOW\_COMMENT);
let currentNode;
while ((currentNode = iterator.nextNode())) {
  console.log(currentNode.textContent.trim());
}
```

In fact, this is the style enforced by ESLint's `no-cond-assign`'s default configuration, as well as Prettier, so you'll likely see this pattern a lot in the wild.

Some people may further recommend adding a comparison operator to turn the condition into an explicit comparison:

```js
while ((currentNode = iterator.nextNode()) !== null) {
```

There are other ways to write this pattern, such as:

```js
while ((currentNode = iterator.nextNode()) && currentNode) {
```

Or, forgoing the idea of using a `while` loop altogether:

```js
const iterator = document.createNodeIterator(document, NodeFilter.SHOW\_COMMENT);
for (
  let currentNode = iterator.nextNode();
  currentNode;
  currentNode = iterator.nextNode()
) {
  console.log(currentNode.textContent.trim());
}
```

If the reader is sufficiently familiar with the assignment as condition pattern, all these variations should have equivalent readability. Otherwise, the last form is probably the most readable, albeit the most verbose.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-while-statement |

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

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

See also
--------

* `do...while`
* `for`
* `break`
* `continue`


import - JavaScript

import
======

The static **`import`** declaration is used to import read-only live bindings which are exported by another module. The imported bindings are called *live bindings* because they are updated by the module that exported the binding, but cannot be re-assigned by the importing module.

In order to use the `import` declaration in a source file, the file must be interpreted by the runtime as a module. In HTML, this is done by adding `type="module"` to the `<script>` tag. Modules are automatically interpreted in strict mode.

There is also a function-like dynamic `import()`, which does not require scripts of `type="module"`.

Syntax
------

```js
import defaultExport from "module-name";
import \* as name from "module-name";
import { export1 } from "module-name";
import { export1 as alias1 } from "module-name";
import { default as alias } from "module-name";
import { export1, export2 } from "module-name";
import { export1, export2 as alias2, /\* … \*/ } from "module-name";
import { "string name" as alias } from "module-name";
import defaultExport, { export1, /\* … \*/ } from "module-name";
import defaultExport, \* as name from "module-name";
import "module-name";
```

`defaultExport`

Name that will refer to the default export from the module. Must be a valid JavaScript identifier.

`module-name`

The module to import from. The evaluation of the specifier is host-specified. This is often a relative or absolute URL to the `.js` file containing the module. In Node, extension-less imports often refer to packages in `node_modules`. Certain bundlers may permit importing files without extensions; check your environment. Only single quoted and double quoted Strings are allowed.

`name`

Name of the module object that will be used as a kind of namespace when referring to the imports. Must be a valid JavaScript identifier.

`exportN`

Name of the exports to be imported. The name can be either an identifier or a string literal, depending on what `module-name` declares to export. If it is a string literal, it must be aliased to a valid identifier.

`aliasN`

Names that will refer to the named imports. Must be a valid JavaScript identifier.

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

`import` declarations can only be present in modules, and only at the top-level (i.e. not inside blocks, functions, etc.). If an `import` declaration is encountered in non-module contexts (for example, `<script>` tags without `type="module"`, `eval`, `new Function`, which all have "script" or "function body" as parsing goals), a `SyntaxError` is thrown. To load modules in non-module contexts, use the dynamic import syntax instead.

All imported bindings cannot be in the same scope as any other declaration, including `let`, `const`, `class`, `function`, `var`, and `import` declaration.

`import` declarations are designed to be syntactically rigid (for example, only string literal specifiers, only permitted at the top-level, all bindings must be identifiers), which allows modules to be statically analyzed and linked before getting evaluated. This is the key to making modules asynchronous by nature, powering features like top-level await.

### Forms of import declarations

There are four forms of `import` declarations:

* Named import: `import { export1, export2 } from "module-name";`
* Default import: `import defaultExport from "module-name";`
* Namespace import: `import * as name from "module-name";`
* Side effect import: `import "module-name";`

Below are examples to clarify the syntax.

#### Named import

Given a value named `myExport` which has been exported from the module `my-module` either implicitly as `export * from "another.js"` or explicitly using the `export` statement, this inserts `myExport` into the current scope.

```js
import { myExport } from "/modules/my-module.js";
```

You can import multiple names from the same module.

```js
import { foo, bar } from "/modules/my-module.js";
```

You can rename an export when importing it. For example, this inserts `shortName` into the current scope.

```js
import { reallyReallyLongModuleExportName as shortName } from "/modules/my-module.js";
```

A module may also export a member as a string literal which is not a valid identifier, in which case you must alias it in order to use it in the current module.

```js
// /modules/my-module.js
const a = 1;
export { a as "a-b" };
```

```js
import { "a-b" as a } from "/modules/my-module.js";
```

**Note:** `import { x, y } from "mod"` is not equivalent to `import defaultExport from "mod"` and then destructuring `x` and `y` from `defaultExport`. Named and default imports are distinct syntaxes in JavaScript modules.

#### Default import

Default exports need to be imported with the corresponding default import syntax. The simplest version directly imports the default:

```js
import myDefault from "/modules/my-module.js";
```

Since the default export doesn't explicitly specify a name, you can give the identifier any name you like.

It is also possible to specify a default import with namespace imports or named imports. In such cases, the default import will have to be declared first. For instance:

```js
import myDefault, \* as myModule from "/modules/my-module.js";
// myModule.default and myDefault point to the same binding
```

or

```js
import myDefault, { foo, bar } from "/modules/my-module.js";
```

Importing a name called `default` has the same effect as a default import. It is necessary to alias the name because `default` is a reserved word.

```js
import { default as myDefault } from "/modules/my-module.js";
```

#### Namespace import

The following code inserts `myModule` into the current scope, containing all the exports from the module located at `/modules/my-module.js`.

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

Here, `myModule` represents a *namespace* object which contains all exports as properties. For example, if the module imported above includes an export `doAllTheAmazingThings()`, you would call it like this:

```js
myModule.doAllTheAmazingThings();
```

`myModule` is a sealed object with `null` prototype. The default export available as a key called `default`. For more information, see module namespace object.

**Note:** JavaScript does not have wildcard imports like `import * from "module-name"`, because of the high possibility of name conflicts.

#### Import a module for its side effects only

 Import an entire module for side effects only, without importing anything. This runs
 the module's global code, but doesn't actually import any values.

```js
import "/modules/my-module.js";
```

This is often used for polyfills, which mutate the global variables.

### Hoisting

Import declarations are hoisted. In this case, that means that the identifiers the imports introduce are available in the entire module scope, and their side effects are produced before the rest of the module's code runs.

```js
myModule.doAllTheAmazingThings(); // myModule.doAllTheAmazingThings is imported by the next line

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

Examples
--------

### Standard Import

In this example, we create a re-usable module that exports a function to get all primes within a given range.

```js
// getPrimes.js
/\*\*
 \* Returns a list of prime numbers that are smaller than `max`.
 \*/
export function getPrimes(max) {
  const isPrime = Array.from({ length: max }, () => true);
  isPrime[0] = isPrime[1] = false;
  isPrime[2] = true;
  for (let i = 2; i \* i < max; i++) {
    if (isPrime[i]) {
      for (let j = i \*\* 2; j < max; j += i) {
        isPrime[j] = false;
      }
    }
  }
  return [...isPrime.entries()]
    .filter(([, isPrime]) => isPrime)
    .map(([number]) => number);
}
```

```js
import { getPrimes } from "/modules/getPrimes.js";

console.log(getPrimes(10)); // [2, 3, 5, 7]
```

### Imported values can only be modified by the exporter

The identifier being imported is a *live binding*, because the module exporting it may re-assign it and the imported value would change. However, the module importing it cannot re-assign it. Still, any module holding an exported object can mutate the object, and the mutated value can be observed by all other modules importing the same value.

You can also observe the new value through the module namespace object.

```js
// my-module.js
export let myValue = 1;
setTimeout(() => {
  myValue = 2;
}, 500);
```

```js
// main.js
import { myValue } from "/modules/my-module.js";
import \* as myModule from "/modules/my-module.js";

console.log(myValue); // 1
console.log(myModule.myValue); // 1
setTimeout(() => {
  console.log(myValue); // 2; my-module has updated its value
  console.log(myModule.myValue); // 2
  myValue = 3; // TypeError: Assignment to constant variable.
  // The importing module can only read the value but can't re-assign it.
}, 1000);
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-imports |

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

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

See also
--------

* `export`
* `import()`
* `import.meta`
* Previewing ES6 Modules and more from ES2015, ES2016 and beyond on blogs.windows.com (2016)
* ES6 in Depth: Modules on hacks.mozilla.org (2015)
* ES modules: A cartoon deep-dive on hacks.mozilla.org (2018)
* Exploring JS, Ch.16: Modules by Dr. Axel Rauschmayer
* Export and Import on javascript.info


break - JavaScript

break
=====

The **`break`** statement terminates the current loop or `switch` statement and transfers program control to the statement following the terminated statement. It can also be used to jump past a labeled statement when used within that labeled statement.

Try it
------

Syntax
------

```js
break;
break label;
```

`label` Optional

Identifier associated with the label of the statement to break to. If the `break` statement is not nested within a loop or `switch`, then the label identifier is required.

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

When `break;` is encountered, the program breaks out of the innermost `switch` or looping statement and continues executing the next statement after that.

When `break label;` is encountered, the program breaks out of the statement labeled with `label` and continues executing the next statement after that. The `break` statement needs to be nested within the referenced label. The labeled statement can be any statement (commonly a block statement); it does not have to be another loop statement.

A `break` statement, with or without a following label, cannot be used at the top level of a script, module, function's body, or static initialization block, even when the function or class is further contained within a loop.

Examples
--------

### break in while loop

The following function has a `break` statement that terminates the `while` loop when `i` is 3, and then returns the value `3 * x`.

```js
function testBreak(x) {
  let i = 0;

  while (i < 6) {
    if (i === 3) {
      break;
    }
    i += 1;
  }

  return i \* x;
}
```

### break in switch statements

The following code has a `break` statement that terminates the `switch` statement when a case is matched and the corresponding code has run.

```js
const food = "sushi";

switch (food) {
  case "sushi":
    console.log("Sushi is originally from Japan.");
    break;
  case "pizza":
    console.log("Pizza is originally from Italy.");
    break;
  default:
    console.log("I have never heard of that dish.");
    break;
}
```

### break in labeled blocks

The following code uses `break` statements with labeled blocks. By using `break outerBlock`, control is transferred to the end of the block statement marked as `outerBlock`.

```js
outerBlock: {
  innerBlock: {
    console.log("1");
    break outerBlock; // breaks out of both innerBlock and outerBlock
    console.log(":-("); // skipped
  }
  console.log("2"); // skipped
}
```

### Unsyntactic break statements

A `break` statement must be nested within any label it references. The following code also uses `break` statements with labeled blocks, but generates a syntax error because its `break` statement references `block2` but it's not nested within `block2`.

```js
block1: {
  console.log("1");
  break block2; // SyntaxError: label not found
}

block2: {
  console.log("2");
}
```

Syntax errors are also generated in the following code examples which use `break` statements within functions that are nested within a loop, or labeled block that the `break` statements are intended to break out of.

```js
function testBreak(x) {
  let i = 0;

  while (i < 6) {
    if (i === 3) {
      (() => {
        break;
      })();
    }
    i += 1;
  }

  return i \* x;
}

testBreak(1); // SyntaxError: Illegal break statement
```

```js
block1: {
  console.log("1");
  (() => {
    break block1; // SyntaxError: Undefined label 'block1'
  })();
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-break-statement |

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

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

See also
--------

* `continue`
* label
* `switch`


Block statement - JavaScript

Block statement
===============

A **block statement** is used to group zero or more statements. The block is delimited by a pair of braces ("curly braces") and contains a list of zero or more statements and declarations.

Try it
------

Syntax
------

```js
{
  StatementList
}
```

`StatementList`

Statements and declarations grouped within the block statement.

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

The block statement is often called the *compound statement* in other languages. It allows you to use multiple statements where JavaScript expects only one statement. Combining statements into blocks is a common practice in JavaScript, especially when used in association with control flow statements like `if...else` and `for`. The opposite behavior is possible using an empty statement, where you provide no statement, although one is required.

In addition, combined with block-scoped declarations like `let`, `const`, and `class`, blocks can prevent temporary variables from polluting the global namespace, just like IIFEs do.

### Block scoping rules with var or function declaration in non-strict mode

Variables declared with `var` or created by function declarations in non-strict mode **do not** have block scope. Variables introduced within a block are scoped to the containing function or script, and the effects of setting them persist beyond the block itself. For example:

```js
var x = 1;
{
  var x = 2;
}
console.log(x); // 2
```

This logs 2 because the `var x` statement within the block is in the same scope as the `var x` statement before the block.

In non-strict code, function declarations inside blocks behave strangely. Do not use them.

### Block scoping rules with let, const, class, or function declaration in strict mode

By contrast, identifiers declared with `let`, `const`, and `class` do have block scope:

```js
let x = 1;
{
  let x = 2;
}
console.log(x); // 1
```

The `x = 2` is limited in scope to the block in which it was defined.

The same is true of `const`:

```js
const c = 1;
{
  const c = 2;
}
console.log(c); // 1; does not throw SyntaxError
```

Note that the block-scoped `const c = 2` *does not* throw a `SyntaxError: Identifier 'c' has already been declared` because it can be declared uniquely within the block.

In strict mode, function declarations inside blocks are scoped to that block and are hoisted to the top of the block.

```js
"use strict";

{
  foo(); // Logs "foo"
  function foo() {
    console.log("foo");
  }
}

foo(); // ReferenceError: foo is not defined
```

Examples
--------

### Using a block statement as the body of a for loop

A `for` loop accepts a single statement as its body.

```js
for (let i = 0; i < 10; i++) console.log(i);
```

If you want to use more than one statement in the loop body, you can group them into one block statement:

```js
for (let i = 0; i < 10; i++) {
  console.log(i);
  console.log(i \*\* 2);
}
```

### Using a block statement to encapsulate data

`let` and `const` declarations are scoped to the containing block. This allows you to hide data from the global scope without wrapping it in a function.

```js
let sector;
{
  // These variables are scoped to this block and are not
  // accessible after the block
  const angle = Math.PI / 3;
  const radius = 10;
  sector = {
    radius,
    angle,
    area: (angle / 2) \* radius \*\* 2,
    perimeter: 2 \* radius + angle \* radius,
  };
}
console.log(sector);
// {
// radius: 10,
// angle: 1.0471975511965976,
// area: 52.35987755982988,
// perimeter: 30.471975511965976
// }
console.log(typeof radius); // "undefined"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-block |

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

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

See also
--------

* `while`
* `if...else`
* `let`


if...else - JavaScript

if...else
=========

The **`if...else`** statement executes a statement if a specified condition is truthy. If the condition is falsy, another statement in the optional `else` clause will be executed.

Try it
------

Syntax
------

```js
if (condition)
  statement1

// With an else clause
if (condition)
  statement1
else
  statement2
```

`condition`

An expression that is considered to be either truthy or falsy.

`statement1`

Statement that is executed if *condition* is truthy. Can be any statement, including further nested `if` statements. To execute multiple statements, use a block statement (`{ /* ... */ }`) to group those statements. To execute no statements, use an empty statement.

`statement2`

Statement that is executed if `condition` is falsy and the `else` clause exists. Can be any statement, including block statements and further nested `if` statements.

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

Multiple `if...else` statements can be nested to create an `else if` clause. Note that there is no `elseif` (in one word) keyword in JavaScript.

```js
if (condition1)
  statement1
else if (condition2)
  statement2
else if (condition3)
  statement3
// …
else
  statementN
```

To see how this works, this is how it would look if the nesting were properly indented:

```js
if (condition1)
  statement1
else
  if (condition2)
    statement2
  else
    if (condition3)
      statement3
// …
```

To execute multiple statements within a clause, use a block statement (`{ /* ... */ }`) to group those statements.

```js
if (condition) {
  statements1
} else {
  statements2
}
```

Not using blocks may lead to confusing behavior, especially if the code is hand-formatted. For example:

```js
function checkValue(a, b) {
  if (a === 1)
    if (b === 2)
      console.log("a is 1 and b is 2");
  else
    console.log("a is not 1");
}
```

This code looks innocent — however, executing `checkValue(1, 3)` will log "a is not 1". This is because in the case of dangling else, the `else` clause will be connected to the closest `if` clause. Therefore, the code above, with proper indentation, would look like:

```js
function checkValue(a, b) {
  if (a === 1)
    if (b === 2)
      console.log("a is 1 and b is 2");
    else
      console.log("a is not 1");
}
```

In general, it is a good practice to always use block statements, especially in code involving nested `if` statements.

```js
function checkValue(a, b) {
  if (a === 1) {
    if (b === 2) {
      console.log("a is 1 and b is 2");
    }
  } else {
    console.log("a is not 1");
  }
}
```

Do not confuse the primitive Boolean values `true` and `false` with truthiness or falsiness of the `Boolean` object. Any value that is not `false`, `undefined`, `null`, `0`, `-0`, `NaN`, or the empty string (`""`), and any object, including a Boolean object whose value is `false`, is considered truthy when used as the condition. For example:

```js
const b = new Boolean(false);
if (b) {
  console.log("b is truthy"); // "b is truthy"
}
```

Examples
--------

### Using if...else

```js
if (cipherChar === fromChar) {
  result += toChar;
  x++;
} else {
  result += clearChar;
}
```

### Using else if

Note that there is no `elseif` syntax in JavaScript. However, you can write it with a space between `else` and `if`:

```js
if (x > 50) {
  /\* do something \*/
} else if (x > 5) {
  /\* do something \*/
} else {
  /\* do something \*/
}
```

### Using an assignment as a condition

You should almost never have an `if...else` with an assignment like `x = y` as a condition:

```js
if ((x = y)) {
  // …
}
```

Because unlike `while` loops, the condition is only evaluated once, so the assignment is only performed once. The code above is equivalent to:

```js
x = y;
if (x) {
  // …
}
```

Which is much clearer. However, in the rare case you find yourself wanting to do something like that, the `while` documentation has a Using an assignment as a condition section with our recommendations.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-if-statement |

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

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

See also
--------

* `block`
* `switch`
* Conditional (ternary) operator


debugger - JavaScript

debugger
========

 The **`debugger`** statement invokes any available debugging
 functionality, such as setting a breakpoint. If no debugging functionality is available,
 this statement has no effect.

Syntax
------

```js
debugger;
```

Examples
--------

### Using the debugger statement

 The following example shows code where a `debugger` statement has been
 inserted, to invoke a debugger (if one exists) when the function is called.

```js
function potentiallyBuggyCode() {
  debugger;
  // do potentially buggy stuff to examine, step through, etc.
}
```

 When the debugger is invoked, execution is paused at the `debugger`
 statement. It is like a breakpoint in the script source.

![A browser with developer tools open to the debugger panel showing how execution is paused at the debugger statement to allow close inspection of variables, scopes, events, etc.](/en-US/docs/Web/JavaScript/Reference/Statements/debugger/screen_shot_2014-02-07_at_9.14.35_am.png)

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-debugger-statement |

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

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

See also
--------

* The Firefox JavaScript Debugger¶ in the Firefox source docs


let - JavaScript

let
===

The **`let`** declaration declares re-assignable, block-scoped local variables, optionally initializing each to a value.

Try it
------

Syntax
------

```js
let name1;
let name1 = value1;
let name1 = value1, name2 = value2;
let name1, name2 = value2;
let name1 = value1, name2, /\* …, \*/ nameN = valueN;
```

### Parameters

`nameN`

The name of the variable to declare. Each must be a legal JavaScript identifier or a destructuring binding pattern.

`valueN` Optional

Initial value of the variable. It can be any legal expression. Default value is `undefined`.

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

The scope of a variable declared with `let` is one of the following curly-brace-enclosed syntaxes that most closely contains the `let` declaration:

* Block statement
* `switch` statement
* `try...catch` statement
* Body of one of the `for` statements, if the `let` is in the header of the statement
* Function body
* Static initialization block

Or if none of the above applies:

* The current module, for code running in module mode
* The global scope, for code running in script mode.

Compared with `var`, `let` declarations have the following differences:

* `let` declarations are scoped to blocks as well as functions.
* `let` declarations can only be accessed after the place of declaration is reached (see temporal dead zone). For this reason, `let` declarations are commonly regarded as non-hoisted.
* `let` declarations do not create properties on `globalThis` when declared at the top level of a script.
* `let` declarations cannot be redeclared by any other declaration in the same scope.
* `let` begins *declarations*, not *statements*. That means you cannot use a lone `let` declaration as the body of a block (which makes sense, since there's no way to access the variable).

```js
if (true) let a = 1; // SyntaxError: Lexical declaration cannot appear in a single-statement context
```

Note that `let` is allowed as an identifier name when declared with `var` or `function` in non-strict mode, but you should avoid using `let` as an identifier name to prevent unexpected syntax ambiguities.

Many style guides (including MDN's) recommend using `const` over `let` whenever a variable is not reassigned in its scope. This makes the intent clear that a variable's type (or value, in the case of a primitive) can never change. Others may prefer `let` for non-primitives that are mutated.

The list that follows the `let` keyword is called a *binding list* and is separated by commas, where the commas are *not* comma operators and the `=` signs are *not* assignment operators. Initializers of later variables can refer to earlier variables in the list.

### Temporal dead zone (TDZ)

A variable declared with `let`, `const`, or `class` is said to be in a "temporal dead zone" (TDZ) from the start of the block until code execution reaches the place where the variable is declared and initialized.

While inside the TDZ, the variable has not been initialized with a value, and any attempt to access it will result in a `ReferenceError`. The variable is initialized with a value when execution reaches the place in the code where it was declared. If no initial value was specified with the variable declaration, it will be initialized with a value of `undefined`.

This differs from `var` variables, which will return a value of `undefined` if they are accessed before they are declared. The code below demonstrates the different result when `let` and `var` are accessed in code before the place where they are declared.

```js
{
  // TDZ starts at beginning of scope
  console.log(bar); // "undefined"
  console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
  var bar = 1;
  let foo = 2; // End of TDZ (for foo)
}
```

The term "temporal" is used because the zone depends on the order of execution (time) rather than the order in which the code is written (position). For example, the code below works because, even though the function that uses the `let` variable appears before the variable is declared, the function is *called* outside the TDZ.

```js
{
  // TDZ starts at beginning of scope
  const func = () => console.log(letVar); // OK

  // Within the TDZ letVar access throws `ReferenceError`

  let letVar = 3; // End of TDZ (for letVar)
  func(); // Called outside TDZ!
}
```

Using the `typeof` operator for a `let` variable in its TDZ will throw a `ReferenceError`:

```js
typeof i; // ReferenceError: Cannot access 'i' before initialization
let i = 10;
```

This differs from using `typeof` for undeclared variables, and variables that hold a value of `undefined`:

```js
console.log(typeof undeclaredVariable); // "undefined"
```

**Note:** `let` and `const` declarations are only processed when the current script gets processed. If you have two `<script>` elements running in script mode within one HTML, the first script is not subject to the TDZ restrictions for top-level `let` or `const` variables declared in the second script, although if you declare a `let` or `const` variable in the first script, declaring it again in the second script will cause a redeclaration error.

### Redeclarations

`let` declarations cannot be in the same scope as any other declaration, including `let`, `const`, `class`, `function`, `var`, and `import` declaration.

```js
{
  let foo;
  let foo; // SyntaxError: Identifier 'foo' has already been declared
}
```

A `let` declaration within a function's body cannot have the same name as a parameter. A `let` declaration within a `catch` block cannot have the same name as the `catch`-bound identifier.

```js
function foo(a) {
  let a = 1; // SyntaxError: Identifier 'a' has already been declared
}
try {
} catch (e) {
  let e; // SyntaxError: Identifier 'e' has already been declared
}
```

If you're experimenting in a REPL, such as the Firefox web console (**Tools** > **Web Developer** > **Web Console**), and you run two `let` declarations with the same name in two separate inputs, you may get the same re-declaration error. See further discussion of this issue in Firefox bug 1580891. The Chrome console allows `let` re-declarations between different REPL inputs.

You may encounter errors in `switch` statements because there is only one block.

```js
let x = 1;

switch (x) {
  case 0:
    let foo;
    break;
  case 1:
    let foo; // SyntaxError: Identifier 'foo' has already been declared
    break;
}
```

To avoid the error, wrap each `case` in a new block statement.

```js
let x = 1;

switch (x) {
  case 0: {
    let foo;
    break;
  }
  case 1: {
    let foo;
    break;
  }
}
```

Examples
--------

### Scoping rules

Variables declared by `let` have their scope in the block for which they are declared, as well as in any contained sub-blocks. In this way, `let` works very much like `var`. The main difference is that the scope of a `var` variable is the entire enclosing function:

```js
function varTest() {
  var x = 1;
  {
    var x = 2; // same variable!
    console.log(x); // 2
  }
  console.log(x); // 2
}

function letTest() {
  let x = 1;
  {
    let x = 2; // different variable
    console.log(x); // 2
  }
  console.log(x); // 1
}
```

At the top level of programs and functions, `let`, unlike `var`, does not create a property on the global object. For example:

```js
var x = "global";
let y = "global";
console.log(this.x); // "global"
console.log(this.y); // undefined
```

### TDZ combined with lexical scoping

The following code results in a `ReferenceError` at the line shown:

```js
function test() {
  var foo = 33;
  if (foo) {
    let foo = foo + 55; // ReferenceError
  }
}
test();
```

The `if` block is evaluated because the outer `var foo` has a value. However due to lexical scoping this value is not available inside the block: the identifier `foo` *inside* the `if` block is the `let foo`. The expression `foo + 55` throws a `ReferenceError` because initialization of `let foo` has not completed — it is still in the temporal dead zone.

This phenomenon can be confusing in a situation like the following. The instruction `let n of n.a` is already inside the scope of the `for...of` loop's block. So, the identifier `n.a` is resolved to the property `a` of the `n` object located in the first part of the instruction itself (`let n`). This is still in the temporal dead zone as its declaration statement has not been reached and terminated.

```js
function go(n) {
  // n here is defined!
  console.log(n); // { a: [1, 2, 3] }

  for (let n of n.a) {
    // ^ ReferenceError
    console.log(n);
  }
}

go({ a: [1, 2, 3] });
```

### Other situations

When used inside a block, `let` limits the variable's scope to that block. Note the difference between `var`, whose scope is inside the function where it is declared.

```js
var a = 1;
var b = 2;

{
  var a = 11; // the scope is global
  let b = 22; // the scope is inside the block

  console.log(a); // 11
  console.log(b); // 22
}

console.log(a); // 11
console.log(b); // 2
```

However, this combination of `var` and `let` declarations below is a `SyntaxError` because `var` not being block-scoped, leading to them being in the same scope. This results in an implicit re-declaration of the variable.

```js
let x = 1;

{
  var x = 2; // SyntaxError for re-declaration
}
```

### Declaration with destructuring

The left-hand side of each `=` can also be a binding pattern. This allows creating multiple variables at once.

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

For more information, see Destructuring assignment.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-let-and-const-declarations |

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

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

See also
--------

* `var`
* `const`
* Hoisting
* ES6 In Depth: `let` and `const` on hacks.mozilla.org (2015)
* Breaking changes in `let` and `const` in Firefox 44 on blog.mozilla.org (2015)
* You Don't Know JS: Scope & Closures, Ch.3: Function vs. Block Scope by Kyle Simpson
* What is the Temporal Dead Zone? on Stack Overflow
* What is the difference between using `let` and `var`? on Stack Overflow
* Why was the name 'let' chosen for block-scoped variable declarations in JavaScript? on Stack Overflow


throw - JavaScript

throw
=====

The **`throw`** statement throws a user-defined exception. Execution of the current function will stop (the statements after `throw` won't be executed), and control will be passed to the first `catch` block in the call stack. If no `catch` block exists among caller functions, the program will terminate.

Try it
------

Syntax
------

```js
throw expression;
```

`expression`

The expression to throw.

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

The `throw` statement is valid in all contexts where statements can be used. Its execution generates an exception that penetrates through the call stack. For more information on error bubbling and handling, see Control flow and error handling.

The `throw` keyword can be followed by any kind of expression, for example:

```js
throw error; // Throws a previously defined value (e.g. within a catch block)
throw new Error("Required"); // Throws a new Error object
```

In practice, the exception you throw should *always* be an `Error` object or an instance of an `Error` subclass, such as `RangeError`. This is because code that catches the error may expect certain properties, such as `message`, to be present on the caught value. For example, web APIs typically throw `DOMException` instances, which inherit from `Error.prototype`.

### Automatic semicolon insertion

The syntax forbids line terminators between the `throw` keyword and the expression to be thrown.

```js
throw
new Error();
```

The code above is transformed by automatic semicolon insertion (ASI) into:

```js
throw;
new Error();
```

This is invalid code, because unlike `return`, `throw` must be followed by an expression.

To avoid this problem (to prevent ASI), you could use parentheses:

```js
throw (
  new Error()
);
```

Examples
--------

### Throwing a user-defined error

This example defines a function that throws a `TypeError` if the input is not of the expected type.

```js
function isNumeric(x) {
  return ["number", "bigint"].includes(typeof x);
}

function sum(...values) {
  if (!values.every(isNumeric)) {
    throw new TypeError("Can only add numbers");
  }
  return values.reduce((a, b) => a + b);
}

console.log(sum(1, 2, 3)); // 6
try {
  sum("1", "2");
} catch (e) {
  console.error(e); // TypeError: Can only add numbers
}
```

### Throwing an existing object

This example calls a callback-based async function, and throws an error if the callback receives an error.

```js
readFile("foo.txt", (err, data) => {
  if (err) {
    throw err;
  }
  console.log(data);
});
```

Errors thrown this way are not catchable by the caller and will cause the program to crash unless (a) the `readFile` function itself catches the error, or (b) the program is running in a context that catches top-level errors. You can handle errors more naturally by using the `Promise()` constructor.

```js
function readFilePromise(path) {
  return new Promise((resolve, reject) => {
    readFile(path, (err, data) => {
      if (err) {
        reject(err);
      }
      resolve(data);
    });
  });
}

try {
  const data = await readFilePromise("foo.txt");
  console.log(data);
} catch (err) {
  console.error(err);
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-throw-statement |

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

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

See also
--------

* `try...catch`
* `Error`


for await...of - JavaScript

for await...of
==============

The **`for await...of`** statement creates a loop iterating over async iterable objects as well as sync iterables. This statement can only be used in contexts where `await` can be used, which includes inside an async function body and in a module.

Try it
------

Syntax
------

```js
for await (variable of iterable)
  statement
```

`variable`

Receives a value from the sequence on each iteration. May be either a declaration with `const`, `let`, or `var`, or an assignment target (e.g. a previously declared variable, an object property, or a destructuring assignment pattern). Variables declared with `var` are not local to the loop, i.e. they are in the same scope the `for await...of` loop is in.

`iterable`

An async iterable or sync iterable. The source of the sequence of values on which the loop operates.

`statement`

A statement to be executed on every iteration. May reference `variable`. You can use a block statement to execute multiple statements.

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

When a `for await...of` loop iterates over an iterable, it first gets the iterable's `[@@asyncIterator]()` method and calls it, which returns an async iterator. If the `@asyncIterator` method does not exist, it then looks for an `[@@iterator]()` method, which returns a sync iterator. The sync iterator returned is then wrapped into an async iterator by wrapping every object returned from the `next()`, `return()`, and `throw()` methods into a resolved or rejected promise, with the `value` property resolved if it's also a promise. The loop then repeatedly calls the final async iterator's `next()` method and awaits the returned promise, producing the sequence of values to be assigned to `variable`.

If the `for await...of` loop exited early (e.g. a `break` statement is encountered or an error is thrown), the `return()` method of the iterator is called to perform any cleanup. The returned promise is awaited before the loop exits.

`for await...of` generally functions the same as the `for...of` loop and shares many of the same syntax and semantics. There are a few differences:

* `for await...of` works on both sync and async iterables, while `for...of` only works on sync iterables.
* `for await...of` can only be used in contexts where `await` can be used, which includes inside an async function body and in a module. Even when the iterable is sync, the loop still awaits the return value for every iteration, leading to slower execution due to repeated promise unwrapping.
* If the `iterable` is a sync iterable that yields promises, `for await...of` would produce a sequence of resolved values, while `for...of` would produce a sequence of promises. (However, beware of error handling and cleanup — see Iterating over sync iterables and generators)
* For `for await...of`, the `variable` can be the identifier `async` (e.g. `for await (async of foo)`); `for...of` forbids this case.
Examples
--------

### Iterating over async iterables

You can also iterate over an object that explicitly implements async iterable protocol:

```js
const LIMIT = 3;

const asyncIterable = {
  [Symbol.asyncIterator]() {
    let i = 0;
    return {
      next() {
        const done = i === LIMIT;
        const value = done ? undefined : i++;
        return Promise.resolve({ value, done });
      },
      return() {
        // This will be reached if the consumer called 'break' or 'return' early in the loop.
        return { done: true };
      },
    };
  },
};

(async () => {
  for await (const num of asyncIterable) {
    console.log(num);
  }
})();
// 0
// 1
// 2
```

### Iterating over async generators

 Since the return values of async generator functions conform to the async iterable protocol,
 they can be looped using `for await...of`.

```js
async function\* asyncGenerator() {
  let i = 0;
  while (i < 3) {
    yield i++;
  }
}

(async () => {
  for await (const num of asyncGenerator()) {
    console.log(num);
  }
})();
// 0
// 1
// 2
```

For a more concrete example of iterating over an async generator using `for await...of`, consider iterating over data from an API.

This example first creates an async iterable for a stream of data, then uses it to find the size of the response from the API.

```js
async function\* streamAsyncIterable(stream) {
  const reader = stream.getReader();
  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done) return;
      yield value;
    }
  } finally {
    reader.releaseLock();
  }
}

// Fetches data from URL and calculates response size using the async generator.
async function getResponseSize(url) {
  const response = await fetch(url);
  // Will hold the size of the response, in bytes.
  let responseSize = 0;
  // The for-await-of loop. Async iterates over each portion of the response.
  for await (const chunk of streamAsyncIterable(response.body)) {
    // Incrementing the total response length.
    responseSize += chunk.length;
  }

  console.log(`Response Size: ${responseSize} bytes`); // "Response Size: 1071472"
  return responseSize;
}
getResponseSize("https://jsonplaceholder.typicode.com/photos");
```

### Iterating over sync iterables and generators

`for await...of` loop also consumes sync iterables and generators. In that case it internally awaits emitted values before assign them to the loop control variable.

```js
function\* generator() {
  yield 0;
  yield 1;
  yield Promise.resolve(2);
  yield Promise.resolve(3);
  yield 4;
}

(async () => {
  for await (const num of generator()) {
    console.log(num);
  }
})();
// 0
// 1
// 2
// 3
// 4

// compare with for-of loop:

for (const numOrPromise of generator()) {
  console.log(numOrPromise);
}
// 0
// 1
// Promise { 2 }
// Promise { 3 }
// 4
```

**Note:** Be aware of yielding rejected promises from a sync generator. In such case, `for await...of` throws when consuming the rejected promise and DOESN'T CALL `finally` blocks within that generator. This can be undesirable if you need to free some allocated resources with `try/finally`.

```js
function\* generatorWithRejectedPromises() {
  try {
    yield 0;
    yield 1;
    yield Promise.resolve(2);
    yield Promise.reject(3);
    yield 4;
    throw 5;
  } finally {
    console.log("called finally");
  }
}

(async () => {
  try {
    for await (const num of generatorWithRejectedPromises()) {
      console.log(num);
    }
  } catch (e) {
    console.log("caught", e);
  }
})();
// 0
// 1
// 2
// caught 3

// compare with for-of loop:

try {
  for (const numOrPromise of generatorWithRejectedPromises()) {
    console.log(numOrPromise);
  }
} catch (e) {
  console.log("caught", e);
}
// 0
// 1
// Promise { 2 }
// Promise { <rejected> 3 }
// 4
// caught 5
// called finally
```

To make `finally` blocks of a sync generator always called, use the appropriate form of the loop — `for await...of` for the async generator and `for...of` for the sync one — and await yielded promises explicitly inside the loop.

```js
(async () => {
  try {
    for (const numOrPromise of generatorWithRejectedPromises()) {
      console.log(await numOrPromise);
    }
  } catch (e) {
    console.log("caught", e);
  }
})();
// 0
// 1
// 2
// caught 3
// called finally
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-for-in-and-for-of-statements |

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

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

See also
--------

* `Symbol.asyncIterator`
* `for...of`