Classes - JavaScript

Classes
=======

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
Classes are a template for creating objects. They encapsulate data with code to work on that data. Classes in JS are built on prototypes but also have some syntax and semantics that are unique to classes.

For more examples and explanations, see the Using classes guide.

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

### Defining classes

Classes are in fact "special functions", and just as you can define function expressions and function declarations, a class can be defined in two ways: a class expression or a class declaration.

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

// Expression; the class is anonymous but assigned to a variable
const Rectangle = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};

// Expression; the class has its own name
const Rectangle = class Rectangle2 {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};
```

Like function expressions, class expressions may be anonymous, or have a name that's different from the variable that it's assigned to. However, unlike function declarations, class declarations have the same temporal dead zone restrictions as `let` or `const` and behave as if they are not hoisted.

### Class body

The body of a class is the part that is in curly braces `{}`. This is where you define class members, such as methods or constructor.

The body of a class is executed in strict mode even without the `"use strict"` directive.

A class element can be characterized by three aspects:

* Kind: Getter, setter, method, or field
* Location: Static or instance
* Visibility: Public or private

Together, they add up to 16 possible combinations. To divide the reference more logically and avoid overlapping content, the different elements are introduced in detail in different pages:

Method definitions

Public instance method

getter

Public instance getter

setter

Public instance setter

Public class fields

Public instance field

`static`

Public static method, getter, setter, and field

Private properties

Everything that's private

**Note:** Private features have the restriction that all property names declared in the same class must be unique. All other public properties do not have this restriction — you can have multiple public properties with the same name, and the last one overwrites the others. This is the same behavior as in object initializers.

In addition, there are two special class element syntaxes: `constructor` and static initialization blocks, with their own references.

#### Constructor

The `constructor` method is a special method for creating and initializing an object created with a class. There can only be one special method with the name "constructor" in a class — a `SyntaxError` is thrown if the class contains more than one occurrence of a `constructor` method.

A constructor can use the `super` keyword to call the constructor of the super class.

You can create instance properties inside the constructor:

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

Alternatively, if your instance properties' values do not depend on the constructor's arguments, you can define them as class fields.

#### Static initialization blocks

Static initialization blocks allow flexible initialization of static properties, including the evaluation of statements during initialization, while granting access to the private scope.

Multiple static blocks can be declared, and these can be interleaved with the declaration of static fields and methods (all static items are evaluated in declaration order).

#### Methods

Methods are defined on the prototype of each class instance and are shared by all instances. Methods can be plain functions, async functions, generator functions, or async generator functions. For more information, see method definitions.

```js
class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  // Getter
  get area() {
    return this.calcArea();
  }
  // Method
  calcArea() {
    return this.height \* this.width;
  }
  \*getSides() {
    yield this.height;
    yield this.width;
    yield this.height;
    yield this.width;
  }
}

const square = new Rectangle(10, 10);

console.log(square.area); // 100
console.log([...square.getSides()]); // [10, 10, 10, 10]
```

#### Static methods and fields

The `static` keyword defines a static method or field for a class. Static properties (fields and methods) are defined on the class itself instead of each instance. Static methods are often used to create utility functions for an application, whereas static fields are useful for caches, fixed-configuration, or any other data that doesn't need to be replicated across instances.

```js
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  static displayName = "Point";
  static distance(a, b) {
    const dx = a.x - b.x;
    const dy = a.y - b.y;

    return Math.hypot(dx, dy);
  }
}

const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
p1.displayName; // undefined
p1.distance; // undefined
p2.displayName; // undefined
p2.distance; // undefined

console.log(Point.displayName); // "Point"
console.log(Point.distance(p1, p2)); // 7.0710678118654755
```

#### Field declarations

With the class field declaration syntax, the constructor example can be written as:

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

Class fields are similar to object properties, not variables, so we don't use keywords such as `const` to declare them. In JavaScript, private features use a special identifier syntax, so modifier keywords like `public` and `private` should not be used either.

As seen above, the fields can be declared with or without a default value. Fields without default values default to `undefined`. By declaring fields up-front, class definitions become more self-documenting, and the fields are always present, which help with optimizations.

See public class fields for more information.

#### Private properties

Using private fields, the definition can be refined as below.

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

 It's an error to reference private fields from outside of the class; they can only be read or written within the class body.
 By defining things that are not visible outside of the class, you ensure that your classes' users can't depend on internals, which may change from version to version.

Private fields can only be declared up-front in a field declaration. They cannot be created later through assigning to them, the way that normal properties can.

For more information, see private properties.

### Inheritance

The `extends` keyword is used in *class declarations* or *class expressions* to create a class as a child of another constructor (either a class or a function).

```js
class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  constructor(name) {
    super(name); // call the super class constructor and pass in the name parameter
  }

  speak() {
    console.log(`${this.name} barks.`);
  }
}

