set - JavaScript

set
===

The **`set`** syntax binds an object property to a function to be called when there is an attempt to set that property. It can also be used in classes.

Try it
------

Syntax
------

```js
{ set prop(val) { /\* … \*/ } }
{ set [expression](val) { /\* … \*/ } }
```

There are some additional syntax restrictions:

* A setter must have exactly one parameter.
### Parameters

`prop`

The name of the property to bind to the given function. In the same way as other properties in object initializers, it can be a string literal, a number literal, or an identifier.

`val`

 An alias for the variable that holds the value attempted to be assigned to
 `prop`.

`expression`

You can also use expressions for a computed property name to bind to the given function.

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

In JavaScript, a setter can be used to execute a function whenever an attempt is made to change a property's value. Setters are most often used in conjunction with getters.

An object property is either a data property or an accessor property, but it cannot simultaneously be both. Read `Object.defineProperty()` for more information. The setter syntax allows you to specify the setter function in an object initializer.

```js
const obj = {
  set prop() {
    // setter, the code executed when setting obj.prop
  },
}
```

Properties defined using this syntax are own properties of the created object, and they are configurable and enumerable.

Examples
--------

### Defining a setter on new objects in object initializers

 The following example defines a pseudo-property `current` of object
 `language`. When `current` is assigned a value, it updates
 `log` with that value:

```js
const language = {
  set current(name) {
    this.log.push(name);
  },
  log: [],
};

language.current = "EN";
console.log(language.log); // ['EN']

language.current = "FA";
console.log(language.log); // ['EN', 'FA']
```

 Note that `current` is not defined, and any attempts to access it will
 result in `undefined`.

### Using setters in classes

You can use the exact same syntax to define public instance setters that are available on class instances. In classes, you don't need the comma separator between methods.

```js
class ClassWithGetSet {
  #msg = "hello world";
  get msg() {
    return this.#msg;
  }
  set msg(x) {
    this.#msg = `hello ${x}`;
  }
}

const instance = new ClassWithGetSet();
console.log(instance.msg); // "hello world"

instance.msg = "cake";
console.log(instance.msg); // "hello cake"
```

Setter properties are defined on the `prototype` property of the class and are thus shared by all instances of the class. Unlike setter properties in object literals, setter properties in classes are not enumerable.

Static setters and private setters use similar syntaxes, which are described in the `static` and private properties pages.

### Removing a setter with the `delete` operator

 If you want to remove the setter, you can just `delete`
 it:

```js
delete language.current;
```

### Defining a setter on existing objects using `defineProperty`

 To append a setter to an *existing* object, use
 `Object.defineProperty()`.

```js
const o = { a: 0 };

Object.defineProperty(o, "b", {
  set(x) {
    this.a = x / 2;
  },
});

o.b = 10;
// Runs the setter, which assigns 10 / 2 (5) to the 'a' property

console.log(o.a); // 5
```

### Using a computed property name

```js
const expr = "foo";

const obj = {
  baz: "bar",
  set [expr](v) {
    this.baz = v;
  },
};

console.log(obj.baz); // "bar"

obj.foo = "baz";
// Run the setter

console.log(obj.baz); // "baz"
```

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

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

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

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

See also
--------

* Working with objects guide
* Functions
* `get`
* `Object.defineProperty()`
* Object initializer
* `class`
* Property accessors
* Incompatible ES5 change: literal getter and setter functions must now have exactly zero or one arguments by Jeff Walden (2010)
* More SpiderMonkey changes: ancient, esoteric, very rarely used syntax for creating getters and setters is being removed by Jeff Walden (2010)


The arguments object - JavaScript

The arguments object
====================

**`arguments`** is an array-like object accessible inside functions that contains the values of the arguments passed to that function.

Try it
------

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

**Note:** In modern code, rest parameters should be preferred.

The `arguments` object is a local variable available within all non-arrow functions. You can refer to a function's arguments inside that function by using its `arguments` object. It has entries for each argument the function was called with, with the first entry's index at `0`.

For example, if a function is passed 3 arguments, you can access them as follows:

```js
arguments[0]; // first argument
arguments[1]; // second argument
arguments[2]; // third argument
```

The `arguments` object is useful for functions called with more arguments than they are formally declared to accept, called *variadic functions*, such as `Math.min()`. This example function accepts any number of string arguments and returns the longest one:

```js
function longestString() {
  let longest = "";
  for (let i = 0; i < arguments.length; i++) {
    if (arguments[i].length > longest.length) {
      longest = arguments[i];
    }
  }
  return longest;
}
```

You can use `arguments.length` to count how many arguments the function was called with. If you instead want to count how many parameters a function is declared to accept, inspect that function's `length` property.

### Assigning to indices

Each argument index can also be set or reassigned:

```js
arguments[1] = "new value";
```

Non-strict functions that only have simple parameters (that is, no rest, default, or destructured parameters) will sync the new value of parameters with the `arguments` object, and vice versa:

```js
function func(a) {
  arguments[0] = 99; // updating arguments[0] also updates a
  console.log(a);
}
func(10); // 99

function func2(a) {
  a = 99; // updating a also updates arguments[0]
  console.log(arguments[0]);
}
func2(10); // 99
```

Non-strict functions that *are* passed rest, default, or destructured parameters will not sync new values assigned to parameters in the function body with the `arguments` object. Instead, the `arguments` object in non-strict functions with complex parameters will always reflect the values passed to the function when the function was called.

```js
function funcWithDefault(a = 55) {
  arguments[0] = 99; // updating arguments[0] does not also update a
  console.log(a);
}
funcWithDefault(10); // 10

function funcWithDefault2(a = 55) {
  a = 99; // updating a does not also update arguments[0]
  console.log(arguments[0]);
}
funcWithDefault2(10); // 10

// An untracked default parameter
function funcWithDefault3(a = 55) {
  console.log(arguments[0]);
  console.log(arguments.length);
}
funcWithDefault3(); // undefined; 0
```

This is the same behavior exhibited by all strict-mode functions, regardless of the type of parameters they are passed. That is, assigning new values to parameters in the body of the function never affects the `arguments` object, nor will assigning new values to the `arguments` indices affect the value of parameters, even when the function only has simple parameters.

**Note:** You cannot write a `"use strict";` directive in the body of a function definition that accepts rest, default, or destructured parameters. Doing so will throw a syntax error.

### arguments is an array-like object

`arguments` is an array-like object, which means that `arguments` has a `length` property and properties indexed from zero, but it doesn't have `Array`'s built-in methods like `forEach()` or `map()`. However, it can be converted to a real `Array`, using one of `slice()`, `Array.from()`, or spread syntax.

```js
const args = Array.prototype.slice.call(arguments);
// or
const args = Array.from(arguments);
// or
const args = [...arguments];
```

For common use cases, using it as an array-like object is sufficient, since it both is iterable and has `length` and number indices. For example, `Function.prototype.apply()` accepts array-like objects.

```js
function midpoint() {
  return (
    (Math.min.apply(null, arguments) + Math.max.apply(null, arguments)) / 2
  );
}

console.log(midpoint(3, 1, 4, 1, 5)); // 3
```

Properties
----------

`arguments.callee`
Deprecated

Reference to the currently executing function that the arguments belong to. Forbidden in strict mode.

`arguments.length`

The number of arguments that were passed to the function.

`arguments[@@iterator]`

Returns a new Array iterator object that contains the values for each index in `arguments`.

Examples
--------

### Defining a function that concatenates several strings

This example defines a function that concatenates several strings. The function's only formal argument is a string containing the characters that separate the items to concatenate.

```js
function myConcat(separator) {
  const args = Array.prototype.slice.call(arguments, 1);
  return args.join(separator);
}
```

You can pass as many arguments as you like to this function. It returns a string list using each argument in the list:

```js
myConcat(", ", "red", "orange", "blue");
// "red, orange, blue"

myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
// "elephant; giraffe; lion; cheetah"

myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
// "sage. basil. oregano. pepper. parsley"
```

### Defining a function that creates HTML lists

This example defines a function that creates a string containing HTML for a list. The only formal argument for the function is a string that is `"u"` if the list is to be unordered (bulleted), or `"o"` if the list is to be ordered (numbered). The function is defined as follows:

```js
function list(type) {
  let html = `<${type}l><li>`;
  const args = Array.prototype.slice.call(arguments, 1);
  html += args.join("</li><li>");
  html += `</li></${type}l>`; // end list
  return html;
}
```

You can pass any number of arguments to this function, and it adds each argument as a list item to a list of the type indicated. For example:

```js
list("u", "One", "Two", "Three");
// "<ul><li>One</li><li>Two</li><li>Three</li></ul>"
```

### Using typeof with arguments

The `typeof` operator returns `'object'` when used with `arguments`

```js
console.log(typeof arguments); // 'object'
```

The type of individual arguments can be determined by indexing `arguments`:

```js
console.log(typeof arguments[0]); // returns the type of the first argument
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-arguments-exotic-objects |

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

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

See also
--------

* Functions guide
* Functions
* Rest parameters


get - JavaScript

get
===

The **`get`** syntax binds an object property to a function that will be called when that property is looked up. It can also be used in classes.

Try it
------

Syntax
------

```js
{ get prop() { /\* … \*/ } }
{ get [expression]() { /\* … \*/ } }
```

There are some additional syntax restrictions:

* A getter must have exactly zero parameters.
### Parameters

`prop`

The name of the property to bind to the given function. In the same way as other properties in object initializers, it can be a string literal, a number literal, or an identifier.

`expression`

You can also use expressions for a computed property name to bind to the given function.

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

Sometimes it is desirable to allow access to a property that returns a dynamically computed value, or you may want to reflect the status of an internal variable without requiring the use of explicit method calls. In JavaScript, this can be accomplished with the use of a *getter*.

An object property is either a data property or an accessor property, but it cannot simultaneously be both. Read `Object.defineProperty()` for more information. The getter syntax allows you to specify the getter function in an object initializer.

```js
const obj = {
  get prop() {
    // getter, the code executed when reading obj.prop
    return someValue;
  },
};
```

Properties defined using this syntax are own properties of the created object, and they are configurable and enumerable.

Examples
--------

### Defining a getter on new objects in object initializers

 This will create a pseudo-property `latest` for object `obj`,
 which will return the last array item in `log`.

```js
const obj = {
  log: ["example", "test"],
  get latest() {
    if (this.log.length === 0) return undefined;
    return this.log[this.log.length - 1];
  },
};
console.log(obj.latest); // "test"
```

Note that attempting to assign a value to `latest` will not change it.

### Using getters in classes

You can use the exact same syntax to define public instance getters that are available on class instances. In classes, you don't need the comma separator between methods.

```js
class ClassWithGetSet {
  #msg = "hello world";
  get msg() {
    return this.#msg;
  }
  set msg(x) {
    this.#msg = `hello ${x}`;
  }
}

const instance = new ClassWithGetSet();
console.log(instance.msg); // "hello world"

instance.msg = "cake";
console.log(instance.msg); // "hello cake"
```

Getter properties are defined on the `prototype` property of the class and are thus shared by all instances of the class. Unlike getter properties in object literals, getter properties in classes are not enumerable.

Static getters and private getters use similar syntaxes, which are described in the `static` and private properties pages.

### Deleting a getter using the `delete` operator

 If you want to remove the getter, you can just `delete`
 it:

```js
delete obj.latest;
```

### Defining a getter on existing objects using `defineProperty`

 To append a getter to an existing object later at any time, use
 `Object.defineProperty()`.

```js
const o = { a: 0 };

Object.defineProperty(o, "b", {
  get() {
    return this.a + 1;
  },
});

console.log(o.b); // Runs the getter, which yields a + 1 (which is 1)
```

### Using a computed property name

```js
const expr = "foo";

const obj = {
  get [expr]() {
    return "bar";
  },
};

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

### Defining static getters

```js
class MyConstants {
  static get foo() {
    return "foo";
  }
}

console.log(MyConstants.foo); // 'foo'
MyConstants.foo = "bar";
console.log(MyConstants.foo); // 'foo', a static getter's value cannot be changed
```

### Smart / self-overwriting / lazy getters

 Getters give you a way to *define* a property of an object, but they do not
 *calculate* the property's value until it is accessed. A getter defers the cost
 of calculating the value until the value is needed. If it is never needed, you never pay
 the cost.

 An additional optimization technique to lazify or delay the calculation of a property
 value and cache it for later access are *smart* (or *memoized*) getters.
 The value is calculated the first time the getter is called, and is then cached so
 subsequent accesses return the cached value without recalculating it. This is useful in
 the following situations:

* If the calculation of a property value is expensive (takes much RAM or CPU time,
 spawns worker threads, retrieves remote file, etc.).
* If the value isn't needed just now. It will be used later, or in some case it's not
 used at all.
* If it's used, it will be accessed several times, and there is no need to
 re-calculate that value will never be changed or shouldn't be re-calculated.

**Note:** This means that you shouldn't write a lazy getter for a property whose value you
 expect to change, because if the getter is lazy then it will not recalculate the
 value.

 Note that getters are not "lazy" or "memoized" by nature; you must implement this
 technique if you desire this behavior.

 In the following example, the object has a getter as its own property. On getting the
 property, the property is removed from the object and re-added, but implicitly as a data
 property this time. Finally, the value gets returned.

```js
const obj = {
  get notifier() {
    delete this.notifier;
    this.notifier = document.getElementById("bookmarked-notification-anchor");
    return this.notifier;
  },
};
```

### get vs. defineProperty

 While using the `get` keyword and `Object.defineProperty()` have
 similar results, there is a subtle difference between the two when used on
 `classes`.

 When using `get` the property will be defined on the instance's prototype,
 while using `Object.defineProperty()` the property will be defined on the
 instance it is applied to.

```js
class Example {
  get hello() {
    return "world";
  }
}

const obj = new Example();
console.log(obj.hello);
// "world"

console.log(Object.getOwnPropertyDescriptor(obj, "hello"));
// undefined

console.log(
  Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), "hello"),
);
// { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }
```

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

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

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

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

See also
--------

* Working with objects guide
* Functions
* `set`
* `Object.defineProperty()`
* Object initializer
* `class`
* Property accessors
* Incompatible ES5 change: literal getter and setter functions must now have exactly zero or one arguments by Jeff Walden (2010)
* More SpiderMonkey changes: ancient, esoteric, very rarely used syntax for creating getters and setters is being removed by Jeff Walden (2010)


Arrow function expressions - JavaScript

Arrow function expressions
==========================

An **arrow function expression** is a compact alternative to a traditional function expression, with some semantic differences and deliberate limitations in usage:

* Arrow functions don't have their own bindings to `this`, `arguments`, or `super`, and should not be used as methods.
* Arrow functions cannot be used as constructors. Calling them with `new` throws a `TypeError`. They also don't have access to the `new.target` keyword.
* Arrow functions cannot use `yield` within their body and cannot be created as generator functions.
Try it
------

Syntax
------

```js
() => expression

param => expression

(param) => expression

(param1, paramN) => expression

() => {
  statements
}

param => {
  statements
}

(param1, paramN) => {
  statements
}
```

Rest parameters, default parameters, and destructuring within params are supported, and always require parentheses:

```js
(a, b, ...r) => expression
(a = 400, b = 20, c) => expression
([a, b] = [10, 20]) => expression
({ a, b } = { a: 10, b: 20 }) => expression
```

Arrow functions can be `async` by prefixing the expression with the `async` keyword.

```js
async param => expression
async (param1, param2, ...paramN) => {
  statements
}
```

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

Let's decompose a traditional anonymous function down to the simplest arrow function step-by-step. Each step along the way is a valid arrow function.

**Note:** Traditional function expressions and arrow functions have more differences than their syntax. We will introduce their behavior differences in more detail in the next few subsections.

```js
// Traditional anonymous function
(function (a) {
  return a + 100;
});

// 1. Remove the word "function" and place arrow between the argument and opening body brace
(a) => {
  return a + 100;
};

// 2. Remove the body braces and word "return" — the return is implied.
(a) => a + 100;

// 3. Remove the parameter parentheses
a => a + 100;
```

In the example above, both the parentheses around the parameter and the braces around the function body may be omitted. However, they can only be omitted in certain cases.

The parentheses can only be omitted if the function has a single simple parameter. If it has multiple parameters, no parameters, or default, destructured, or rest parameters, the parentheses around the parameter list are required.

```js
// Traditional anonymous function
(function (a, b) {
  return a + b + 100;
});

// Arrow function
(a, b) => a + b + 100;

const a = 4;
const b = 2;

// Traditional anonymous function (no parameters)
(function () {
  return a + b + 100;
});

// Arrow function (no parameters)
() => a + b + 100;
```

The braces can only be omitted if the function directly returns an expression. If the body has additional lines of processing, the braces are required — and so is the `return` keyword. Arrow functions cannot guess what or when you want to return.

```js
// Traditional anonymous function
(function (a, b) {
  const chuck = 42;
  return a + b + chuck;
});

// Arrow function
(a, b) => {
  const chuck = 42;
  return a + b + chuck;
};
```

Arrow functions are always unnamed. If the arrow function needs to call itself, use a named function expression instead. You can also assign the arrow function to a variable so it has a name.

```js
// Traditional Function
function bob(a) {
  return a + 100;
}

// Arrow Function
const bob2 = (a) => a + 100;
```

### Function body

Arrow functions can have either an *expression body* or the usual *block body*.

In an expression body, only a single expression is specified, which becomes the implicit return value. In a block body, you must use an explicit `return` statement.

```js
const func = (x) => x \* x;
// expression body syntax, implied "return"

const func2 = (x, y) => {
  return x + y;
};
// with block body, explicit "return" needed
```

Returning object literals using the expression body syntax `(params) => { object: literal }` does not work as expected.

```js
const func = () => { foo: 1 };
// Calling func() returns undefined!

const func2 = () => { foo: function () {} };
// SyntaxError: function statement requires a name

const func3 = () => { foo() {} };
// SyntaxError: Unexpected token '{'
```

This is because JavaScript only sees the arrow function as having an expression body if the token following the arrow is not a left brace, so the code inside braces ({}) is parsed as a sequence of statements, where `foo` is a label, not a key in an object literal.

To fix this, wrap the object literal in parentheses:

```js
const func = () => ({ foo: 1 });
```

### Cannot be used as methods

Arrow function expressions should only be used for non-method functions because they do not have their own `this`. Let's see what happens when we try to use them as methods:

```js
"use strict";

const obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c() {
    console.log(this.i, this);
  },
};

obj.b(); // logs undefined, Window { /\* … \*/ } (or the global object)
obj.c(); // logs 10, Object { /\* … \*/ }
```

Another example involving `Object.defineProperty()`:

```js
"use strict";

const obj = {
  a: 10,
};

Object.defineProperty(obj, "b", {
  get: () => {
    console.log(this.a, typeof this.a, this); // undefined 'undefined' Window { /\* … \*/ } (or the global object)
    return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
  },
});
```

Because a class's body has a `this` context, arrow functions as class fields close over the class's `this` context, and the `this` inside the arrow function's body will correctly point to the instance (or the class itself, for static fields). However, because it is a closure, not the function's own binding, the value of `this` will not change based on the execution context.