const d = new Dog("Mitzie");
d.speak(); // Mitzie barks.
```

If there is a constructor present in the subclass, it needs to first call `super()` before using `this`. The `super` keyword can also be used to call corresponding methods of super class.

```js
class Cat {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Lion extends Cat {
  speak() {
    super.speak();
    console.log(`${this.name} roars.`);
  }
}

const l = new Lion("Fuzzy");
l.speak();
// Fuzzy makes a noise.
// Fuzzy roars.
```

### Evaluation order

When a `class` declaration or `class` expression is evaluated, its various components are evaluated in the following order:

1. The `extends` clause, if present, is first evaluated. It must evaluate to a valid constructor function or `null`, or a `TypeError` is thrown.
2. The `constructor` method is extracted, substituted with a default implementation if `constructor` is not present. However, because the `constructor` definition is only a method definition, this step is not observable.
3. The class elements' property keys are evaluated in the order of declaration. If the property key is computed, the computed expression is evaluated, with the `this` value set to the `this` value surrounding the class (not the class itself). None of the property values are evaluated yet.
4. Methods and accessors are installed in the order of declaration. Instance methods and accessors are installed on the `prototype` property of the current class, and static methods and accessors are installed on the class itself. Private instance methods and accessors are saved to be installed on the instance directly later. This step is not observable.
5. The class is now initialized with the prototype specified by `extends` and implementation specified by `constructor`. For all steps above, if an evaluated expression tries to access the name of the class, a `ReferenceError` is thrown because the class is not initialized yet.
6. The class elements' values are evaluated in the order of declaration:
    * For each instance field (public or private), its initializer expression is saved. The initializer is evaluated during instance creation, at the start of the constructor (for base classes) or immediately before the `super()` call returns (for derived classes).
    * For each static field (public or private), its initializer is evaluated with `this` set to the class itself, and the property is created on the class.
    * Static initialization blocks are evaluated with `this` set to the class itself.
7. The class is now fully initialized and can be used as a constructor function.

For how instances are created, see the `constructor` reference.

Examples
--------

### Binding this with instance and static methods

When a static or instance method is called without a value for `this`, such as by assigning the method to a variable and then calling it, the `this` value will be `undefined` inside the method. This behavior is the same even if the `"use strict"` directive isn't present, because code within the `class` body is always executed in strict mode.

```js
class Animal {
  speak() {
    return this;
  }
  static eat() {
    return this;
  }
}

const obj = new Animal();
obj.speak(); // the Animal object
const speak = obj.speak;
speak(); // undefined

Animal.eat(); // class Animal
const eat = Animal.eat;
eat(); // undefined
```

If we rewrite the above using traditional function-based syntax in non–strict mode, then `this` method calls are automatically bound to `globalThis`. In strict mode, the value of `this` remains as `undefined`.

```js
function Animal() {}

Animal.prototype.speak = function () {
  return this;
};

Animal.eat = function () {
  return this;
};

const obj = new Animal();
const speak = obj.speak;
speak(); // global object (in non–strict mode)

const eat = Animal.eat;
eat(); // global object (in non-strict mode)
```

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

* Using classes guide
* `class`
* `class` expression
* Functions
* ES6 In Depth: Classes on hacks.mozilla.org (2015)


Deprecated and obsolete features - JavaScript

Deprecated and obsolete features
================================

This page lists features of JavaScript that are deprecated (that is, still available but planned for removal) and obsolete (that is, no longer usable).

Deprecated features
-------------------

These deprecated features can still be used, but should be used with caution because they are not required to be implemented by every JavaScript engine. You should work to remove their use from your code.

Some of these deprecated features are listed in the Annex B section of the ECMAScript specification. This section is described as normative optional — that is, web browser hosts must implement these features, while non-web hosts may not. These features are likely stable because removing them will cause backward compatibility issues and break legacy websites. (JavaScript has the design goal of "don't break the web".) Still, they are not cross-platform portable and may not be supported by all analysis tools, so you are advised to not use them, as the introduction of Annex B states:

>
> … All of the language features and behaviors specified in this annex have one or more undesirable characteristics and in the absence of legacy usage would be removed from this specification. …
>
>
> … Programmers should not use or assume the existence of these features and behaviors when writing new ECMAScript code. …
>
>
>

Some others, albeit in the main spec body, are also marked as normative optional and should not be depended on.

### HTML comments

JavaScript source, if parsed as scripts, allows HTML-like comments, as if the script is part of a `<script>` tag.

The following is valid JavaScript when running in a web browser (or Node.js, which uses the V8 engine powering Chrome):

```js
<!-- comment
console.log("a"); <!-- another comment
console.log("b");
--> More comment
// Logs "a" and "b"
```

`<!--` and `-->` both act like `//`, i.e. starting line comments. `-->` is only valid at the start of a line (to avoid ambiguity with a postfix decrement followed by a greater than operator), while `<!--` can occur anywhere in the line.

### RegExp

The following properties are deprecated. This does not affect their use in replacement strings:

`$1–$9`

Parenthesized substring matches, if any.

`input, $_`

The string against which a regular expression is matched.

`lastMatch, $&`

The last matched substring.

`lastParen, $+`

The last parenthesized substring match, if any.

`leftContext, $``

The substring preceding the most recent match.

`rightContext, $'`

The substring following the most recent match.

**Warning:** Avoid using these static properties, as they can cause issues when interacting with external code!

The `compile()` method is deprecated. Construct a new `RegExp` instance instead.

The following regex syntaxes are deprecated and only available in Unicode-unaware mode. In Unicode-aware mode, they are all syntax errors:

* Lookahead assertions can have quantifiers.
* Backreferences that do not refer to an existing capturing group become legacy octal escapes.
* In character classes, character ranges where one boundary is a character class makes the `-` become a literal character.
* An escape sequence that's not recognized becomes an "identity escape".
* Escape sequences within character classes of the form `\cX` where `X` is a number or `_` are decoded in the same way as those with ASCII letters: `\c0` is the same as `\cP` when taken modulo 32. In addition, if the form `\cX` is encountered anywhere where `X` is not one of the recognized characters, then the backslash is treated as a literal character.
* The sequence `\k` within a regex that doesn't have any named capturing groups is treated as an identity escape.
* The syntax characters `]`, `{`, and `}` may appear literally without escaping if they cannot be interpreted as the end of a character class or quantifier delimiters.
### Function

* The `caller` property of functions and the `arguments.callee` property are deprecated and unavailable in strict mode.
* Instead of accessing `arguments` as a property of a function, you should use the `arguments` object inside function closures.
### Object

* The `Object.prototype.__proto__` accessors are deprecated. Use `Object.getPrototypeOf` and `Object.setPrototypeOf` instead. This does not apply to the `__proto__` literal key in object literals.
* The `Object.prototype.__defineGetter__`, `Object.prototype.__defineSetter__`, `Object.prototype.__lookupGetter__`, and `Object.prototype.__lookupSetter__` methods are deprecated. Use `Object.getOwnPropertyDescriptor` and `Object.defineProperty` instead.
### String

* HTML wrapper methods like `String.prototype.fontsize` and `String.prototype.big`.
* `String.prototype.substr` probably won't be removed anytime soon, but it's defined in Annex B and hence normative optional.
* `String.prototype.trimLeft` and `String.prototype.trimRight` should be replaced with `String.prototype.trimStart` and `String.prototype.trimEnd`.
### Date

* The `getYear()` and `setYear()` methods are affected by the Year-2000-Problem and have been subsumed by `getFullYear` and `setFullYear`.
* The `toGMTString()` method is deprecated. Use `toUTCString()` instead.
### Escape sequences

* Octal escape sequences (\ followed by one, two, or three octal digits) are deprecated in string and regular expression literals.
* The `escape()` and `unescape()` functions are deprecated. Use `encodeURI()`, `encodeURIComponent()`, `decodeURI()`, or `decodeURIComponent()` to encode and decode escape sequences for special characters.
### Statements

The `with` statement is deprecated and unavailable in strict mode.

Initializers in `var` declarations of `for...in` loops headers are deprecated and produce syntax errors in strict mode. They are silently ignored in non-strict mode.

Normally, the `catch` block of a `try...catch` statement cannot contain any variable declaration with the same name as the variables bound in the `catch()`. An extension grammar allows the `catch` block to contain a `var` declared variable with the same name as the `catch`-bound identifier, but only if the `catch` binding is a simple identifier, not a destructuring pattern. However, this variable's initialization and assignment would only act on the `catch`-bound identifier, instead of the upper scope variable, and the behavior could be confusing.

```js
var a = 2;
try {
  throw 42;
} catch (a) {
  var a = 1; // This 1 is assigned to the caught `a`, not the outer `a`.
}
console.log(a); // 2

try {
  throw 42;
  // Note: identifier changed to `err` to avoid conflict with
  // the inner declaration of `a`.
} catch (err) {
  var a = 1; // This 1 is assigned to the upper-scope `a`.
}
console.log(a); // 1
```

This is listed in Annex B of the spec and hence may not be implemented everywhere. Avoid any name conflicts between the `catch`-bound identifier and variables declared in the `catch` block.

Obsolete features
-----------------

These obsolete features have been entirely removed from JavaScript and can no longer be used as of the indicated version of JavaScript.

### RegExp

The following are now properties of `RegExp` instances, no longer of the `RegExp` constructor:

| Property | Description |
| --- | --- |
| `global` | Whether or not to test the regular expression against all possible matches in a string, or only against the first. |
| `ignoreCase` | Whether or not to ignore case while attempting a match in a string. |
| `lastIndex` | The index at which to start the next match. |
| `multiline` (also via `RegExp.$*`) | Whether or not to search in strings across multiple lines. |
| `source` | The text of the pattern. |

The `valueOf()` method is no longer specialized for `RegExp`. It uses `Object.prototype.valueOf()`, which returns itself.

### Function

* Functions' `arity` property is obsolete. Use `length` instead.
### Object

| Property | Description | Alternative |
| --- | --- | --- |
| `__count__` | Returns the number of enumerable properties directly on a user-defined object. | `Object.keys()` |
| `__parent__` | Points to an object's context. | No direct replacement |
| `__iterator__` | Used with legacy iterators. | `Symbol.iterator` and the new iteration protocols |
| `__noSuchMethod__` | A method called when a non-existent property is called as method. | `Proxy` |
| `Object.prototype.eval()` | Evaluates a string of JavaScript code in the context of the specified object. | No direct replacement |
| `Object.observe()` | Asynchronously observing the changes to an object. | `Proxy` |
| `Object.unobserve()` | Remove observers. | `Proxy` |
| `Object.getNotifier()` | Create a notifier object that allows to synthetically trigger a change observable with `Object.observe()`. | No direct replacement |
| `Object.prototype.watch()` | Attach a handler callback to a property that gets called when the property is assigned. | `Proxy` |
| `Object.prototype.unwatch()` | Remove watch handlers on a property. | `Proxy` |

### String

* Non-standard String generic methods like `String.slice(myStr, 0, 12)`, `String.replace(myStr, /\./g, "!")`, etc. have been introduced in Firefox 1.5 (JavaScript 1.6), deprecated in Firefox 53, and removed in Firefox 68. You can use methods on `String.prototype` together with `Function.call` instead.
* `String.prototype.quote` is removed from Firefox 37.
* Non-standard `flags` parameter in `String.prototype.search`, `String.prototype.match`, and `String.prototype.replace` are obsolete.
### WeakMap

* `WeakMap.prototype.clear()` was added in Firefox 20 and removed in Firefox 46. It is not possible to traverse all keys in a `WeakMap`.
### Date

* `Date.prototype.toLocaleFormat()`, which used a format string in the same format expected by the `strftime()` function in C, is obsolete. Use `toLocaleString()` or `Intl.DateTimeFormat` instead.
### Array

* Non-standard Array generic methods like `Array.slice(myArr, 0, 12)`, `Array.forEach(myArr, myFn)`, etc. have been introduced in Firefox 1.5 (JavaScript 1.6), deprecated in Firefox 68, and removed in Firefox 71. You can use methods on `Array.prototype` together with `Function.call` instead.

| Property | Description | Alternative |
| --- | --- | --- |
| `Array.observe()` | Asynchronously observing changes to Arrays. | `Proxy` |
| `Array.unobserve()` | Remove observers. | `Proxy` |

### Number

* `Number.toInteger()` is obsolete. Use `Math.floor`, `Math.round`, or other methods instead.
### Proxy

* `Proxy.create` and `Proxy.createFunction` are obsolete. Use the `Proxy()` constructor instead.
* The following traps are obsolete:
    + `hasOwn` (bug 980565, Firefox 33).
    + `getEnumerablePropertyKeys` (bug 783829, Firefox 37)
    + `getOwnPropertyNames` (bug 1007334, Firefox 33)
    + `keys` (bug 1007334, Firefox 33)
### ParallelArray

* `ParallelArray` is obsolete.
### Statements

* `for each...in` is obsolete. Use `for...of` instead.
* let blocks and let expressions are obsolete.
* Expression closures (`function () 1` as a shorthand of `function () { return 1; }`) are obsolete. Use regular `functions` or arrow functions instead.
### Acquiring source text

The `toSource()` methods of arrays, numbers, strings, etc. and the `uneval()` global function are obsolete. Use `toString()`, or write your own serialization method instead.

### Legacy generator and iterator

Legacy generator function statements and legacy generator function expressions are removed. The legacy generator function syntax reuses the `function` keyword, which automatically becomes a generator function when there are one or more `yield` expressions in the body — this is now a syntax error. Use `function*` statements and `function*` expressions instead.

Array comprehensions and generator comprehensions are removed.

```js
// Legacy array comprehensions
[for (x of iterable) x]
[for (x of iterable) if (condition) x]
[for (x of iterable) for (y of iterable) x + y]

// Legacy generator comprehensions
(for (x of iterable) x)
(for (x of iterable) if (condition) x)
(for (x of iterable) for (y of iterable) x + y)
```

Firefox, prior to version 26, implemented another iterator protocol that is similar to the standard Iterator protocol. An object is an legacy iterator when it implements a `next()` method, which produces a value on each call and throws a `StopIteration` object at the end of iteration. This legacy iterator protocol differs from the standard iterator protocol:

* The value was returned directly as the return value of calls to `next()`, instead of the `value` property of the `IteratorResult` object.
* Iteration termination was expressed by throwing a `StopIteration` object, instead of through the `done` property of the `IteratorResult` object.

This feature, along with the `StopIteration` global constructor, was removed in Firefox 58+. For future-facing usages, consider using `for...of` loops and the iterator protocol.

### Sharp variables

Sharp variables are obsolete. To create circular structures, use temporary variables instead.


JavaScript error reference - JavaScript

JavaScript error reference
==========================

Below, you'll find a list of errors which are thrown by JavaScript. These errors can be a helpful debugging aid, but the reported problem isn't always immediately clear. The pages below will provide additional details about these errors. Each error is an object based upon the `Error` object, and has a `name` and a `message`.

Errors displayed in the Web console may include a link to the corresponding page below to help you quickly comprehend the problem in your code.

For a beginner's introductory tutorial on fixing JavaScript errors, see What went wrong? Troubleshooting JavaScript.

List of errors
--------------

In this list, each page is listed by name (the type of error) and message (a more detailed human-readable error message). Together, these two properties provide a starting point toward understanding and resolving the error. For more information, follow the links below!

* Error: Permission denied to access property "x"
* InternalError: too much recursion
* RangeError: BigInt division by zero
* RangeError: BigInt negative exponent
* RangeError: argument is not a valid code point
* RangeError: invalid array length
* RangeError: invalid date
* RangeError: precision is out of range
* RangeError: radix must be an integer
* RangeError: repeat count must be less than infinity
* RangeError: repeat count must be non-negative
* RangeError: x can't be converted to BigInt because it isn't an integer
* ReferenceError: "x" is not defined
* ReferenceError: assignment to undeclared variable "x"
* ReferenceError: can't access lexical declaration 'X' before initialization
* ReferenceError: deprecated caller or arguments usage
* ReferenceError: reference to undefined property "x"
* SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated
* SyntaxError: "use strict" not allowed in function with non-simple parameters
* SyntaxError: "x" is a reserved identifier
* SyntaxError: JSON.parse: bad parsing
* SyntaxError: Unexpected '#' used outside of class body
* SyntaxError: Unexpected token
* SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //# instead
* SyntaxError: a declaration in the head of a for-of loop can't have an initializer
* SyntaxError: applying the 'delete' operator to an unqualified name is deprecated
* SyntaxError: await is only valid in async functions, async generators and modules
* SyntaxError: cannot use `??` unparenthesized within `||` and `&&` expressions
* SyntaxError: continue must be inside loop
* SyntaxError: for-in loop head declarations may not have initializers
* SyntaxError: function statement requires a name
* SyntaxError: getter and setter for private name #x should either be both static or non-static
* SyntaxError: identifier starts immediately after numeric literal
* SyntaxError: illegal character
* SyntaxError: invalid BigInt syntax
* SyntaxError: invalid assignment left-hand side
* SyntaxError: invalid regular expression flag "x"
* SyntaxError: label not found
* SyntaxError: missing ) after argument list
* SyntaxError: missing ) after condition
* SyntaxError: missing : after property id
* SyntaxError: missing ; before statement
* SyntaxError: missing = in const declaration
* SyntaxError: missing ] after element list
* SyntaxError: missing formal parameter
* SyntaxError: missing name after . operator
* SyntaxError: missing variable name
* SyntaxError: missing } after function body
* SyntaxError: missing } after property list
* SyntaxError: redeclaration of formal parameter "x"
* SyntaxError: return not in function
* SyntaxError: test for equality (==) mistyped as assignment (=)?
* SyntaxError: unlabeled break must be inside loop or switch
* SyntaxError: unparenthesized unary expression can't appear on the left-hand side of '\*\*'
* SyntaxError: unterminated string literal
* TypeError: "x" has no properties
* TypeError: "x" is (not) "y"
* TypeError: "x" is not a constructor
* TypeError: "x" is not a function
* TypeError: "x" is not a non-null object
* TypeError: "x" is read-only
* TypeError: 'x' is not iterable
* TypeError: More arguments needed
* TypeError: Reduce of empty array with no initial value
* TypeError: X.prototype.y called on incompatible type
* TypeError: can't assign to property "x" on "y": not an object
* TypeError: can't convert BigInt to number
* TypeError: can't convert x to BigInt
* TypeError: can't define property "x": "obj" is not extensible
* TypeError: can't delete non-configurable array element
* TypeError: can't redefine non-configurable property "x"
* TypeError: cannot use 'in' operator to search for 'x' in 'y'
* TypeError: cyclic object value
* TypeError: invalid 'instanceof' operand 'x'
* TypeError: invalid Array.prototype.sort argument
* TypeError: invalid assignment to const "x"
* TypeError: property "x" is non-configurable and can't be deleted
* TypeError: setting getter-only property "x"
* URIError: malformed URI sequence
* Warning: -file- is being assigned a //# sourceMappingURL, but already has one
* Warning: unreachable code after return statement