```js
class C {
  a = 1;
  autoBoundMethod = () => {
    console.log(this.a);
  };
}

const c = new C();
c.autoBoundMethod(); // 1
const { autoBoundMethod } = c;
autoBoundMethod(); // 1
// If it were a normal method, it should be undefined in this case
```

Arrow function properties are often said to be "auto-bound methods", because the equivalent with normal methods is:

```js
class C {
  a = 1;
  constructor() {
    this.method = this.method.bind(this);
  }
  method() {
    console.log(this.a);
  }
}
```

**Note:** Class fields are defined on the *instance*, not on the *prototype*, so every instance creation would create a new function reference and allocate a new closure, potentially leading to more memory usage than a normal unbound method.

For similar reasons, the `call()`, `apply()`, and `bind()` methods are not useful when called on arrow functions, because arrow functions establish `this` based on the scope the arrow function is defined within, and the `this` value does not change based on how the function is invoked.

### No binding of arguments

Arrow functions do not have their own `arguments` object. Thus, in this example, `arguments` is a reference to the arguments of the enclosing scope:

```js
function foo(n) {
  const f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0] is n
  return f();
}

foo(3); // 3 + 3 = 6
```

**Note:** You cannot declare a variable called `arguments` in strict mode, so the code above would be a syntax error. This makes the scoping effect of `arguments` much easier to comprehend.

 In most cases, using rest parameters
 is a good alternative to using an `arguments` object.

```js
function foo(n) {
  const f = (...args) => args[0] + n;
  return f(10);
}

foo(1); // 11
```

### Cannot be used as constructors

Arrow functions cannot be used as constructors and will throw an error when called with `new`. They also do not have a `prototype` property.

```js
const Foo = () => {};
const foo = new Foo(); // TypeError: Foo is not a constructor
console.log("prototype" in Foo); // false
```

### Cannot be used as generators

The `yield` keyword cannot be used in an arrow function's body (except when used within generator functions further nested within the arrow function). As a consequence, arrow functions cannot be used as generators.

### Line break before arrow

An arrow function cannot contain a line break between its parameters and its arrow.

```js
const func = (a, b, c)
  => 1;
// SyntaxError: Unexpected token '=>'
```

For the purpose of formatting, you may put the line break after the arrow or use parentheses/braces around the function body, as shown below. You can also put line breaks between parameters.

```js
const func = (a, b, c) =>
  1;

const func2 = (a, b, c) => (
  1
);

const func3 = (a, b, c) => {
  return 1;
};

const func4 = (
  a,
 b,
 c,
) => 1;
```

### Precedence of arrow

Although the arrow in an arrow function is not an operator, arrow functions have special parsing rules that interact differently with operator precedence compared to regular functions.

```js
let callback;

callback = callback || () => {};
// SyntaxError: invalid arrow-function arguments
```

Because `=>` has a lower precedence than most operators, parentheses are necessary to avoid `callback || ()` being parsed as the arguments list of the arrow function.

```js
callback = callback || (() => {});
```

Examples
--------

### Using arrow functions

```js
// An empty arrow function returns undefined
const empty = () => {};

(() => "foobar")();
// Returns "foobar"
// (this is an Immediately Invoked Function Expression)

const simple = (a) => (a > 15 ? 15 : a);
simple(16); // 15
simple(10); // 10

const max = (a, b) => (a > b ? a : b);

// Easy array filtering, mapping, etc.
const arr = [5, 6, 13, 0, 1, 18, 23];

const sum = arr.reduce((a, b) => a + b);
// 66

const even = arr.filter((v) => v % 2 === 0);
// [6, 0, 18]

const double = arr.map((v) => v \* 2);
// [10, 12, 26, 0, 2, 36, 46]

// More concise promise chains
promise
  .then((a) => {
    // …
  })
  .then((b) => {
    // …
  });

// Parameterless arrow functions that are visually easier to parse
setTimeout(() => {
  console.log("I happen sooner");
  setTimeout(() => {
    // deeper code
    console.log("I happen later");
  }, 1);
}, 1);
```

### Using call, bind, and apply

The `call()`, `apply()`, and `bind()` methods work as expected with traditional functions, because we establish the scope for each of the methods:

```js
const obj = {
  num: 100,
};

// Setting "num" on globalThis to show how it is NOT used.
globalThis.num = 42;

// A simple traditional function to operate on "this"
const add = function (a, b, c) {
  return this.num + a + b + c;
};

console.log(add.call(obj, 1, 2, 3)); // 106
console.log(add.apply(obj, [1, 2, 3])); // 106
const boundAdd = add.bind(obj);
console.log(boundAdd(1, 2, 3)); // 106
```

With arrow functions, since our `add` function is essentially created on the `globalThis` (global) scope, it will assume `this` is the `globalThis`.

```js
const obj = {
  num: 100,
};

// Setting "num" on globalThis to show how it gets picked up.
globalThis.num = 42;

// Arrow function
const add = (a, b, c) => this.num + a + b + c;

console.log(add.call(obj, 1, 2, 3)); // 48
console.log(add.apply(obj, [1, 2, 3])); // 48
const boundAdd = add.bind(obj);
console.log(boundAdd(1, 2, 3)); // 48
```

Perhaps the greatest benefit of using arrow functions is with methods like `setTimeout()` and `EventTarget.prototype.addEventListener()` that usually require some kind of closure, `call()`, `apply()`, or `bind()` to ensure that the function is executed in the proper scope.

With traditional function expressions, code like this does not work as expected:

```js
const obj = {
  count: 10,
  doSomethingLater() {
    setTimeout(function () {
      // the function executes on the window scope
      this.count++;
      console.log(this.count);
    }, 300);
  },
};

obj.doSomethingLater(); // logs "NaN", because the property "count" is not in the window scope.
```

With arrow functions, the `this` scope is more easily preserved:

```js
const obj = {
  count: 10,
  doSomethingLater() {
    // The method syntax binds "this" to the "obj" context.
    setTimeout(() => {
      // Since the arrow function doesn't have its own binding and
      // setTimeout (as a function call) doesn't create a binding
      // itself, the "obj" context of the outer method is used.
      this.count++;
      console.log(this.count);
    }, 300);
  },
};

obj.doSomethingLater(); // logs 11
```

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

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

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

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

See also
--------

* Functions guide
* Functions
* `function`
* `function` expression
* ES6 In Depth: Arrow functions on hacks.mozilla.org (2015)


Rest parameters - JavaScript

Rest parameters
===============

The **rest parameter** syntax allows a function to accept an indefinite number of arguments as an array, providing a way to represent variadic functions in JavaScript.

Try it
------

Syntax
------

```js
function f(a, b, ...theArgs) {
  // …
}
```

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

A function definition's last parameter can be prefixed with `...` (three U+002E FULL STOP characters), which will cause all remaining (user supplied) parameters to be placed within an `Array` object.

```js
function myFun(a, b, ...manyMoreArgs) {
  console.log("a", a);
  console.log("b", b);
  console.log("manyMoreArgs", manyMoreArgs);
}

myFun("one", "two", "three", "four", "five", "six");

// Console Output:
// a, one
// b, two
// manyMoreArgs, ["three", "four", "five", "six"]
```

A function definition can only have one rest parameter, and the rest parameter must be the last parameter in the function definition.

```js
function wrong1(...one, ...wrong) {}
function wrong2(...wrong, arg2, arg3) {}
```

The rest parameter is not counted towards the function's `length` property.

### The difference between rest parameters and the arguments object

There are three main differences between rest parameters and the `arguments` object:

* The `arguments` object is **not a real array**, while rest parameters are `Array` instances, meaning methods like `sort()`, `map()`, `forEach()` or `pop()` can be applied on it directly.
* The `arguments` object has the additional (deprecated) `callee` property.
* In a non-strict function with simple parameters, the `arguments` object syncs its indices with the values of parameters. The rest parameter array never updates its value when the named parameters are re-assigned.
* The rest parameter bundles all the *extra* parameters into a single array, but does not contain any named argument defined *before* the `...restParam`. The `arguments` object contains all of the parameters — including the parameters in the `...restParam` array — bundled into one array-like object.
Examples
--------

### Using rest parameters

In this example, the first argument is mapped to `a` and the second to `b`, so these named arguments are used as normal.

However, the third argument, `manyMoreArgs`, will be an array that contains the third, fourth, fifth, sixth, …, nth — as many arguments as the user specifies.

```js
function myFun(a, b, ...manyMoreArgs) {
  console.log("a", a);
  console.log("b", b);
  console.log("manyMoreArgs", manyMoreArgs);
}

myFun("one", "two", "three", "four", "five", "six");

// a, "one"
// b, "two"
// manyMoreArgs, ["three", "four", "five", "six"] <-- an array
```

Below, even though there is just one value, the last argument still gets put into an array.

```js
// Using the same function definition from example above

myFun("one", "two", "three");

// a, "one"
// b, "two"
// manyMoreArgs, ["three"] <-- an array with just one value
```

Below, the third argument isn't provided, but `manyMoreArgs` is still an array (albeit an empty one).

```js
// Using the same function definition from example above

myFun("one", "two");

// a, "one"
// b, "two"
// manyMoreArgs, [] <-- still an array
```

Below, only one argument is provided, so `b` gets the default value `undefined`, but `manyMoreArgs` is still an empty array.

```js
// Using the same function definition from example above

myFun("one");

// a, "one"
// b, undefined
// manyMoreArgs, [] <-- still an array
```

### Argument length

Since `theArgs` is an array, a count of its elements is given by the `length` property. If the function's only parameter is a rest parameter, `restParams.length` will be equal to `arguments.length`.

```js
function fun1(...theArgs) {
  console.log(theArgs.length);
}

fun1(); // 0
fun1(5); // 1
fun1(5, 6, 7); // 3
```

### Using rest parameters in combination with ordinary parameters

In the next example, a rest parameter is used to collect all parameters after the first parameter into an array. Each one of the parameter values collected into the array is then multiplied by the first parameter, and the array is returned:

```js
function multiply(multiplier, ...theArgs) {
  return theArgs.map((element) => multiplier \* element);
}

const arr = multiply(2, 15, 25, 42);
console.log(arr); // [30, 50, 84]
```

### From arguments to an array

`Array` methods can be used on rest parameters, but not on the `arguments` object:

```js
function sortRestArgs(...theArgs) {
  const sortedArgs = theArgs.sort();
  return sortedArgs;
}

console.log(sortRestArgs(5, 3, 7, 1)); // 1, 3, 5, 7

function sortArguments() {
  const sortedArgs = arguments.sort();
  return sortedArgs; // this will never happen
}

console.log(sortArguments(5, 3, 7, 1));
// throws a TypeError (arguments.sort is not a function)
```

Rest parameters were introduced to reduce the boilerplate code that was commonly used for converting a set of arguments to an array.

Before rest parameters, `arguments` need to be converted to a normal array before calling array methods on them:

```js
function fn(a, b) {
  const normalArray = Array.prototype.slice.call(arguments);
  // — or —
  const normalArray2 = [].slice.call(arguments);
  // — or —
  const normalArrayFrom = Array.from(arguments);

  const first = normalArray.shift(); // OK, gives the first argument
  const firstBad = arguments.shift(); // ERROR (arguments is not a normal array)
}
```

Now, you can easily gain access to a normal array using a rest parameter:

```js
function fn(...args) {
  const normalArray = args;
  const first = normalArray.shift(); // OK, gives the first argument
}
```

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

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

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

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

See also
--------

* Functions guide
* Functions
* Spread syntax (`...`)
* Default parameters
* `arguments`
* `Array`


Method definitions - JavaScript

Method definitions
==================

**Method definition** is a shorter syntax for defining a function property in an object initializer. It can also be used in classes.

Try it
------

Syntax
------

```js
({
  property(parameters) {},
  \*generator(parameters) {},
  async property(parameters) {},
  async \*generator(parameters) {},

  // with computed keys
  [expression](parameters) {},
  \*[expression](parameters) {},
  async [expression](parameters) {},
  async \*[expression](parameters) {},
})
```

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

The shorthand syntax is similar to the getter and setter syntax.

Given the following code:

```js
const obj = {
  foo: function () {
    // …
  },
  bar: function () {
    // …
  },
};
```

You are now able to shorten this to:

```js
const obj = {
  foo() {
    // …
  },
  bar() {
    // …
  },
};
```

Properties defined using this syntax are own properties of the created object, and they are configurable, enumerable, and writable, just like normal properties.

`function*`, `async function`, and `async function*` properties all have their respective method syntaxes; see examples below.

However, note that the method syntax is not equivalent to a normal property with a function as its value — there are semantic differences. This makes methods defined in object literals more consistent with methods in classes.

### Method definitions are not constructable

Methods cannot be constructors! They will throw a `TypeError` if you try to instantiate them. On the other hand, a property created as a function can be used as a constructor.

```js
const obj = {
  method() {},
};
new obj.method(); // TypeError: obj.method is not a constructor
```

### Using super in method definitions

Only functions defined as methods have access to the `super` keyword. `super.prop` looks up the property on the prototype of the object that the method was initialized on.

```js
const obj = {
  \_\_proto\_\_: {
    prop: "foo",
  },
  notAMethod: function () {
    console.log(super.prop); // SyntaxError: 'super' keyword unexpected here
  },
};
```

Examples
--------

### Using method definitions

```js
const obj = {
  a: "foo",
  b() {
    return this.a;
  },
};
console.log(obj.b()); // "foo"
```

### Method definitions in classes

You can use the exact same syntax to define public instance methods that are available on class instances. In classes, you don't need the comma separator between methods.

```js
class ClassWithPublicInstanceMethod {
  publicMethod() {
    return "hello world";
  }
  secondPublicMethod() {
    return "goodbye world";
  }
}

const instance = new ClassWithPublicInstanceMethod();
console.log(instance.publicMethod()); // "hello world"
```

Public instance methods are defined on the `prototype` property of the class and are thus shared by all instances of the class. They are writable, non-enumerable, and configurable.

Inside instance methods, `this` and `super` work like in normal methods. Usually, `this` refers to the instance itself. In subclasses, `super` lets you access the prototype of the object that the method is attached to, allowing you to call methods from the superclass.

```js
class BaseClass {
  msg = "hello world";
  basePublicMethod() {
    return this.msg;
  }
}

class SubClass extends BaseClass {
  subPublicMethod() {
    return super.basePublicMethod();
  }
}

const instance = new SubClass();
console.log(instance.subPublicMethod()); // "hello world"
```

Static methods and private methods use similar syntaxes, which are described in the `static` and private properties pages.

### Computed property names

The method syntax also supports computed property names.

```js
const bar = {
  foo0: function () {
    return 0;
  },
  foo1() {
    return 1;
  },
  ["foo" + 2]() {
    return 2;
  },
};

console.log(bar.foo0()); // 0
console.log(bar.foo1()); // 1
console.log(bar.foo2()); // 2
```

### Generator methods

Note that the asterisk (`*`) in the generator method syntax must be *before* the generator property name. (That is, `* g(){}` will work, but `g *(){}` will not.)

```js
// Using a named property
const obj = {
  g: function\* () {
    let index = 0;
    while (true) {
      yield index++;
    }
  },
};

// The same object using shorthand syntax
const obj2 = {
  \*g() {
    let index = 0;
    while (true) {
      yield index++;
    }
  },
};

const it = obj2.g();
console.log(it.next().value); // 0
console.log(it.next().value); // 1
```

### Async methods

```js
// Using a named property
const obj = {
  f: async function () {
    await somePromise;
  },
};

// The same object using shorthand syntax
const obj2 = {
  async f() {
    await somePromise;
  },
};
```

### Async generator methods

```js
const obj = {
  f: async function\* () {
    yield 1;
    yield 2;
    yield 3;
  },
};

// The same object using shorthand syntax
const obj2 = {
  async \*f() {
    yield 1;
    yield 2;
    yield 3;
  },
};
```

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

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

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

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

See also
--------

* Working with objects guide
* Functions
* `get`
* `set`
* Object initializer
* `class`


arguments.length - JavaScript

arguments.length
================

The **`arguments.length`** data property contains the number of arguments passed to the function.

Value
-----

A non-negative integer.

| Property attributes of `arguments.length` |
| --- |
| Writable | yes |
| Enumerable | no |
| Configurable | yes |

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

The `arguments.length` property provides the number of arguments actually passed to a function. This can be more or less than the defined parameter's count (see `Function.prototype.length`). For example, for the function below:

```js
function func1(a, b, c) {
  console.log(arguments.length);
}
```

`func1.length` returns `3`, because `func1` declares three formal parameters. However, `func1(1, 2, 3, 4, 5)` logs `5`, because `func1` was called with five arguments. Similarly, `func1(1)` logs `1`, because `func1` was called with one argument.

Examples
--------

### Using arguments.length

In this example, we define a function that can add two or more numbers together.

```js
function adder(base /\*, num1, …, numN \*/) {
  base = Number(base);
  for (let i = 1; i < arguments.length; i++) {
    base += Number(arguments[i]);
  }
  return base;
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-arguments-exotic-objects |

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

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

See also
--------

* Functions guide
* Functions
* `arguments`
* `Function`: `length`


arguments.callee - JavaScript

arguments.callee
================

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

**Note:** Accessing `arguments.callee` in strict mode will throw a `TypeError`. If a function must reference itself, either give the function expression a name or use a function declaration.

The **`arguments.callee`** data property contains the currently executing function that the arguments belong to.

Value
-----

A reference to the currently executing function.

| Property attributes of `arguments.callee` |
| --- |
| Writable | yes |
| Enumerable | no |
| Configurable | yes |

**Note:** `callee` is a data property only in non-strict functions with simple parameters (in which case the `arguments` object is also auto-syncing). Otherwise, it is an accessor property whose getter and setter both throw a `TypeError`.

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

`callee` is a property of the `arguments` object. It can be used to refer to the currently executing function inside the function body of that function. This is useful when the name of the function is unknown, such as within a function expression with no name (also called "anonymous functions").

(The text below is largely adapted from a Stack Overflow answer by olliej)

Early versions of JavaScript did not allow named function expressions, and for this reason you could not make a recursive function expression.

For example, this syntax worked:

```js
function factorial(n) {
  return n <= 1 ? 1 : factorial(n - 1) \* n;
}

[1, 2, 3, 4, 5].map(factorial);
```

but:

```js
[1, 2, 3, 4, 5].map(function (n) {
  return n <= 1 ? 1 : /\* what goes here? \*/ (n - 1) \* n;
});
```

did not. To get around this `arguments.callee` was added so you could do

```js
[1, 2, 3, 4, 5].map(function (n) {
  return n <= 1 ? 1 : arguments.callee(n - 1) \* n;
});
```

However, the design of `arguments.callee` has multiple issues. The first problem is that the recursive call will get a different `this` value. For example:

```js
const global = this;

const sillyFunction = function (recursed) {
  if (this !== global) {
    console.log("This is:", this);
  } else {
    console.log("This is the global");
  }

  if (!recursed) {
    return arguments.callee(true);
  }
};