Expressions and operators - JavaScript

Expressions and operators
=========================

This chapter documents all the JavaScript language operators, expressions and keywords.

Expressions and operators by category
-------------------------------------

For an alphabetical listing see the sidebar on the left.

### Primary expressions

Basic keywords and general expressions in JavaScript. These expressions have the highest precedence (higher than operators).

`this`

The `this` keyword refers to a special property of an execution context.

Literals

Basic `null`, boolean, number, and string literals.

`[]`

Array initializer/literal syntax.

`{}`

Object initializer/literal syntax.

`function`

The `function` keyword defines a function expression.

`class`

The `class` keyword defines a class expression.

`function*`

The `function*` keyword defines a generator function expression.

`async function`

The `async function` defines an async function expression.

`async function*`

The `async function*` keywords define an async generator function expression.

`/ab+c/i`

Regular expression literal syntax.

``string``

Template literal syntax.

`( )`

Grouping operator.

### Left-hand-side expressions

Left values are the destination of an assignment.

Property accessors

Member operators provide access to a property or method of an object (`object.property` and `object["property"]`).

`?.`

The optional chaining operator returns `undefined` instead of causing an error if a reference is nullish (`null` or `undefined`).

`new`

The `new` operator creates an instance of a constructor.

`new.target`

In constructors, `new.target` refers to the constructor that was invoked by `new`.

`import.meta`

An object exposing context-specific metadata to a JavaScript module.

`super`

The `super` keyword calls the parent constructor or allows accessing properties of the parent object.

`import()`

The `import()` syntax allows loading a module asynchronously and dynamically into a potentially non-module environment.

### Increment and decrement

Postfix/prefix increment and postfix/prefix decrement operators.

`A++`

Postfix increment operator.

`A--`

Postfix decrement operator.

`++A`

Prefix increment operator.

`--A`

Prefix decrement operator.

### Unary operators

A unary operation is an operation with only one operand.

`delete`

The `delete` operator deletes a property from an object.

`void`

The `void` operator evaluates an expression and discards its return value.

`typeof`

The `typeof` operator determines the type of a given object.

`+`

The unary plus operator converts its operand to Number type.

`-`

The unary negation operator converts its operand to Number type and then negates it.

`~`

Bitwise NOT operator.

`!`

Logical NOT operator.

`await`

Pause and resume an async function and wait for the promise's fulfillment/rejection.

### Arithmetic operators

Arithmetic operators take numerical values (either literals or variables) as their operands and return a single numerical value.

`**`

Exponentiation operator.

`*`

Multiplication operator.

`/`

Division operator.

`%`

Remainder operator.

`+` (Plus)

Addition operator.

`-`

Subtraction operator.

### Relational operators

A comparison operator compares its operands and returns a boolean value based on whether the comparison is true.

`<` (Less than)

Less than operator.

`>` (Greater than)

Greater than operator.

`<=`

Less than or equal operator.

`>=`

Greater than or equal operator.

`instanceof`

The `instanceof` operator determines whether an object is an instance of another object.

`in`

The `in` operator determines whether an object has a given property.

**Note:** `=>` is not an operator, but the notation for Arrow functions.

### Equality operators

The result of evaluating an equality operator is always of type boolean based on whether the comparison is true.

`==`

Equality operator.

`!=`

Inequality operator.

`===`

Strict equality operator.

`!==`

Strict inequality operator.

### Bitwise shift operators

Operations to shift all bits of the operand.

`<<`

Bitwise left shift operator.

`>>`

Bitwise right shift operator.

`>>>`

Bitwise unsigned right shift operator.

### Binary bitwise operators

Bitwise operators treat their operands as a set of 32 bits (zeros and ones) and return standard JavaScript numerical values.

`&`

Bitwise AND.

`|`

Bitwise OR.

`^`

Bitwise XOR.

### Binary logical operators

Logical operators implement boolean (logical) values and have short-circuiting behavior.

`&&`

Logical AND.

`||`

Logical OR.

`??`

Nullish Coalescing Operator.

### Conditional (ternary) operator

`(condition ? ifTrue : ifFalse)`

The conditional operator returns one of two values based on the logical value of the condition.

### Assignment operators

An assignment operator assigns a value to its left operand based on the value of its right operand.

`=`

Assignment operator.

`*=`

Multiplication assignment.

`/=`

Division assignment.

`%=`

Remainder assignment.

`+=`

Addition assignment.

`-=`

Subtraction assignment

`<<=`

Left shift assignment.

`>>=`

Right shift assignment.

`>>>=`

Unsigned right shift assignment.

`&=`

Bitwise AND assignment.

`^=`

Bitwise XOR assignment.

`|=`

Bitwise OR assignment.

`**=`

Exponentiation assignment.

`&&=`

Logical AND assignment.

`||=`

Logical OR assignment.

`??=`

Nullish coalescing assignment.

`[a, b] = arr`, `{ a, b } = obj`

Destructuring assignment allows you to assign the properties of an array or object to variables using syntax that looks similar to array or object literals.

### Yield operators

`yield`

Pause and resume a generator function.

`yield*`

Delegate to another generator function or iterable object.

### Spread syntax

`...obj`

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.

### Comma operator

`,`

The comma operator allows multiple expressions to be evaluated in a single statement and returns the result of the last expression.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-addition-operator-plus |
| ECMAScript Language Specification # sec-assignment-operators |
| ECMAScript Language Specification # sec-async-function-definitions |
| ECMAScript Language Specification # sec-async-generator-function-definitions |
| ECMAScript Language Specification # prod-BitwiseANDExpression |
| ECMAScript Language Specification # sec-bitwise-not-operator |
| ECMAScript Language Specification # prod-BitwiseORExpression |
| ECMAScript Language Specification # prod-BitwiseXORExpression |
| ECMAScript Language Specification # sec-class-definitions |
| ECMAScript Language Specification # sec-comma-operator |
| ECMAScript Language Specification # sec-conditional-operator |
| ECMAScript Language Specification # sec-postfix-decrement-operator |
| ECMAScript Language Specification # sec-delete-operator |
| ECMAScript Language Specification # sec-destructuring-assignment |
| ECMAScript Language Specification # sec-destructuring-binding-patterns |
| ECMAScript Language Specification # sec-multiplicative-operators |
| ECMAScript Language Specification # sec-equality-operators |
| ECMAScript Language Specification # sec-exp-operator |
| ECMAScript Language Specification # sec-function-definitions |
| ECMAScript Language Specification # sec-generator-function-definitions |
| ECMAScript Language Specification # sec-relational-operators |
| ECMAScript Language Specification # sec-grouping-operator |
| ECMAScript Language Specification # sec-import-calls |
| ECMAScript Language Specification # prod-ImportMeta |
| HTML Standard # hostgetimportmetaproperties |
| ECMAScript Language Specification # sec-postfix-increment-operator |
| ECMAScript Language Specification # sec-left-shift-operator |
| ECMAScript Language Specification # prod-LogicalANDExpression |
| ECMAScript Language Specification # sec-logical-not-operator |
| ECMAScript Language Specification # prod-LogicalORExpression |
| ECMAScript Language Specification # sec-new-operator |
| ECMAScript Language Specification # sec-built-in-function-objects |
| ECMAScript Language Specification # sec-null-value |
| ECMAScript Language Specification # prod-CoalesceExpression |
| ECMAScript Language Specification # sec-object-initializer |
| ECMAScript Language Specification # prod-OptionalExpression |
| ECMAScript Language Specification # sec-property-accessors |
| ECMAScript Language Specification # sec-signed-right-shift-operator |
| ECMAScript Language Specification # prod-SpreadElement |
| ECMAScript Language Specification # prod-ArgumentList |
| ECMAScript Language Specification # prod-PropertyDefinition |
| ECMAScript Language Specification # sec-subtraction-operator-minus |
| ECMAScript Language Specification # sec-super-keyword |
| ECMAScript Language Specification # sec-this-keyword |
| ECMAScript Language Specification # sec-typeof-operator |
| ECMAScript Language Specification # sec-unary-minus-operator |
| ECMAScript Language Specification # sec-unary-plus-operator |
| ECMAScript Language Specification # sec-unsigned-right-shift-operator |
| ECMAScript Language Specification # sec-void-operator |
| ECMAScript Language Specification # prod-YieldExpression |
| ECMAScript Language Specification # sec-generator-function-definitions-runtime-semantics-evaluation |

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

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

See also
--------

* Operator precedence


Strict mode - JavaScript

Strict mode
===========

**Note:** Sometimes you'll see the default, non-strict mode referred to as *sloppy mode*. This isn't an official term, but be aware of it, just in case.

JavaScript's strict mode is a way to *opt in* to a restricted variant of JavaScript, thereby implicitly opting-out of "sloppy mode". Strict mode isn't just a subset: it *intentionally* has different semantics from normal code. Browsers not supporting strict mode will run strict mode code with different behavior from browsers that do, so don't rely on strict mode without feature-testing for support for the relevant aspects of strict mode. Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally.

Strict mode makes several changes to normal JavaScript semantics:

1. Eliminates some JavaScript silent errors by changing them to throw errors.
2. Fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that's not strict mode.
3. Prohibits some syntax likely to be defined in future versions of ECMAScript.
Invoking strict mode
--------------------

Strict mode applies to *entire scripts* or to *individual functions*. It doesn't apply to block statements enclosed in `{}` braces; attempting to apply it to such contexts does nothing. `eval` code, `Function` code, event handler attributes, strings passed to `setTimeout()`, and related functions are either function bodies or entire scripts, and invoking strict mode in them works as expected.

### Strict mode for scripts

To invoke strict mode for an entire script, put the *exact* statement `"use strict";` (or `'use strict';`) before any other statements.

```js
// Whole-script strict mode syntax
"use strict";
const v = "Hi! I'm a strict mode script!";
```

### Strict mode for functions

Likewise, to invoke strict mode for a function, put the *exact* statement `"use strict";` (or `'use strict';`) in the function's body before any other statements.

```js
function myStrictFunction() {
  // Function-level strict mode syntax
  "use strict";
  function nested() {
    return "And so am I!";
  }
  return `Hi! I'm a strict mode function! ${nested()}`;
}
function myNotStrictFunction() {
  return "I'm not strict.";
}
```

The `"use strict"` directive can only be applied to the body of functions with simple parameters. Using `"use strict"` in functions with rest, default, or destructured parameters is a syntax error.

```js
function sum(a = 1, b = 2) {
  // SyntaxError: "use strict" not allowed in function with default parameter
  "use strict";
  return a + b;
}
```

### Strict mode for modules

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.

```js
function myStrictFunction() {
  // because this is a module, I'm strict by default
}
export default myStrictFunction;
```

### Strict mode for classes

All parts of a class's body are strict mode code, including both class declarations and class expressions.

```js
class C1 {
  // All code here is evaluated in strict mode
  test() {
    delete Object.prototype;
  }
}
new C1().test(); // TypeError, because test() is in strict mode

const C2 = class {
  // All code here is evaluated in strict mode
};

// Code here may not be in strict mode
delete Object.prototype; // Will not throw error
```

Changes in strict mode
----------------------

Strict mode changes both syntax and runtime behavior. Changes generally fall into these categories:

* changes converting mistakes into errors (as syntax errors or at runtime)
* changes simplifying how variable references are resolved
* changes simplifying `eval` and `arguments`
* changes making it easier to write "secure" JavaScript
* changes anticipating future ECMAScript evolution.
### Converting mistakes into errors

Strict mode changes some previously-accepted mistakes into errors. JavaScript was designed to be easy for novice developers, and sometimes it gives operations which should be errors non-error semantics. Sometimes this fixes the immediate problem, but sometimes this creates worse problems in the future. Strict mode treats these mistakes as errors so that they're discovered and promptly fixed.

#### Assigning to undeclared variables

Strict mode makes it impossible to accidentally create global variables. In sloppy mode, mistyping a variable in an assignment creates a new property on the global object and continues to "work". Assignments which would accidentally create global variables throw an error in strict mode:

```js
"use strict";
let mistypeVariable;

// Assuming no global variable mistypeVarible exists
// this line throws a ReferenceError due to the
// misspelling of "mistypeVariable" (lack of an "a")
mistypeVarible = 17;
```

#### Failing to assign to object properties

Strict mode makes assignments which would otherwise silently fail to throw an exception. There are three ways to fail a property assignment:

* assignment to a non-writable data property
* assignment to a getter-only accessor property
* assignment to a new property on a non-extensible object

For example, `NaN` is a non-writable global variable. In sloppy mode, assigning to `NaN` does nothing; the developer receives no failure feedback. In strict mode, assigning to `NaN` throws an exception.

```js
"use strict";

// Assignment to a non-writable global
undefined = 5; // TypeError
Infinity = 5; // TypeError

// Assignment to a non-writable property
const obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // TypeError

// Assignment to a getter-only property
const obj2 = {
  get x() {
    return 17;
  },
};
obj2.x = 5; // TypeError

// Assignment to a new property on a non-extensible object
const fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // TypeError
```

#### Failing to delete object properties

Attempts to delete a non-configurable or otherwise undeletable (e.g. it's intercepted by a proxy's `deleteProperty` handler which returns `false`) property throw in strict mode (where before the attempt would have no effect):

```js
"use strict";
delete Object.prototype; // TypeError
delete [].length; // TypeError
```

Strict mode also forbids deleting plain names. `delete name` in strict mode is a syntax error:

```js
"use strict";

var x;
delete x; // syntax error
```

If the name is a configurable global property, prefix it with `globalThis` to delete it.

```js
"use strict";

delete globalThis.x;
```

#### Duplicate parameter names

Strict mode requires that function parameter names be unique. In sloppy mode, the last duplicated argument hides previous identically-named arguments. Those previous arguments remain available through `arguments`, so they're not completely inaccessible. Still, this hiding makes little sense and is probably undesirable (it might hide a typo, for example), so in strict mode, duplicate argument names are a syntax error:

```js
function sum(a, a, c) {
  // syntax error
  "use strict";
  return a + a + c; // wrong if this code ran
}
```

#### Legacy octal literals

Strict mode forbids a `0`-prefixed octal literal or octal escape sequence. In sloppy mode, a number beginning with a `0`, such as `0644`, is interpreted as an octal number (`0644 === 420`), if all digits are smaller than 8. Novice developers sometimes believe a leading-zero prefix has no semantic meaning, so they might use it as an alignment device — but this changes the number's meaning! A leading-zero syntax for the octal is rarely useful and can be mistakenly used, so strict mode makes it a syntax error:

```js
"use strict";
const sum =
  015 + // syntax error
  197 +
  142;
```

The standardized way to denote octal literals is via the `0o` prefix. For example:

```js
const sumWithOctal = 0o10 + 8;
console.log(sumWithOctal); // 16
```

Octal escape sequences, such as `"\45"`, which is equal to `"%"`, can be used to represent characters by extended-ASCII character code numbers in octal. In strict mode, this is a syntax error. More formally, it's disallowed to have `\` followed by any decimal digit other than `0`, or `\0` followed by a decimal digit; for example `\9` and `\07`.

#### Setting properties on primitive values

Strict mode forbids setting properties on primitive values. Accessing a property on a primitive implicitly creates a wrapper object that's unobservable, so in sloppy mode, setting properties is ignored (no-op). In strict mode, a `TypeError` is thrown.

```js
"use strict";