sillyFunction();
// This is the global
// This is: [object Arguments]
```

In addition, references to `arguments.callee` make inlining and tail recursion impossible in the general case. (You can achieve it in select cases through tracing, etc., but even the best code is suboptimal due to checks that would not otherwise be necessary.)

ECMAScript 3 resolved these issues by allowing named function expressions. For example:

```js
[1, 2, 3, 4, 5].map(function factorial(n) {
  return n <= 1 ? 1 : factorial(n - 1) \* n;
});
```

This has numerous benefits:

* the function can be called like any other from inside your code
* it does not create a variable in the outer scope (except for IE 8 and below)
* it has better performance than accessing the arguments object

Strict mode has banned other properties that leak stack information, like the `caller` property of functions. This is because looking at the call stack has one single major effect: it makes a large number of optimizations impossible, or much more difficult. For example, if you cannot guarantee that a function `f` will not call an unknown function, it is not possible to inline `f`.

```js
function f(a, b, c, d, e) {
  return a ? b \* c : d \* e;
}
```

If the JavaScript interpreter cannot guarantee that all the provided arguments are numbers at the point that the call is made, it needs to either insert checks for all the arguments before the inlined code, or it cannot inline the function. This means any call site that may have been trivially inlinable accumulates a large number of guards. Now in this particular case a smart interpreter should be able to rearrange the checks to be more optimal and not check any values that would not be used. However in many cases that's just not possible and therefore it becomes impossible to inline.

Examples
--------

### Using arguments.callee in an anonymous recursive function

A recursive function must be able to refer to itself. Typically, a function refers to itself by its name. However, an anonymous function (which can be created by a function expression or the `Function` constructor) does not have a name. Therefore if there is no accessible variable referring to it, the only way the function can refer to itself is by `arguments.callee`.

The following example defines a function, which, in turn, defines and returns a factorial function. This example isn't very practical, and there are nearly no cases where the same result cannot be achieved with named function expressions.

```js
function create() {
  return function (n) {
    if (n <= 1) {
      return 1;
    }
    return n \* arguments.callee(n - 1);
  };
}

const result = create()(5); // returns 120 (5 \* 4 \* 3 \* 2 \* 1)
```

### Recursion of anonymous functions with a Y-combinator

Although function expressions can now be named, arrow functions always remain anonymous, which means they cannot reference themselves without being assigned to a variable first. Fortunately, in Lambda calculus there's a very good solution which allows a function to both be anonymous and self-referential. The technique is called a Y-combinator. Here we will not explain *how* it works, only *that* it works.

```js
// The Y-combinator: a utility function!
const Y = (hof) => ((x) => x(x))((x) => hof((y) => x(x)(y)));

console.log(
  [1, 2, 3, 4, 5].map(
    // Wrap the higher-order function in the Y-combinator
    // "factorial" is not a function's name: it's introduced as a parameter
    Y((factorial) => (n) => (n <= 1 ? 1 : factorial(n - 1) \* n)),
  ),
);
// [ 1, 2, 6, 24, 120 ]
```

**Note:** This method allocates a new closure for every iteration, which may significantly increase memory usage. It's only here to demonstrate the possibility, but should be avoided in production. Use a temporary variable or a named function expression instead.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-arguments-exotic-objects |

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

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

See also
--------

* Functions guide
* Functions
* `arguments`
* `Function.prototype.caller`


arguments[@@iterator]() - JavaScript

arguments[@@iterator]()
=======================

The **`[@@iterator]()`** method of `arguments` objects implements the iterable protocol and allows `arguments` objects to be consumed by most syntaxes expecting iterables, such as the spread syntax and `for...of` loops. It returns an array iterator object that yields the value of each index in the `arguments` object.

The initial value of this property is the same function object as the initial value of the `Array.prototype.values` property (and also the same as `Array.prototype[@@iterator]`).

Syntax
------

```js
arguments[Symbol.iterator]()
```

### Parameters

None.

### Return value

The same return value as `Array.prototype.values()`: a new iterable iterator object that yields the value of each index in the `arguments` object.

Examples
--------

### Iteration using for...of loop

Note that you seldom need to call this method directly. The existence of the `@@iterator` method makes `arguments` objects iterable, and iterating syntaxes like the `for...of` loop automatically call this method to obtain the iterator to loop over.

```js
function f() {
  for (const letter of arguments) {
    console.log(letter);
  }
}
f("w", "y", "k", "o", "p");
```

### Manually hand-rolling the iterator

You may still manually call the `next()` method of the returned iterator object to achieve maximum control over the iteration process.

```js
function f() {
  const argsIter = arguments[Symbol.iterator]();
  console.log(argsIter.next().value); // a
  console.log(argsIter.next().value); // b
  console.log(argsIter.next().value); // c
  console.log(argsIter.next().value); // d
  console.log(argsIter.next().value); // e
}
f("w", "y", "k", "o", "p");
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-createunmappedargumentsobject |
| ECMAScript Language Specification # sec-createmappedargumentsobject |

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

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

See also
--------

* Functions guide
* Functions
* `arguments`
* `Array.prototype.values()`
* `Symbol.iterator`
* Iteration protocols


async function* - JavaScript

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

The **`async function*`** declaration creates a binding of a new async generator function to a given name.

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

Try it
------

Syntax
------

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

**Note:** Async generator functions do not have arrow function counterparts.

**Note:** `function` and `*` are separate tokens, so they can be separated by whitespace or line terminators. However, there cannot be a line terminator between `async` and `function`, otherwise a semicolon is automatically inserted, causing `async` to become an identifier and the rest to become a `function*` declaration.

### Parameters

`name`

The function name.

`param` Optional

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

`statements` Optional

The statements comprising the body of the function.

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

An `async function*` declaration creates an `AsyncGeneratorFunction` object. Each time when an async generator function is called, it returns a new `AsyncGenerator` object, which conforms to the async iterator protocol. Every call to `next()` returns a `Promise` that resolves to the iterator result object.

An async generator function combines the features of async functions and generator functions. You can use both the `await` and `yield` keywords within the function body. This empowers you to handle asynchronous tasks ergonomically with `await`, while leveraging the lazy nature of generator functions.

When a promise is yielded from an async generator, the iterator result promise's eventual state will match that of the yielded promise. For example:

```js
async function\* foo() {
  yield Promise.reject(1);
}

foo()
  .next()
  .catch((e) => console.error(e));
```

`1` will be logged, because if the yielded promise rejects, the iterator result will reject as well. The `value` property of an async generator's resolved result will not be another promise.

`async function*` declarations behave similar to `function` declarations — they are hoisted to the top of their scope and can be called anywhere in their scope, and they can be redeclared only in certain contexts.

Examples
--------

### Declaring an async generator function

Async generator functions always produce promises of results — even when each `yield` step is synchronous.

```js
async function\* myGenerator(step) {
  await new Promise((resolve) => setTimeout(resolve, 10));
  yield 0;
  yield step;
  yield step \* 2;
}

const gen = myGenerator(2);
gen
  .next()
  .then((res) => {
    console.log(res); // { value: 0, done: false }
    return gen.next();
  })
  .then((res) => {
    console.log(res); // { value: 2, done: false }
    return gen.next();
  })
  .then((res) => {
    console.log(res); // { value: 4, done: false }
    return gen.next();
  })
  .then((res) => {
    console.log(res); // { value: undefined, done: true }
    return gen.next();
  });
```

### Using an async generator function to read a series of files

In this example, we read a series of files and only access its content when requested, using Node's `fs/promises` module.

```js
async function\* readFiles(directory) {
  const files = await fs.readdir(directory);
  for (const file of files) {
    const stats = await fs.stat(file);
    if (stats.isFile()) {
      yield {
        name: file,
        content: await fs.readFile(file, "utf8"),
      };
    }
  }
}

const files = readFiles(".");
console.log((await files.next()).value);
// Possible output: { name: 'file1.txt', content: '...' }
console.log((await files.next()).value);
// Possible output: { name: 'file2.txt', content: '...' }
```

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

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

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

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

See also
--------

* Functions guide
* Iterators and generators guide
* Functions
* `AsyncGeneratorFunction`
* `async function*` expression
* `function`
* `function*`
* `async function`
* Iteration protocols
* `yield`
* `yield*`
* `AsyncGenerator`


function* - JavaScript

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

The **`function*`** declaration creates a binding of a new generator function to a given name. A generator function can be exited and later re-entered, with its context (variable bindings) saved across re-entrances.

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

Try it
------

Syntax
------

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

**Note:** Generator functions do not have arrow function counterparts.

**Note:** `function` and `*` are separate tokens, so they can be separated by whitespace or line terminators.

### Parameters

`name`

The function name.

`param` Optional

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

`statements` Optional

The statements comprising the body of the function.

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

 A `function*` declaration creates a `GeneratorFunction` object. Each time when a generator function is called, it returns a new `Generator` object, which conforms to the iterator protocol. When the iterator's `next()`
 method is called, the generator function's body is executed until the first
 `yield` expression, which specifies the value to be
 returned from the iterator or, with `yield*`, delegates
 to another generator function. The `next()` method returns an object with a
 `value` property containing the yielded value and a `done`
 property which indicates whether the generator has yielded its last value, as a boolean.
 Calling the `next()` method with an argument will resume the generator
 function execution, replacing the `yield` expression where an execution was
 paused with the argument from `next()`.

 Generators in JavaScript — especially when combined with Promises — are a very
 powerful tool for asynchronous programming as they mitigate — if not entirely eliminate
 -- the problems with callbacks, such as Callback Hell and
 Inversion of Control.
 However, an even simpler solution to these problems can be achieved
 with async functions.

 A `return` statement in a generator, when executed, will make the generator
 finish (i.e. the `done` property of the object returned by it will be set to
 `true`). If a value is returned, it will be set as the `value`
 property of the object returned by the generator.
 Much like a `return` statement, an error thrown inside the generator will
 make the generator finished — unless caught within the generator's body.
 When a generator is finished, subsequent `next()` calls will not execute any
 of that generator's code, they will just return an object of this form:
 `{value: undefined, done: true}`.