false.true = ""; // TypeError
(14).sailing = "home"; // TypeError
"with".you = "far away"; // TypeError
```

#### Duplicate property names

Duplicate property names used to be considered a `SyntaxError` in strict mode. With the introduction of computed property names, making duplication possible at runtime, this restriction was removed in ES2015.

```js
"use strict";
const o = { p: 1, p: 2 }; // syntax error prior to ECMAScript 2015
```

**Note:** Making code that used to error become non-errors is always considered backwards-compatible. This is a good part of the language being strict about throwing errors: it leaves room for future semantic changes.

### Simplifying scope management

Strict mode simplifies how variable names map to particular variable definitions in the code. Many compiler optimizations rely on the ability to say that variable *X* is stored in *that* location: this is critical to fully optimizing JavaScript code. JavaScript sometimes makes this basic mapping of name to variable definition in the code impossible to perform until runtime. Strict mode removes most cases where this happens, so the compiler can better optimize strict mode code.

#### Removal of the with statement

Strict mode prohibits `with`. The problem with `with` is that any name inside the block might map either to a property of the object passed to it, or to a variable in surrounding (or even global) scope, at runtime; it's impossible to know which beforehand. Strict mode makes `with` a syntax error, so there's no chance for a name in a `with` to refer to an unknown location at runtime:

```js
"use strict";
const x = 17;
with (obj) {
  // Syntax error
  // If this weren't strict mode, would this be const x, or
  // would it instead be obj.x? It's impossible in general
  // to say without running the code, so the name can't be
  // optimized.
  x;
}
```

The simple alternative of assigning the object to a short name variable, then accessing the corresponding property on that variable, stands ready to replace `with`.

#### Non-leaking eval

In strict mode, `eval` does not introduce new variables into the surrounding scope. In sloppy mode, `eval("var x;")` introduces a variable `x` into the surrounding function or the global scope. This means that, in general, in a function containing a call to `eval`, every name not referring to an argument or local variable must be mapped to a particular definition at runtime (because that `eval` might have introduced a new variable that would hide the outer variable). In strict mode, `eval` creates variables only for the code being evaluated, so `eval` can't affect whether a name refers to an outer variable or some local variable:

```js
var x = 17;
var evalX = eval("'use strict'; var x = 42; x;");
console.assert(x === 17);
console.assert(evalX === 42);
```

Whether the string passed to `eval()` is evaluated in strict mode depends on how `eval()` is invoked (direct eval or indirect eval).

#### Block-scoped function declarations

The JavaScript language specification, since its start, had not allowed function declarations nested in block statements. However, it was so intuitive that most browsers implemented it as an extension grammar. Unfortunately, the implementations' semantics diverged, and it became impossible for the language specification to reconcile all implementations. Therefore, block-scoped function declarations are only explicitly specified in strict mode (whereas they were once disallowed in strict mode), while sloppy mode behavior remains divergent among browsers.

### Making eval and arguments simpler

Strict mode makes `arguments` and `eval` less bizarrely magical. Both involve a considerable amount of magical behavior in sloppy mode: `eval` to add or remove bindings and to change binding values, and `arguments` syncing named arguments with its indexed properties. Strict mode makes great strides toward treating `eval` and `arguments` as keywords.

#### Preventing binding or assigning eval and arguments

The names `eval` and `arguments` can't be bound or assigned in language syntax. All these attempts to do so are syntax errors:

```js
"use strict";
eval = 17;
arguments++;
++eval;
const obj = { set p(arguments) {} };
let eval;
try {
} catch (arguments) {}
function x(eval) {}
function arguments() {}
const y = function eval() {};
const f = new Function("arguments", "'use strict'; return 17;");
```

#### No syncing between parameters and arguments indices

Strict mode code doesn't sync indices of the `arguments` object with each parameter binding. In a sloppy mode function whose first argument is `arg`, setting `arg` also sets `arguments[0]`, and vice versa (unless no arguments were provided or `arguments[0]` is deleted). `arguments` objects for strict mode functions store the original arguments when the function was invoked. `arguments[i]` does not track the value of the corresponding named argument, nor does a named argument track the value in the corresponding `arguments[i]`.

```js
function f(a) {
  "use strict";
  a = 42;
  return [a, arguments[0]];
}
const pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);
```

### "Securing" JavaScript

Strict mode makes it easier to write "secure" JavaScript. Some websites now provide ways for users to write JavaScript which will be run by the website *on behalf of other users*. JavaScript in browsers can access the user's private information, so such JavaScript must be partially transformed before it is run, to censor access to forbidden functionality. JavaScript's flexibility makes it effectively impossible to do this without many runtime checks. Certain language functions are so pervasive that performing runtime checks has a considerable performance cost. A few strict mode tweaks, plus requiring that user-submitted JavaScript be strict mode code and that it be invoked in a certain manner, substantially reduce the need for those runtime checks.

#### No this substitution

The value passed as `this` to a function in strict mode is not forced into being an object (a.k.a. "boxed"). For a sloppy mode function, `this` is always an object: either the provided object, if called with an object-valued `this`; or the boxed value of `this`, if called with a primitive as `this`; or the global object, if called with `undefined` or `null` as `this`. (Use `call`, `apply`, or `bind` to specify a particular `this`.) Not only is automatic boxing a performance cost, but exposing the global object in browsers is a security hazard because the global object provides access to functionality that "secure" JavaScript environments must restrict. Thus for a strict mode function, the specified `this` is not boxed into an object, and if unspecified, `this` is `undefined` instead of `globalThis`:

```js
"use strict";
function fun() {
  return this;
}
console.assert(fun() === undefined);
console.assert(fun.call(2) === 2);
console.assert(fun.apply(null) === null);
console.assert(fun.call(undefined) === undefined);
console.assert(fun.bind(true)() === true);
```

#### Removal of stack-walking properties

In strict mode it's no longer possible to "walk" the JavaScript stack. Many implementations used to implement some extension features that make it possible to detect the upstream caller of a function. When a function `fun` is in the middle of being called, `fun.caller` is the function that most recently called `fun`, and `fun.arguments` is the `arguments` for that invocation of `fun`. Both extensions are problematic for "secure" JavaScript because they allow "secured" code to access "privileged" functions and their (potentially unsecured) arguments. If `fun` is in strict mode, both `fun.caller` and `fun.arguments` are non-deletable properties which throw when set or retrieved:

```js
function restricted() {
  "use strict";
  restricted.caller; // throws a TypeError
  restricted.arguments; // throws a TypeError
}
function privilegedInvoker() {
  return restricted();
}
privilegedInvoker();
```

Similarly, `arguments.callee` is no longer supported. In sloppy mode, `arguments.callee` refers to the enclosing function. This use case is weak: name the enclosing function! Moreover, `arguments.callee` substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if `arguments.callee` is accessed. `arguments.callee` for strict mode functions is a non-deletable property which throws an error when set or retrieved:

```js
"use strict";
const f = function () {
  return arguments.callee;
};
f(); // throws a TypeError
```

### Future-proofing JavaScript

#### Extra reserved words

Reserved words are identifiers that can't be used as variable names. Strict mode reserves some more names than sloppy mode, some of which are already used in the language, and some of which are reserved for the future to make future syntax extensions easier to implement.

* `implements`
* `interface`
* `let`
* `package`
* `private`
* `protected`
* `public`
* `static`
* `yield`
Transitioning to strict mode
----------------------------

Strict mode has been designed so that the transition to it can be made gradually. It is possible to change each file individually and even to transition code to strict mode down to the function granularity.

You can migrate a codebase to strict mode by first adding `"use strict"` to a piece of source code, and then fixing all execution errors, while watching out for semantic differences.

### Syntax errors

When adding `'use strict';`, the following cases will throw a `SyntaxError` before the script is executing:

* Octal syntax `const n = 023;`
* `with` statement
* Using `delete` on a variable name `delete myVariable`;
* Using `eval` or `arguments` as variable or function argument name
* Using one of the newly reserved keywords (in prevision for future language features): `implements`, `interface`, `let`, `package`, `private`, `protected`, `public`, `static`, and `yield`
* Declaring two function parameters with the same name `function f(a, b, b) {}`
* Declaring the same property name twice in an object literal `{a: 1, b: 3, a: 7}`. This constraint was later removed (bug 1041128).

These errors are good, because they reveal plain errors or bad practices. They occur before the code is running, so they are easily discoverable as long as the code gets parsed by the runtime.

### New runtime errors

JavaScript used to silently fail in contexts where what was done should be an error. Strict mode throws in such cases. If your code base contains such cases, testing will be necessary to be sure nothing is broken. You can screen for such errors at the function granularity level.

* Assigning to an undeclared variable throws a `ReferenceError`. This used to set a property on the global object, which is rarely the expected effect. If you really want to set a value to the global object, explicitly assign it as a property on `globalThis`.
* Failing to assign to an object's property (e.g. it's read-only) throws a `TypeError`. In sloppy mode, this would silently fail.
* Deleting a non-deletable property throws a `TypeError`. In sloppy mode, this would silently fail.
* Accessing `arguments.callee`, `strictFunction.caller`, or `strictFunction.arguments` throws a `TypeError` if the function is in strict mode. If you are using `arguments.callee` to call the function recursively, you can use a named function expression instead.
### Semantic differences

These differences are very subtle differences. It's possible that a test suite doesn't catch this kind of subtle difference. Careful review of your code base will probably be necessary to be sure these differences don't affect the semantics of your code. Fortunately, this careful review can be done gradually down the function granularity.

`this`

In sloppy mode, function calls like `f()` would pass the global object as the `this` value. In strict mode, it is now `undefined`. When a function was called with `call` or `apply`, if the value was a primitive value, this one was boxed into an object (or the global object for `undefined` and `null`). In strict mode, the value is passed directly without conversion or replacement.

`arguments`

In sloppy mode, modifying a value in the `arguments` object modifies the corresponding named argument. This made optimizations complicated for JavaScript engine and made code harder to read/understand. In strict mode, the `arguments` object is created and initialized with the same values than the named arguments, but changes to either the `arguments` object or the named arguments aren't reflected in one another.

`eval`

In strict mode code, `eval` doesn't create a new variable in the scope from which it was called. Also, of course, in strict mode, the string is evaluated with strict mode rules. Thorough testing will need to be performed to make sure nothing breaks. Not using eval if you don't really need it may be another pragmatic solution.

Block-scoped function declarations

In sloppy mode, a function declaration inside a block may be visible outside the block and even callable. In strict mode, a function declaration inside a block is only visible inside the block.

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

| Specification |
| --- |
| ECMAScript Language Specification  |

See also
--------

* JavaScript modules guide
* Lexical grammar


Lexical grammar - JavaScript

Lexical grammar
===============

This page describes JavaScript's lexical grammar. JavaScript source text is just a sequence of characters — in order for the interpreter to understand it, the string has to be *parsed* to a more structured representation. The initial step of parsing is called lexical analysis, in which the text gets scanned from left to right and is converted into a sequence of individual, atomic input elements. Some input elements are insignificant to the interpreter, and will be stripped after this step — they include white space and comments. The others, including identifiers, keywords, literals, and punctuators (mostly operators), will be used for further syntax analysis. Line terminators and multiline comments are also syntactically insignificant, but they guide the process for automatic semicolons insertion to make certain invalid token sequences become valid.

Format-control characters
-------------------------

Format-control characters have no visual representation but are used to control the interpretation of the text.

| Code point | Name | Abbreviation | Description |
| --- | --- | --- | --- |
| U+200C | Zero width non-joiner | <ZWNJ> | Placed between characters to prevent being connected into ligatures in certain languages (Wikipedia). |
| U+200D | Zero width joiner | <ZWJ> | Placed between characters that would not normally be connected in order to cause the characters to be rendered using their connected form in certain languages (Wikipedia). |
| U+FEFF | Byte order mark | <BOM> | Used at the start of the script to mark it as Unicode and the text's byte order (Wikipedia). |

In JavaScript source text, <ZWNJ> and <ZWJ> are treated as identifier parts, while <BOM> (also called a zero-width no-break space <ZWNBSP> when not at the start of text) is treated as white space.

White space
-----------

White space characters improve the readability of source text and separate tokens from each other. These characters are usually unnecessary for the functionality of the code. Minification tools are often used to remove whitespace in order to reduce the amount of data that needs to be transferred.

| Code point | Name | Abbreviation | Description | Escape sequence |
| --- | --- | --- | --- | --- |
| U+0009 | Character tabulation | <TAB> | Horizontal tabulation | \t |
| U+000B | Line tabulation | <VT> | Vertical tabulation | \v |
| U+000C | Form feed | <FF> | Page breaking control character (Wikipedia). | \f |
| U+0020 | Space | <SP> | Normal space |  |
| U+00A0 | No-break space | <NBSP> | Normal space, but no point at which a line may break |  |
| U+FEFF | Zero-width no-break space | <ZWNBSP> | When not at the start of a script, the BOM marker is a normal whitespace character. |  |
| Others | Other Unicode space characters | <USP> | Characters in the "Space\_Separator" general category |  |

**Note:** Of those characters with the "White\_Space" property but are not in the "Space\_Separator" general category, U+0009, U+000B, and U+000C are still treated as white space in JavaScript; U+0085 NEXT LINE has no special role; others become the set of line terminators.

**Note:** Changes to the Unicode standard used by the JavaScript engine may affect programs' behavior. For example, ES2016 upgraded the reference Unicode standard from 5.1 to 8.0.0, which caused U+180E MONGOLIAN VOWEL SEPARATOR to be moved from the "Space\_Separator" category to the "Format (Cf)" category, and made it a non-whitespace. Subsequently, the result of `"\u180E".trim().length` changed from `0` to `1`.

Line terminators
----------------

In addition to white space characters, line terminator characters are used to improve the readability of the source text. However, in some cases, line terminators can influence the execution of JavaScript code as there are a few places where they are forbidden. Line terminators also affect the process of automatic semicolon insertion.

Outside the context of lexical grammar, white space and line terminators are often conflated. For example, `String.prototype.trim()` removes all white space and line terminators from the beginning and end of a string. The `\s` character class escape in regular expressions matches all white space and line terminators.

Only the following Unicode code points are treated as line terminators in ECMAScript, other line breaking characters are treated as white space (for example, Next Line, NEL, U+0085 is considered as white space).

| Code point | Name | Abbreviation | Description | Escape sequence |
| --- | --- | --- | --- | --- |
| U+000A | Line Feed | <LF> | New line character in UNIX systems. | \n |
| U+000D | Carriage Return | <CR> | New line character in Commodore and early Mac systems. | \r |
| U+2028 | Line Separator | <LS> | Wikipedia |  |
| U+2029 | Paragraph Separator | <PS> | Wikipedia |  |

Comments
--------

Comments are used to add hints, notes, suggestions, or warnings to JavaScript code. This can make it easier to read and understand. They can also be used to disable code to prevent it from being executed; this can be a valuable debugging tool.

JavaScript has two long-standing ways to add comments to code: line comments and block comments. In addition, there's a special hashbang comment syntax.

### Line comments

The first way is the `//` comment; this makes all text following it on the same line into a comment. For example:

```js
function comment() {
  // This is a one line JavaScript comment
  console.log("Hello world!");
}
comment();
```

### Block comments

The second way is the `/* */` style, which is much more flexible.

For example, you can use it on a single line:

```js
function comment() {
  /\* This is a one line JavaScript comment \*/
  console.log("Hello world!");
}
comment();
```

You can also make multiple-line comments, like this:

```js
function comment() {
  /\* This comment spans multiple lines. Notice
 that we don't need to end the comment until we're done. \*/
  console.log("Hello world!");
}
comment();
```

You can also use it in the middle of a line, if you wish, although this can make your code harder to read so it should be used with caution:

```js
function comment(x) {
  console.log("Hello " + x /\* insert the value of x \*/ + " !");
}
comment("world");
```

In addition, you can use it to disable code to prevent it from running, by wrapping code in a comment, like this:

```js
function comment() {
  /\* console.log("Hello world!"); \*/
}
comment();
```

In this case, the `console.log()` call is never issued, since it's inside a comment. Any number of lines of code can be disabled this way.

Block comments that contain at least one line terminator behave like line terminators in automatic semicolon insertion.

### Hashbang comments

There's a special third comment syntax, the **hashbang comment**. A hashbang comment behaves exactly like a single line-only (`//`) comment, except that it begins with `#!` and **is only valid at the absolute start of a script or module**. Note also that no whitespace of any kind is permitted before the `#!`. The comment consists of all the characters after `#!` up to the end of the first line; only one such comment is permitted.

Hashbang comments in JavaScript resemble shebangs in Unix which provide the path to a specific JavaScript interpreter that you want to use to execute the script. Before the hashbang comment became standardized, it had already been de-facto implemented in non-browser hosts like Node.js, where it was stripped from the source text before being passed to the engine. An example is as follows:

```js
#!/usr/bin/env node

console.log("Hello world");
```

The JavaScript interpreter will treat it as a normal comment — it only has semantic meaning to the shell if the script is directly run in a shell.

**Warning:** If you want scripts to be runnable directly in a shell environment, encode them in UTF-8 without a BOM. Although a BOM will not cause any problems for code running in a browser — because it's stripped during UTF-8 decoding, before the source text is analyzed — a Unix/Linux shell will not recognize the hashbang if it's preceded by a BOM character.

You must only use the `#!` comment style to specify a JavaScript interpreter. In all other cases just use a `//` comment (or multiline comment).

Identifiers
-----------

An *identifier* is used to link a value with a name. Identifiers can be used in various places:

```js
const decl = 1; // Variable declaration (may also be `let` or `var`)
function fn() {} // Function declaration
const obj = { key: "value" }; // Object keys
// Class declaration
class C {
  #priv = "value"; // Private property
}
lbl: console.log(1); // Label
```

In JavaScript, identifiers are commonly made of alphanumeric characters, underscores (`_`), and dollar signs (`$`). Identifiers are not allowed to start with numbers. However, JavaScript identifiers are not only limited to ASCII — many Unicode code points are allowed as well. Namely, any character in the ID\_Start category can start an identifier, while any character in the ID\_Continue category can appear after the first character.

**Note:** If, for some reason, you need to parse some JavaScript source yourself, do not assume all identifiers follow the pattern `/[A-Za-z_$][\w$]*/` (i.e. ASCII-only)! The range of identifiers can be described by the regex `/[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u` (excluding unicode escape sequences).

In addition, JavaScript allows using Unicode escape sequences in the form of `\u0000` or `\u{000000}` in identifiers, which encode the same string value as the actual Unicode characters. For example, `你好` and `\u4f60\u597d` are the same identifiers:

```js
const 你好 = "Hello";
console.log(\u4f60\u597d); // Hello
```

Not all places accept the full range of identifiers. Certain syntaxes, such as function declarations, function expressions, and variable declarations require using identifiers names that are not reserved words.

```js
function import() {} // Illegal: import is a reserved word.
```

Most notably, private properties and object properties allow reserved words.

```js
const obj = { import: "value" }; // Legal despite `import` being reserved
class C {
  #import = "value";
}
```

Keywords
--------

*Keywords* are tokens that look like identifiers but have special meanings in JavaScript. For example, the keyword `async` before a function declaration indicates that the function is asynchronous.

Some keywords are *reserved*, meaning that they cannot be used as an identifier for variable declarations, function declarations, etc. They are often called *reserved words*. A list of these reserved words is provided below. Not all keywords are reserved — for example, `async` can be used as an identifier anywhere. Some keywords are only *contextually reserved* — for example, `await` is only reserved within the body of an async function, and `let` is only reserved in strict mode code, or `const` and `let` declarations.

Identifiers are always compared by *string value*, so escape sequences are interpreted. For example, this is still a syntax error:

```js
const els\u{65} = 1;
// `els\u{65}` encodes the same identifier as `else`
```

### Reserved words

These keywords cannot be used as identifiers for variables, functions, classes, etc. anywhere in JavaScript source.

* `break`
* `case`
* `catch`
* `class`
* `const`
* `continue`
* `debugger`
* `default`
* `delete`
* `do`
* `else`
* `export`
* `extends`
* `false`
* `finally`
* `for`
* `function`
* `if`
* `import`
* `in`
* `instanceof`
* `new`
* `null`
* `return`
* `super`
* `switch`
* `this`
* `throw`
* `true`
* `try`
* `typeof`
* `var`
* `void`
* `while`
* `with`