`function*` declarations behave similar to `function` declarations — they are hoisted to the top of their scope and can be called anywhere in their scope, and they can be redeclared only in certain contexts.

Examples
--------

### Simple example

```js
function\* idMaker() {
  let index = 0;
  while (true) {
    yield index++;
  }
}

const gen = idMaker();

console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
// …
```

### Example with yield\*

```js
function\* anotherGenerator(i) {
  yield i + 1;
  yield i + 2;
  yield i + 3;
}

function\* generator(i) {
  yield i;
  yield\* anotherGenerator(i);
  yield i + 10;
}

const gen = generator(10);

console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20
```

### Passing arguments into Generators

```js
function\* logGenerator() {
  console.log(0);
  console.log(1, yield);
  console.log(2, yield);
  console.log(3, yield);
}

const gen = logGenerator();

// the first call of next executes from the start of the function
// until the first yield statement
gen.next(); // 0
gen.next("pretzel"); // 1 pretzel
gen.next("california"); // 2 california
gen.next("mayonnaise"); // 3 mayonnaise
```

### Return statement in a generator

```js
function\* yieldAndReturn() {
  yield "Y";
  return "R";
  yield "unreachable";
}

const gen = yieldAndReturn();
console.log(gen.next()); // { value: "Y", done: false }
console.log(gen.next()); // { value: "R", done: true }
console.log(gen.next()); // { value: undefined, done: true }
```

### Generator as an object property

```js
const someObj = {
  \*generator() {
    yield "a";
    yield "b";
  },
};

const gen = someObj.generator();

console.log(gen.next()); // { value: 'a', done: false }
console.log(gen.next()); // { value: 'b', done: false }
console.log(gen.next()); // { value: undefined, done: true }
```

### Generator as an object method

```js
class Foo {
  \*generator() {
    yield 1;
    yield 2;
    yield 3;
  }
}

const f = new Foo();
const gen = f.generator();

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

### Generator as a computed property

```js
class Foo {
  \*[Symbol.iterator]() {
    yield 1;
    yield 2;
  }
}

const SomeObj = {
  \*[Symbol.iterator]() {
    yield "a";
    yield "b";
  },
};

console.log(Array.from(new Foo())); // [ 1, 2 ]
console.log(Array.from(SomeObj)); // [ 'a', 'b' ]
```

### Generators are not constructable

```js
function\* f() {}
const obj = new f(); // throws "TypeError: f is not a constructor
```

### Generator defined in an expression

```js
const foo = function\* () {
  yield 10;
  yield 20;
};

const bar = foo();
console.log(bar.next()); // {value: 10, done: false}
```

### Generator example

```js
function\* powers(n) {
  //endless loop to generate
  for (let current = n; ; current \*= n) {
    yield current;
  }
}

for (const power of powers(2)) {
  // controlling generator
  if (power > 32) {
    break;
  }
  console.log(power);
  // 2
  // 4
  // 8
  // 16
  // 32
}
```

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

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

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

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

See also
--------

* Functions guide
* Iterators and generators guide
* Functions
* `GeneratorFunction`
* `function*` expression
* `function`
* `async function`
* `async function*`
* Iteration protocols
* `yield`
* `yield*`
* `Generator`
* Regenerator on GitHub
* Promises and Generators: control flow utopia presentation by Forbes Lindesay at JSConf (2013)
* Task.js on GitHub
* You Don't Know JS: Async & Performance, Ch.4: Generators by Kyle Simpson


try...catch - JavaScript

try...catch
===========

The **`try...catch`** statement is comprised of a `try` block and either a `catch` block, a `finally` block, or both. The code in the `try` block is executed first, and if it throws an exception, the code in the `catch` block will be executed. The code in the `finally` block will always be executed before control flow exits the entire construct.

Try it
------

Syntax
------

```js
try {
  tryStatements
} catch (exceptionVar) {
  catchStatements
} finally {
  finallyStatements
}
```

`tryStatements`

The statements to be executed.

`catchStatements`

Statement that is executed if an exception is thrown in the `try` block.

`exceptionVar` Optional

An optional identifier or pattern to hold the caught exception for the associated `catch` block. If the `catch` block does not use the exception's value, you can omit the `exceptionVar` and its surrounding parentheses.

`finallyStatements`

Statements that are executed before control flow exits the `try...catch...finally` construct. These statements execute regardless of whether an exception was thrown or caught.

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

The `try` statement always starts with a `try` block. Then, a `catch` block or a `finally` block must be present. It's also possible to have both `catch` and `finally` blocks. This gives us three forms for the `try` statement:

* `try...catch`
* `try...finally`
* `try...catch...finally`

Unlike other constructs such as `if` or `for`, the `try`, `catch`, and `finally` blocks must be *blocks*, instead of single statements.

```js
try doSomething(); // SyntaxError
catch (e) console.log(e);
```

A `catch` block contains statements that specify what to do if an exception is thrown in the `try` block. If any statement within the `try` block (or in a function called from within the `try` block) throws an exception, control is immediately shifted to the `catch` block. If no exception is thrown in the `try` block, the `catch` block is skipped.

The `finally` block will always execute before control flow exits the `try...catch...finally` construct. It always executes, regardless of whether an exception was thrown or caught.

You can nest one or more `try` statements. If an inner `try` statement does not have a `catch` block, the enclosing `try` statement's `catch` block is used instead.

You can also use the `try` statement to handle JavaScript exceptions. See the JavaScript Guide for more information on JavaScript exceptions.

### Catch binding

When an exception is thrown in the `try` block, `exceptionVar` (i.e., the `e` in `catch (e)`) holds the exception value. You can use this binding to get information about the exception that was thrown. This binding is only available in the `catch` block's scope.

It needs not be a single identifier. You can use a destructuring pattern to assign multiple identifiers at once.

```js
try {
  throw new TypeError("oops");
} catch ({ name, message }) {
  console.log(name); // "TypeError"
  console.log(message); // "oops"
}
```

The bindings created by the `catch` clause live in the same scope as the `catch` block, so any variables declared in the `catch` block cannot have the same name as the bindings created by the `catch` clause. (There's one exception to this rule, but it's a deprecated syntax.)

```js
try {
  throw new TypeError("oops");
} catch ({ name, message }) {
  var name; // SyntaxError: Identifier 'name' has already been declared
  let message; // SyntaxError: Identifier 'message' has already been declared
}
```

The exception binding is writable. For example, you may want to normalize the exception value to make sure it's an `Error` object.

```js
try {
  throw "Oops; this is not an Error object";
} catch (e) {
  if (!(e instanceof Error)) {
    e = new Error(e);
  }
  console.error(e.message);
}
```

If you don't need the exception value, you can omit it along with the enclosing parentheses.

```js
function isValidJSON(text) {
  try {
    JSON.parse(text);
    return true;
  } catch {
    return false;
  }
}
```

### The finally block

The `finally` block contains statements to execute after the `try` block and `catch` block(s) execute, but before the statements following the `try...catch...finally` block. Control flow will always enter the `finally` block, which can proceed in one of the following ways:

* Immediately after the `try` block finishes execution normally (and no exceptions were thrown);
* Immediately after the `catch` block finishes execution normally;
* Immediately before a control-flow statement (`return`, `throw`, `break`, `continue`) is executed in the `try` block or `catch` block.

If an exception is thrown from the `try` block, even when there's no `catch` block to handle the exception, the `finally` block still executes, in which case the exception is still thrown immediately after the `finally` block finishes executing.

The following example shows one use case for the `finally` block. The code opens a file and then executes statements that use the file; the `finally` block makes sure the file always closes after it is used even if an exception was thrown.

```js
openMyFile();
try {
  // tie up a resource
  writeMyFile(theData);
} finally {
  closeMyFile(); // always close the resource
}
```

Control flow statements (`return`, `throw`, `break`, `continue`) in the `finally` block will "mask" any completion value of the `try` block or `catch` block. In this example, the `try` block tries to return 1, but before returning, the control flow is yielded to the `finally` block first, so the `finally` block's return value is returned instead.

```js
function doIt() {
  try {
    return 1;
  } finally {
    return 2;
  }
}

doIt(); // returns 2
```

It is generally a bad idea to have control flow statements in the `finally` block. Only use it for cleanup code.

Examples
--------

### Unconditional catch block

When a `catch` block is used, the `catch` block is executed when any exception is thrown from within the `try` block. For example, when the exception occurs in the following code, control transfers to the `catch` block.

```js
try {
  throw "myException"; // generates an exception
} catch (e) {
  // statements to handle any exceptions
  logMyErrors(e); // pass exception object to error handler
}
```

The `catch` block specifies an identifier (`e` in the example above) that holds the value of the exception; this value is only available in the scope of the `catch` block.

### Conditional catch blocks

You can create "Conditional `catch` blocks" by combining `try...catch` blocks with `if...else if...else` structures, like this:

```js
try {
  myroutine(); // may throw three types of exceptions
} catch (e) {
  if (e instanceof TypeError) {
    // statements to handle TypeError exceptions
  } else if (e instanceof RangeError) {
    // statements to handle RangeError exceptions
  } else if (e instanceof EvalError) {
    // statements to handle EvalError exceptions
  } else {
    // statements to handle any unspecified exceptions
    logMyErrors(e); // pass exception object to error handler
  }
}
```

A common use case for this is to only catch (and silence) a small subset of expected errors, and then re-throw the error in other cases:

```js
try {
  myRoutine();
} catch (e) {
  if (e instanceof RangeError) {
    // statements to handle this very common expected error
  } else {
    throw e; // re-throw the error unchanged
  }
}
```

This may mimic the syntax from other languages, like Java:

```java
try {
  myRoutine();
} catch (RangeError e) {
  // statements to handle this very common expected error
}
// Other errors are implicitly re-thrown
```

### Nested try blocks

First, let's see what happens with this:

```js
try {
  try {
    throw new Error("oops");
  } finally {
    console.log("finally");
  }
} catch (ex) {
  console.error("outer", ex.message);
}

// Logs:
// "finally"
// "outer" "oops"
```

Now, if we already caught the exception in the inner `try` block by adding a `catch` block:

```js
try {
  try {
    throw new Error("oops");
  } catch (ex) {
    console.error("inner", ex.message);
  } finally {
    console.log("finally");
  }
} catch (ex) {
  console.error("outer", ex.message);
}

// Logs:
// "inner" "oops"
// "finally"
```

And now, let's rethrow the error.

```js
try {
  try {
    throw new Error("oops");
  } catch (ex) {
    console.error("inner", ex.message);
    throw ex;
  } finally {
    console.log("finally");
  }
} catch (ex) {
  console.error("outer", ex.message);
}

// Logs:
// "inner" "oops"
// "finally"
// "outer" "oops"
```

Any given exception will be caught only once by the nearest enclosing `catch` block unless it is rethrown. Of course, any new exceptions raised in the "inner" block (because the code in `catch` block may do something that throws), will be caught by the "outer" block.

### Returning from a finally block

If the `finally` block returns a value, this value becomes the return value of the entire `try-catch-finally` statement, regardless of any `return` statements in the `try` and `catch` blocks. This includes exceptions thrown inside of the `catch` block:

```js
(() => {
  try {
    try {
      throw new Error("oops");
    } catch (ex) {
      console.error("inner", ex.message);
      throw ex;
    } finally {
      console.log("finally");
      return;
    }
  } catch (ex) {
    console.error("outer", ex.message);
  }
})();

// Logs:
// "inner" "oops"
// "finally"
```

The outer "oops" is not thrown because of the return in the `finally` block. The same would apply to any value returned from the `catch` block.

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

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

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

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

See also
--------

* `Error`
* `throw`


return - JavaScript

return
======

The **`return`** statement ends function execution and specifies a value to be returned to the function caller.

Try it
------

Syntax
------

```js
return;
return expression;
```

`expression` Optional

The expression whose value is to be returned. If omitted, `undefined` is returned.

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

The `return` statement can only be used within function bodies. When a `return` statement is used in a function body, the execution of the function is stopped. The `return` statement has different effects when placed in different functions:

* In a plain function, the call to that function evaluates to the return value.
* In an async function, the produced promise is resolved with the returned value.
* In a generator function, the produced generator object's `next()` method returns `{ done: true, value: returnedValue }`.
* In an async generator function, the produced async generator object's `next()` method returns a promise fulfilled with `{ done: true, value: returnedValue }`.

If a `return` statement is executed within a `try` block, its `finally` block, if present, is first executed, before the value is actually returned.

### Automatic semicolon insertion

The syntax forbids line terminators between the `return` keyword and the expression to be returned.

```js
return
a + b;
```

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

```js
return;
a + b;
```

This makes the function return `undefined` and the `a + b` expression is never evaluated. This may generate a warning in the console.

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

```js
return (
  a + b
);
```

Examples
--------

### Interrupt a function

A function immediately stops at the point where `return` is called.

```js
function counter() {
  // Infinite loop
  for (let count = 1; ; count++) {
    console.log(`${count}A`); // Until 5
    if (count === 5) {
      return;
    }
    console.log(`${count}B`); // Until 4
  }
  console.log(`${count}C`); // Never appears
}

counter();

// Logs:
// 1A
// 1B
// 2A
// 2B
// 3A
// 3B
// 4A
// 4B
// 5A
```

### Returning a function

See also the article about Closures.

```js
function magic() {
  return function calc(x) {
    return x \* 42;
  };
}

const answer = magic();
answer(1337); // 56154
```

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

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

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

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

See also
--------

* Functions
* Closures


function - JavaScript

function
========

The **`function`** declaration creates a binding of a new function to a given name.

You can also define functions using the `function` expression.

Try it
------

Syntax
------

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

### Parameters

`name`

The function name.

`param` Optional

The name of a formal parameter for the function. Maximum number of arguments varies in different engines. For the parameters' syntax, see the Functions reference.

`statements` Optional

The statements which comprise the body of the function.

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

A `function` declaration creates a `Function` object. Each time when a function is called, it returns the value specified by the last executed `return` statement, or `undefined` if the end of the function body is reached. See functions for detailed information on functions.

`function` declarations behave like a mix of `var` and `let`:

* Like `let`, in strict mode, function declarations are scoped to the most closely containing block.
* Like `let`, function declarations at the top level of a module or within blocks in strict mode cannot be redeclared by any other declaration.
* Like `var`, function declarations at the top level of a script (strict or non-strict) become properties on `globalThis`. Function declarations at the top level of a script or function body (strict or non-strict) can be redeclared by another `function` or `var`.
* Like both, function declarations can be re-assigned, but you should avoid doing so.
* Unlike either, function declarations are hoisted together with its value and can be called anywhere in its scope.
### Block-level function declaration

**Warning:** In non-strict mode, function declarations inside blocks behave strangely. Only declare functions in blocks if you are in strict mode.

Functions can be conditionally declared — that is, a function statement can be nested within an `if` statement. However, in non-strict mode, the results are inconsistent across implementations.

```js
console.log(
  `'foo' name ${
 "foo" in globalThis ? "is" : "is not"
 } global. typeof foo is ${typeof foo}`,
);
if (false) {
  function foo() {
    return 1;
  }
}

// In Chrome:
// 'foo' name is global. typeof foo is undefined
//
// In Firefox:
// 'foo' name is global. typeof foo is undefined
//
// In Safari:
// 'foo' name is global. typeof foo is function
```

The scoping and hoisting effect won't change regardless of whether the `if` body is actually executed.

```js
console.log(
  `'foo' name ${
 "foo" in globalThis ? "is" : "is not"
 } global. typeof foo is ${typeof foo}`,
);
if (true) {
  function foo() {
    return 1;
  }
}

// In Chrome:
// 'foo' name is global. typeof foo is undefined
//
// In Firefox:
// 'foo' name is global. typeof foo is undefined
//
// In Safari:
// 'foo' name is global. typeof foo is function
```

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

```js
"use strict";

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

console.log(
  `'foo' name ${
 "foo" in globalThis ? "is" : "is not"
 } global. typeof foo is ${typeof foo}`,
);
// 'foo' name is not global. typeof foo is undefined
```

### Hoisting

Function declarations in JavaScript are hoisted to the top of the enclosing function or global scope. You can use the function before you declared it:

```js
hoisted(); // Logs "foo"

function hoisted() {
  console.log("foo");
}
```

Note that function expressions are not hoisted:

```js
notHoisted(); // TypeError: notHoisted is not a function

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

### Redeclarations

Whether `function` declarations can be redeclared in the same scope depends on what scope it's contained in.

At the top level of a script, `function` declarations behave like `var` and can be redeclared by another `function` or `var` but not by `let`, `const`, or `class`.

```js
function a(b) {}
function a(b, c) {}
console.log(a.length); // 2
let a = 2; // SyntaxError: Identifier 'a' has already been declared
```

When `function` declarations are redeclared by `var`, the `var` declaration's initializer always overrides the function's value, regardless of their relative position. This is because function declarations are hoisted before any initializer gets evaluated, so the initializer comes later and overrides the value.

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

At the top level of a function's body, `function` also behaves like `var` and can be redeclared or have the same name as a parameter.

```js
function foo(a) {
  function a() {}
  console.log(typeof a);
}

foo(2); // Logs "function"
```

At the top level of a module or a block in strict mode, `function` declarations behave like `let` and cannot be redeclared by any other declaration.

```js
// Assuming current source is a module
function foo() {}
function foo() {} // SyntaxError: Identifier 'foo' has already been declared
```

```js
"use strict";
{
  function foo() {}
  function foo() {} // SyntaxError: Identifier 'foo' has already been declared
}
```

A `function` declaration within a `catch` block cannot have the same name as the `catch`-bound identifier, even in non-strict mode.

```js
try {
} catch (e) {
  function e() {} // SyntaxError: Identifier 'e' has already been declared
}
```

Examples
--------

### Using function

The following code declares a function that returns the total amount of sales, when given the number of units sold of three products.

```js
function calcSales(unitsA, unitsB, unitsC) {
  return unitsA \* 79 + unitsB \* 129 + unitsC \* 699;
}
```

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

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

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

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

See also
--------

* Functions guide
* Functions
* `Function`
* `function` expression
* `function*`
* `async function`
* `async function*`


Expression statement - JavaScript

Expression statement
====================

An **expression statement** is an expression used in a place where a statement is expected. The expression is evaluated and its result is discarded — therefore, it makes sense only for expressions that have side effects, such as executing a function or updating a variable.

Syntax
------

```js
expression;
```

`expression`

An arbitrary expression to be evaluated. There are certain expressions that may be ambiguous with other statements and are thus forbidden.

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

Apart from the dedicated statement syntaxes, you can also use almost any expression as a statement on its own. The expression statement syntax requires a semicolon at the end, but the automatic semicolon insertion process may insert one for you if the lack of a semicolon results in invalid syntax.