The following are only reserved when they are found in strict mode code:

* `let` (also reserved in `const`, `let`, and class declarations)
* `static`
* `yield` (also reserved in generator function bodies)

The following are only reserved when they are found in module code or async function bodies:

* `await`
### Future reserved words

The following are reserved as future keywords by the ECMAScript specification. They have no special functionality at present, but they might at some future time, so they cannot be used as identifiers.

These are always reserved:

* `enum`

The following are only reserved when they are found in strict mode code:

* `implements`
* `interface`
* `package`
* `private`
* `protected`
* `public`

#### Future reserved words in older standards

The following are reserved as future keywords by older ECMAScript specifications (ECMAScript 1 till 3).

* `abstract`
* `boolean`
* `byte`
* `char`
* `double`
* `final`
* `float`
* `goto`
* `int`
* `long`
* `native`
* `short`
* `synchronized`
* `throws`
* `transient`
* `volatile`
### Identifiers with special meanings

A few identifiers have a special meaning in some contexts without being reserved words of any kind. They include:

* `arguments` (not a keyword, but cannot be declared as identifier in strict mode)
* `as` (`import * as ns from "mod"`)
* `async`
* `eval` (not a keyword, but cannot be declared as identifier in strict mode)
* `from` (`import x from "mod"`)
* `get`
* `of`
* `set`
Literals
--------

**Note:** This section discusses literals that are atomic tokens. Object literals and array literals are expressions that consist of a series of tokens.

### Null literal

See also `null` for more information.

```js
null
```

### Boolean literal

See also boolean type for more information.

```js
true
false
```

### Numeric literals

The Number and BigInt types use numeric literals.

#### Decimal

```js
1234567890
42
```

Decimal literals can start with a zero (`0`) followed by another decimal digit, but if all digits after the leading `0` are smaller than 8, the number is interpreted as an octal number. This is considered a legacy syntax, and number literals prefixed with `0`, whether interpreted as octal or decimal, cause a syntax error in strict mode — so, use the `0o` prefix instead.

```js
0888 // 888 parsed as decimal
0777 // parsed as octal, 511 in decimal
```

##### Exponential

The decimal exponential literal is specified by the following format: `beN`; where `b` is a base number (integer or floating), followed by an `E` or `e` character (which serves as separator or *exponent indicator*) and `N`, which is *exponent* or *power* number – a signed integer.

```js
0e-5   // 0
0e+5   // 0
5e1    // 50
175e-2 // 1.75
1e3    // 1000
1e-3   // 0.001
1E3    // 1000
```

#### Binary

Binary number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "B" (`0b` or `0B`). Any character after the `0b` that is not 0 or 1 will terminate the literal sequence.

```js
0b10000000000000000000000000000000 // 2147483648
0b01111111100000000000000000000000 // 2139095040
0B00000000011111111111111111111111 // 8388607
```

#### Octal