Because the expression is evaluated and then discarded, the result of the expression is not available. Therefore, the expression must have some side effect for it to be useful. Expression statements are commonly:

* Function calls (`console.log("Hello");`, `[1, 2, 3].forEach((i) => console.log(i));`)
* Tagged template literals
* Assignment expressions, including compound assignments
* Increment and decrement operators
* `delete`
* `import()`
* `yield` and `yield*`

Others may also have side effects if they invoke getters or trigger type coercions.

### Forbidden expressions

In order for an expression to be used as a statement, it must not be ambiguous with other statement syntaxes. Therefore, the expression must not start with any of the following tokens:

* `function`: which would be a `function` declaration or `function*` declaration, not a `function` expression or `function*` expression
* `async function`: which would be an `async function` declaration or `async function*` declaration, not an `async function` expression or `async function*` expression
* `class`: which would be a `class` declaration, not a `class` expression
* `let[`: which would be a `let` declaration with array destructuring, not a property accessor on a variable called `let` (`let` can only be an identifier in non-strict mode)
* `{`: which would be a block statement, not an object literal

Therefore, all of the following are invalid:

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

// For some reason, you have a variable called `let`
var let = [1, 2, 3];
let[0] = 4; // SyntaxError: Invalid destructuring assignment target

{
  foo: 1,
  bar: 2, // SyntaxError: Unexpected token ':'
};
```

More dangerously, sometimes the code happens to be valid syntax, but is not what you intend.

```js
// For some reason, you have a variable called `let`
var let = [1, 2, 3];

function setIndex(index, value) {
  if (index >= 0) {
    // Intend to assign to the array `let`, but instead creates an extra variable!
    let[index] = value;
  }
}

setIndex(0, [1, 2]);
console.log(let); // [1, 2, 3]

// This is not an object literal, but a block statement,
// where `foo` is a label and `1` is an expression statement.
// This often happens in the console
{ foo: 1 };
```

To avoid these problems, you can use parentheses, so that the statement is unambiguously an expression statement.

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

Examples
--------

### Avoiding control flow statements

You can avoid almost all use of control flow statements using expression statements. For example, `if...else` can be replaced with ternary operators and logical operators. Iterative statements like `for` or `for...of` can be replaced with array methods.

```js
// Using control flow statements
function range(start, end) {
  if (start > end) {
    [start, end] = [end, start];
  }
  const result = [];
  for (let i = start; i < end; i++) {
    result.push(i);
  }
  return result;
}

// Using expression statements
function range2(start, end) {
  start > end && ([start, end] = [end, start]);
  return Array.from({ length: end - start }, (\_, i) => start + i);
}
```

**Warning:** This only demonstrates a capability of the language. Excessive use of expression statements as a substitute for control-flow statements can make code much less readable.

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

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

See also
--------

* Statements and declarations
* Expressions and operators


for...in - JavaScript

for...in
========

The **`for...in`** statement iterates over all enumerable string properties of an object (ignoring properties keyed by symbols), including inherited enumerable properties.

Try it
------

Syntax
------

```js
for (variable in object)
  statement
```

### Parameters

`variable`

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

`object`

Object whose non-symbol enumerable properties are iterated over.

`statement`

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

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

The loop will iterate over all enumerable properties of the object itself and those the object inherits from its prototype chain (properties of nearer prototypes take precedence over those of prototypes further away from the object in its prototype chain).

A `for...in` loop only iterates over enumerable, non-symbol properties. Objects created from built–in constructors like `Array` and `Object` have inherited non–enumerable properties from `Array.prototype` and `Object.prototype`, such as `Array`'s `indexOf()` method or `Object`'s `toString()` method, which will not be visited in the `for...in` loop.

The traversal order, as of modern ECMAScript specification, is well-defined and consistent across implementations. Within each component of the prototype chain, all non-negative integer keys (those that can be array indices) will be traversed first in ascending order by value, then other string keys in ascending chronological order of property creation.

The `variable` part of `for...in` accepts anything that can come before the `=` operator. You can use `const` to declare the variable as long as it's not reassigned within the loop body (it can change between iterations, because those are two separate variables). Otherwise, you can use `let`. You can use destructuring to assign multiple local variables, or use a property accessor like `for (x.y in iterable)` to assign the value to an object property.

A legacy syntax allows `var` declarations of the loop variable to have an initializer. This throws a syntax error in strict mode and is ignored in non–strict mode.

### Deleted, added, or modified properties

`for...in` visits property keys in the following fashion:

1. It first gets all own string keys of the current object, in a fashion very similar to `Object.getOwnPropertyNames()`.
2. For each key, if no string with the same value has ever been visited, the property descriptor is retrieved and the property is only visited if it is enumerable. However, this property string will be marked as visited even if it's not enumerable.
3. Then, the current object is replaced with its prototype, and the process is repeated.

This means:

* Any property added to the currently visited object during iteration will not be visited, because all own properties of the current object have already been saved beforehand.
* If multiple objects in the prototype chain have a property with the same name, only the first one will be considered, and it is only visited if it's enumerable. If it is non-enumerable, no other properties with the same name further up the prototype chain will be visited, even if they are enumerable.

In general, it is best not to add, modify, or remove properties from the object during iteration, other than the property currently being visited. The spec explicitly allows the implementation to not follow the algorithm above in one of the following cases:

* The object's prototype chain is modified during iteration.
* A property is deleted from the object or its prototype chain during iteration.
* A property is added to the object's prototype chain during iteration.
* A property's enumerability is changed during iteration.

In these cases, implementations may behave differently from what you may expect, or even from each other.

### Array iteration and for...in

Array indexes are just enumerable properties with integer names and are otherwise identical to general object properties. The `for...in` loop will traverse all integer keys before traversing other keys, and in strictly increasing order, making the behavior of `for...in` close to normal array iteration. However, the `for...in` loop will return all enumerable properties, including those with non–integer names and those that are inherited. Unlike `for...of`, `for...in` uses property enumeration instead of the array's iterator. In sparse arrays, `for...of` will visit the empty slots, but `for...in` will not.

It is better to use a `for` loop with a numeric index, `Array.prototype.forEach()`, or the `for...of` loop, because they will return the index as a number instead of a string, and also avoid non-index properties.

### Iterating over own properties only

If you only want to consider properties attached to the object itself, and not its prototypes, you can use one of the following techniques:

* `Object.keys()`
* `Object.getOwnPropertyNames()`

`Object.keys` will return a list of enumerable own string properties, while `Object.getOwnPropertyNames` will also contain non-enumerable ones.

Many JavaScript style guides and linters recommend against the use of `for...in`, because it iterates over the entire prototype chain which is rarely what one wants, and may be a confusion with the more widely-used `for...of` loop. `for...in` is most practically used for debugging purposes, being an easy way to check the properties of an object (by outputting to the console or otherwise). In situations where objects are used as ad hoc key-value pairs, `for...in` allows you check if any of those keys hold a particular value.

Examples
--------

### Using for...in

The `for...in` loop below iterates over all of the object's enumerable, non-symbol properties and logs a string of the property names and their values.

```js
const obj = { a: 1, b: 2, c: 3 };

for (const prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
}

// Logs:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"
```

### Iterating own properties

The following function illustrates the use of `Object.hasOwn()`: the inherited properties are not displayed.

```js
const triangle = { a: 1, b: 2, c: 3 };

function ColoredTriangle() {
  this.color = "red";
}

ColoredTriangle.prototype = triangle;

const obj = new ColoredTriangle();

for (const prop in obj) {
  if (Object.hasOwn(obj, prop)) {
    console.log(`obj.${prop} = ${obj[prop]}`);
  }
}

// Logs:
// "obj.color = red"
```

### Concurrent modification

**Warning:** You should not write code like this yourself. It is only included here to illustrate the behavior of `for...in` in some corner cases.

Properties added to the current object during iteration are never visited:

```js
const obj = { a: 1, b: 2 };

for (const prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
  obj.c = 3;
}

// Logs:
// obj.a = 1
// obj.b = 2
```

Shadowed properties are only visited once:

```js
const proto = { a: 1 };
const obj = { \_\_proto\_\_: proto, a: 2 };

for (const prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
}

// Logs:
// obj.a = 2

Object.defineProperty(obj, "a", { enumerable: false });

for (const prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
}
// Logs nothing, because the first "a" property visited is non-enumerable.
```

In addition, consider the following cases, where the behavior is unspecified, and implementations tend to diverge from the specified algorithm:

Changing the prototype during iteration:

```js
const obj = { a: 1, b: 2 };

for (const prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
  Object.setPrototypeOf(obj, { c: 3 });
}
```

Deleting a property during iteration:

```js
const obj = { a: 1, b: 2, c: 3 };

// Deleting a property before it is visited
for (const prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
  delete obj.c;
}

const obj2 = { a: 1, b: 2, c: 3 };

// Deleting a property after it is visited
for (const prop in obj2) {
  console.log(`obj2.${prop} = ${obj2[prop]}`);
  delete obj2.a;
}
```

Enumerable properties added to the prototype during iteration:

```js
const proto = {};
const obj = { \_\_proto\_\_: proto, a: 1, b: 2 };

for (const prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
  proto.c = 3;
}
```

Changing the enumerability of a property during iteration:

```js
const obj = { a: 1, b: 2, c: 3 };

for (const prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
  Object.defineProperty(obj, "c", { enumerable: false });
}
```

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

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

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

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

See also
--------

* `for...of`
* `for`
* Enumerability and ownership of properties
* `Object.getOwnPropertyNames()`
* `Object.hasOwn()`
* `Array.prototype.forEach()`