Octal number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "O" (`0o` or `0O)`. Any character after the `0o` that is outside the range (01234567) will terminate the literal sequence.

```js
0O755 // 493
0o644 // 420
```

#### Hexadecimal

Hexadecimal number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "X" (`0x` or `0X`). Any character after the `0x` that is outside the range (0123456789ABCDEF) will terminate the literal sequence.

```js
0xFFFFFFFFFFFFFFFFF // 295147905179352830000
0x123456789ABCDEF   // 81985529216486900
0XA                 // 10
```

#### BigInt literal

The BigInt type is a numeric primitive in JavaScript that can represent integers with arbitrary precision. BigInt literals are created by appending `n` to the end of an integer.

```js
123456789123456789n     // 123456789123456789
0o777777777777n         // 68719476735
0x123456789ABCDEFn      // 81985529216486895
0b11101001010101010101n // 955733
```

BigInt literals cannot start with `0` to avoid confusion with legacy octal literals.

```js
0755n; // SyntaxError: invalid BigInt syntax
```

For octal `BigInt` numbers, always use zero followed by the letter "o" (uppercase or lowercase):

```js
0o755n;
```

For more information about `BigInt`, see also JavaScript data structures.

#### Numeric separators

To improve readability for numeric literals, underscores (`_`, `U+005F`) can be used as separators:

```js
1\_000\_000\_000\_000
1\_050.95
0b1010\_0001\_1000\_0101
0o2\_2\_5\_6
0xA0\_B0\_C0
1\_000\_000\_000\_000\_000\_000\_000n
```

Note these limitations:

```js
// More than one underscore in a row is not allowed
100__000; // SyntaxError

// Not allowed at the end of numeric literals
100_; // SyntaxError

// Can not be used after leading 0
0\_1; // SyntaxError
```

### String literals

A string literal is zero or more Unicode code points enclosed in single or double quotes. Unicode code points may also be represented by an escape sequence. All code points may appear literally in a string literal except for these code points:

* U+005C \ (backslash)
* U+000D <CR>
* U+000A <LF>
* The same kind of quote that begins the string literal

Any code points may appear in the form of an escape sequence. String literals evaluate to ECMAScript String values. When generating these String values Unicode code points are UTF-16 encoded.

```js
'foo'
"bar"
```

The following subsections describe various escape sequences (`\` followed by one or more characters) available in string literals. Any escape sequence not listed below becomes an "identity escape" that becomes the code point itself. For example, `\z` is the same as `z`. There's a deprecated octal escape sequence syntax described in the Deprecated and obsolete features page. Many of these escape sequences are also valid in regular expressions — see Character escape.

#### Escape sequences

Special characters can be encoded using escape sequences:

| Escape sequence | Unicode code point |
| --- | --- |
| `\0` | null character (U+0000 NULL) |
| `\'` | single quote (U+0027 APOSTROPHE) |
| `\"` | double quote (U+0022 QUOTATION MARK) |
| `\\` | backslash (U+005C REVERSE SOLIDUS) |
| `\n` | newline (U+000A LINE FEED; LF) |
| `\r` | carriage return (U+000D CARRIAGE RETURN; CR) |
| `\v` | vertical tab (U+000B LINE TABULATION) |
| `\t` | tab (U+0009 CHARACTER TABULATION) |
| `\b` | backspace (U+0008 BACKSPACE) |
| `\f` | form feed (U+000C FORM FEED) |
| `\` followed by a line terminator | empty string |

The last escape sequence, `\` followed by a line terminator, is useful for splitting a string literal across multiple lines without changing its meaning.

```js
const longString =
  "This is a very long string which needs \
to wrap across multiple lines because \
otherwise my code is unreadable.";
```

Make sure there is no space or any other character after the backslash (except for a line break), otherwise it will not work. If the next line is indented, the extra spaces will also be present in the string's value.

You can also use the `+` operator to append multiple strings together, like this:

```js
const longString =
  "This is a very long string which needs " +
  "to wrap across multiple lines because " +
  "otherwise my code is unreadable.";
```

Both of the above methods result in identical strings.

#### Hexadecimal escape sequences

Hexadecimal escape sequences consist of `\x` followed by exactly two hexadecimal digits representing a code unit or code point in the range 0x0000 to 0x00FF.

```js
"\xA9"; // "©"
```

#### Unicode escape sequences

A Unicode escape sequence consists of exactly four hexadecimal digits following `\u`. It represents a code unit in the UTF-16 encoding. For code points U+0000 to U+FFFF, the code unit is equal to the code point. Code points U+10000 to U+10FFFF require two escape sequences representing the two code units (a surrogate pair) used to encode the character; the surrogate pair is distinct from the code point.

See also `String.fromCharCode()` and `String.prototype.charCodeAt()`.

```js
"\u00A9"; // "©" (U+A9)
```

#### Unicode code point escapes

A Unicode code point escape consists of `\u{`, followed by a code point in hexadecimal base, followed by `}`. The value of the hexadecimal digits must be in the range 0 and 0x10FFFF inclusive. Code points in the range U+10000 to U+10FFFF do not need to be represented as a surrogate pair.

See also `String.fromCodePoint()` and `String.prototype.codePointAt()`.

```js
"\u{2F804}"; // CJK COMPATIBILITY IDEOGRAPH-2F804 (U+2F804)

// the same character represented as a surrogate pair
"\uD87E\uDC04";
```

### Regular expression literals

Regular expression literals are enclosed by two forward slashes (`/`). The lexer consumes all characters up to the next unescaped forward slash or the end of the line, unless the forward slash appears within a character class (`[]`). Some characters (namely, those that are identifier parts) can appear after the closing slash, denoting flags.

The lexical grammar is very lenient: not all regular expression literals that get identified as one token are valid regular expressions.

See also `RegExp` for more information.

```js
/ab+c/g
/[/]/
```

A regular expression literal cannot start with two forward slashes (`//`), because that would be a line comment. To specify an empty regular expression, use `/(?:)/`.

### Template literals

One template literal consists of several tokens: ``xxx${` (template head), `}xxx${` (template middle), and `}xxx`` (template tail) are individual tokens, while any expression may come between them.

See also template literals for more information.

```js
`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag`string text ${expression} string text`
```

Automatic semicolon insertion
-----------------------------

Some JavaScript statements' syntax definitions require semicolons (`;`) at the end. They include:

* `var`, `let`, `const`
* Expression statements
* `do...while`
* `continue`, `break`, `return`, `throw`
* `debugger`
* Class field declarations (public or private)
* `import`, `export`

However, to make the language more approachable and convenient, JavaScript is able to automatically insert semicolons when consuming the token stream, so that some invalid token sequences can be "fixed" to valid syntax. This step happens after the program text has been parsed to tokens according to the lexical grammar. There are three cases when semicolons are automatically inserted:

1. When a token not allowed by the grammar is encountered, and it's separated from the previous token by at least one line terminator (including a block comment that includes at least one line terminator), or the token is "}", then a semicolon is inserted before the token.

```js
{ 1
2 } 3

// is transformed by ASI into:

{ 1
;2 ;} 3;

// Which is valid grammar encoding three statements,
// each consisting of a number literal
```

The ending ")" of `do...while` is taken care of as a special case by this rule as well.

```js
do {
  // ...
} while (condition) /\* ; \*/ // ASI here
const a = 1
```

However, semicolons are not inserted if the semicolon would then become the separator in the `for` statement's head.

```js
for (
  let a = 1 // No ASI here
  a < 10 // No ASI here
  a++
) {}
```

Semicolons are also never inserted as empty statements. For example, in the code below, if a semicolon is inserted after ")", then the code would be valid, with an empty statement as the `if` body and the `const` declaration being a separate statement. However, because automatically inserted semicolons cannot become empty statements, this causes a declaration to become the body of the `if` statement, which is not valid.

```js
if (Math.random() > 0.5)
const x = 1 // SyntaxError: Unexpected token 'const'
```

2. When the end of the input stream of tokens is reached, and the parser is unable to parse the single input stream as a complete program, a semicolon is inserted at the end.

```js
const a = 1 /\* ; \*/ // ASI here
```

This rule is a complement to the previous rule, specifically for the case where there's no "offending token" but the end of input stream.

3. When the grammar forbids line terminators in some place but a line terminator is found, a semicolon is inserted. These places include:

* `expr <here> ++`, `expr <here> --`
* `continue <here> lbl`
* `break <here> lbl`
* `return <here> expr`
* `throw <here> expr`
* `yield <here> expr`
* `yield <here> * expr`
* `(param) <here> => {}`
* `async <here> function`, `async <here> prop()`, `async <here> function*`, `async <here> *prop()`, `async <here> (param) <here> => {}`

Here `++` is not treated as a postfix operator applying to variable `b`, because a line terminator occurs between `b` and `++`.

```js
a = b
++c

// is transformed by ASI into

a = b;
++c;
```

Here, the `return` statement returns `undefined`, and the `a + b` becomes an unreachable statement.

```js
return
a + b

// is transformed by ASI into

return;
a + b;
```

Note that ASI would only be triggered if a line break separates tokens that would otherwise produce invalid syntax. If the next token can be parsed as part of a valid structure, semicolons would not be inserted. For example:

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

const b = 1
[1, 2, 3].forEach(console.log)
```

Because `()` can be seen as a function call, it would usually not trigger ASI. Similarly, `[]` may be a member access. The code above is equivalent to:

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

const b = 1[1, 2, 3].forEach(console.log);
```

This happens to be valid syntax. `1[1, 2, 3]` is a property accessor with a comma-joined expression. Therefore, you would get errors like "1 is not a function" and "Cannot read properties of undefined (reading 'forEach')" when running the code.

Within classes, class fields and generator methods can be a pitfall as well.

```js
class A {
  a = 1
  \*gen() {}
}
```

It is seen as:

```js
class A {
  a = 1 \* gen() {}
}
```

And therefore will be a syntax error around `{`.

There are the following rules-of-thumb for dealing with ASI, if you want to enforce semicolon-less style:

* Write postfix `++` and `--` on the same line as their operands.

```js
const a = b
++
console.log(a) // ReferenceError: Invalid left-hand side expression in prefix operation
```

```js
const a = b++
console.log(a)
```

* The expressions after `return`, `throw`, or `yield` should be on the same line as the keyword.

```js
function foo() {
  return
    1 + 1 // Returns undefined; 1 + 1 is ignored
}
```

```js
function foo() {
  return 1 + 1
}

function foo() {
  return (
    1 + 1
  )
}
```

* Similarly, the label identifier after `break` or `continue` should be on the same line as the keyword.

```js
outerBlock: {
  innerBlock: {
    break
      outerBlock // SyntaxError: Illegal break statement
  }
}
```

```js
outerBlock: {
  innerBlock: {
    break outerBlock
  }
}
```

* The `=>` of an arrow function should be on the same line as the end of its parameters.

```js
const foo = (a, b)
  => a + b
```

```js
const foo = (a, b) =>
  a + b
```

* The `async` of async functions, methods, etc. cannot be directly followed by a line terminator.

```js
async
function foo() {}
```

```js
async function
foo() {}
```

* If a line starts with one of `(`, `[`, ```, `+`, `-`, `/` (as in regex literals), prefix it with a semicolon, or end the previous line with a semicolon.

```js
// The () may be merged with the previous line as a function call
(() => {
  // ...
})()

// The [ may be merged with the previous line as a property access
[1, 2, 3].forEach(console.log)

// The ` may be merged with the previous line as a tagged template literal
`string text ${data}`.match(pattern).forEach(console.log)

// The + may be merged with the previous line as a binary + expression
+a.toString()

// The - may be merged with the previous line as a binary - expression
-a.toString()

// The / may be merged with the previous line as a division expression
/pattern/.exec(str).forEach(console.log)
```

```js
;(() => {
  // ...
})()
;[1, 2, 3].forEach(console.log)
;`string text ${data}`.match(pattern).forEach(console.log)
;+a.toString()
;-a.toString()
;/pattern/.exec(str).forEach(console.log)
```

* Class fields should preferably always be ended with semicolons — in addition to the previous rule (which includes a field declaration followed by a computed property, since the latter starts with `[`), semicolons are also required between a field declaration and a generator method.

```js
class A {
  a = 1
  [b] = 2
  \*gen() {} // Seen as a = 1[b] = 2 \* gen() {}
}
```

```js
class A {
  a = 1;
  [b] = 2;
  \*gen() {}
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification  |

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

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

See also
--------

* Grammar and types guide
* Micro-feature from ES6, now in Firefox Aurora and Nightly: binary and octal numbers by Jeff Walden (2013)
* JavaScript character escape sequences by Mathias Bynens (2011)


Statements and declarations - JavaScript

Statements and declarations
===========================

JavaScript applications consist of statements with an appropriate syntax. A single statement may span multiple lines. Multiple statements may occur on a single line if each statement is separated by a semicolon. This isn't a keyword, but a group of keywords.

Statements and declarations by category
---------------------------------------

For an alphabetical listing see the sidebar on the left.

### Control flow

`return`

Specifies the value to be returned by a function.

`break`

Terminates the current loop, switch, or label statement and transfers program control to the statement following the terminated statement.

`continue`

Terminates execution of the statements in the current iteration of the current or labeled loop, and continues execution of the loop with the next iteration.

`throw`

Throws a user-defined exception.

`if...else`

Executes a statement if a specified condition is true. If the condition is false, another statement can be executed.

`switch`

Evaluates an expression, matching the expression's value to a case clause, and executes statements associated with that case.

`try...catch`

Marks a block of statements to try, and specifies a response, should an exception be thrown.

### Declaring variables

`var`

Declares a variable, optionally initializing it to a value.

`let`

Declares a block scope local variable, optionally initializing it to a value.

`const`

Declares a read-only named constant.

### Functions and classes

`function`

Declares a function with the specified parameters.

`function*`

Generator Functions enable writing iterators more easily.

`async function`

Declares an async function with the specified parameters.

`async function*`

Asynchronous Generator Functions enable writing async iterators more easily.

`class`

Declares a class.

### Iterations

`do...while`

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.

`for`

Creates a loop that consists of three optional expressions, enclosed in parentheses and separated by semicolons, followed by a statement executed in the loop.

`for...in`

Iterates over the enumerable properties of an object, in arbitrary order. For each distinct property, statements can be executed.

`for...of`

Iterates over iterable objects (including arrays, array-like objects, iterators and generators), invoking a custom iteration hook with statements to be executed for the value of each distinct property.

`for await...of`

Iterates over async iterable objects, array-like objects, iterators and generators, invoking a custom iteration hook with statements to be executed for the value of each distinct property.

`while`

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.

### Others

Empty

An empty statement is used to provide no statement, although the JavaScript syntax would expect one.

Block

A block statement is used to group zero or more statements. The block is delimited by a pair of curly braces.

Expression statement

An expression statement evaluates an expression and discards its result. It allows the expression to perform side effects, such as executing a function or updating a variable.

`debugger`

Invokes any available debugging functionality. If no debugging functionality is available, this statement has no effect.

`export`

Used to export functions to make them available for imports in external modules, and other scripts.

`import`

Used to import functions exported from an external module, another script.

label

Provides a statement with an identifier that you can refer to using a `break` or `continue` statement.

`with`
Deprecated

Extends the scope chain for a statement.

Difference between statements and declarations
----------------------------------------------

In this section, we will be mixing two kinds of constructs: *statements* and *declarations*. They are two disjoint sets of grammars. The following are declarations:

* `let`
* `const`
* `function`
* `function*`
* `async function`
* `async function*`
* `class`
* `export` (Note: it can only appear at the top-level of a module)
* `import` (Note: it can only appear at the top-level of a module)

Everything else in the list above is a statement.

The terms "statement" and "declaration" have a precise meaning in the formal syntax of JavaScript that affects where they may be placed in code. For example, in most control-flow structures, the body only accepts statements — such as the two arms of an `if...else`:

```js
if (condition)
  statement1;
else
  statement2;
```

If you use a declaration instead of a statement, it would be a `SyntaxError`. For example, a `let` declaration is not a statement, so you can't use it in its bare form as the body of an `if` statement.

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

On the other hand, `var` is a statement, so you can use it on its own as the `if` body.

```js
if (condition)
  var i = 0;
```

You can see declarations as "binding identifiers to values", and statements as "carrying out actions". The fact that `var` is a statement instead of a declaration is a special case, because it doesn't follow normal lexical scoping rules and may create side effects — in the form of creating global variables, mutating existing `var`-defined variables, and defining variables that are visible outside of its block (because `var`-defined variables aren't block-scoped).

As another example, labels can only be attached to statements.

```js
label: const a = 1; // SyntaxError: Lexical declaration cannot appear in a single-statement context
```

**Note:** there's a legacy grammar that allows function declarations to have labels, but it's only standardized for compatibility with web reality.

To get around this, you can wrap the declaration in braces — this makes it part of a block statement.

```js
label: {
  const a = 1;
}

if (condition) {
  let i = 0;
}
```

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

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

See also
--------

* Expressions and operators