JavaScript language overview - JavaScript

JavaScript language overview
============================

JavaScript is a multi-paradigm, dynamic language with types and operators, standard built-in objects, and methods. Its syntax is based on the Java and C languages — many structures from those languages apply to JavaScript as well. JavaScript supports object-oriented programming with object prototypes and classes. It also supports functional programming since functions are first-class objects that can be easily created via expressions and passed around like any other object.

This page serves as a quick overview of various JavaScript language features, written for readers with background in other languages, such as C or Java.

Data types
----------

Let's start off by looking at the building blocks of any language: the types. JavaScript programs manipulate values, and those values all belong to a type. JavaScript offers seven *primitive types*:

* Number: used for all number values (integer and floating point) except for *very* big integers.
* BigInt: used for arbitrarily large integers.
* String: used to store text.
* Boolean: `true` and `false` — usually used for conditional logic.
* Symbol: used for creating unique identifiers that won't collide.
* Undefined: indicating that a variable has not been assigned a value.
* Null: indicating a deliberate non-value.

Everything else is known as an Object. Common object types include:

* `Function`
* `Array`
* `Date`
* `RegExp`
* `Error`

Functions aren't special data structures in JavaScript — they are just a special type of object that can be called.

### Numbers

JavaScript has two built-in numeric types: Number and BigInt.

The Number type is a IEEE 754 64-bit double-precision floating point value, which means integers can be safely represented between -(253 − 1) and 253 − 1 without loss of precision, and floating point numbers can be stored all the way up to 1.79 × 10308. Within numbers, JavaScript does not distinguish between floating point numbers and integers.

```js
console.log(3 / 2); // 1.5, not 1
```

So an *apparent integer* is in fact *implicitly a float*. Because of IEEE 754 encoding, sometimes floating point arithmetic can be imprecise.

```js
console.log(0.1 + 0.2); // 0.30000000000000004
```

For operations that expect integers, such as bitwise operations, the number will be converted to a 32-bit integer.

Number literals can also have prefixes to indicate the base (binary, octal, decimal, or hexadecimal), or an exponent suffix.

```js
console.log(0b111110111); // 503
console.log(0o767); // 503
console.log(0x1f7); // 503
console.log(5.03e2); // 503
```

The BigInt type is an arbitrary length integer. Its behavior is similar to C's integer types (e.g. division truncates to zero), except it can grow indefinitely. BigInts are specified with a number literal and an `n` suffix.

```js
console.log(-3n / 2n); // -1n
```

The standard arithmetic operators are supported, including addition, subtraction, remainder arithmetic, etc. BigInts and numbers cannot be mixed in arithmetic operations.

The `Math` object provides standard mathematical functions and constants.

```js
Math.sin(3.5);
const circumference = 2 \* Math.PI \* r;
```

There are three ways to convert a string to a number:

* `parseInt()`, which parses the string for an integer.
* `parseFloat()`, which parses the string for a floating-point number.
* The `Number()` function, which parses a string as if it's a number literal and supports many different number representations.

You can also use the unary plus `+` as a shorthand for `Number()`.

Number values also include `NaN` (short for "Not a Number") and `Infinity`. Many "invalid math" operations will return `NaN` — for example, if attempting to parse a non-numeric string, or using `Math.log()` on a negative value. Division by zero produces `Infinity` (positive or negative).

`NaN` is contagious: if you provide it as an operand to any mathematical operation, the result will also be `NaN`. `NaN` is the only value in JavaScript that's not equal to itself (per IEEE 754 specification).

### Strings

Strings in JavaScript are sequences of Unicode characters. This should be welcome news to anyone who has had to deal with internationalization. More accurately, they are UTF-16 encoded.

```js
console.log("Hello, world");
console.log("你好，世界！"); // Nearly all Unicode characters can be written literally in string literals
```

Strings can be written with either single or double quotes — JavaScript does not have the distinction between characters and strings. If you want to represent a single character, you just use a string consisting of that single character.

```js
console.log("Hello"[1] === "e"); // true
```

To find the length of a string (in code units), access its `length` property.

Strings have utility methods to manipulate the string and access information about the string. Because all primitives are immutable by design, these methods return new strings.

The `+` operator is overloaded for strings: when one of the operands is a string, it performs string concatenation instead of number addition. A special template literal syntax allows you to write strings with embedded expressions more succinctly. Unlike Python's f-strings or C#'s interpolated strings, template literals use backticks (not single or double quotes).

```js
const age = 25;
console.log("I am " + age + " years old."); // String concatenation
console.log(`I am ${age} years old.`); // Template literal
```

### Other types

JavaScript distinguishes between `null`, which indicates a deliberate non-value (and is only accessible through the `null` keyword), and `undefined`, which indicates absence of value. There are many ways to obtain `undefined`:

* A `return` statement with no value (`return;`) implicitly returns `undefined`.
* Accessing a nonexistent object property (`obj.iDontExist`) returns `undefined`.
* A variable declaration without initialization (`let x;`) will implicitly initialize the variable to `undefined`.

JavaScript has a Boolean type, with possible values `true` and `false` — both of which are keywords. Any value can be converted to a boolean according to the following rules:

1. `false`, `0`, empty strings (`""`), `NaN`, `null`, and `undefined` all become `false`.
2. All other values become `true`.

You can perform this conversion explicitly using the `Boolean()` function:

```js
Boolean(""); // false
Boolean(234); // true
```

However, this is rarely necessary, as JavaScript will silently perform this conversion when it expects a boolean, such as in an `if` statement (see Control structures). For this reason, we sometimes speak of "truthy" and "falsy", meaning values that become `true` and `false`, respectively, when used in boolean contexts.

Boolean operations such as `&&` (logical *and*), `||` (logical *or*), and `!` (logical *not*) are supported; see Operators.

The Symbol type is often used to create unique identifiers. Every symbol created with the `Symbol()` function is guaranteed to be unique. In addition, there are registered symbols, which are shared constants, and well-known symbols, which are utilized by the language as "protocols" for certain operations. You can read more about them in the symbol reference.

Variables
---------

Variables in JavaScript are declared using one of three keywords: `let`, `const`, or `var`.

`let` allows you to declare block-level variables. The declared variable is available from the *block* it is enclosed in.

```js
let a;
let name = "Simon";

// myLetVariable is \*not\* visible out here

for (let myLetVariable = 0; myLetVariable < 5; myLetVariable++) {
  // myLetVariable is only visible in here
}

// myLetVariable is \*not\* visible out here
```

`const` allows you to declare variables whose values are never intended to change. The variable is available from the *block* it is declared in.

```js
const Pi = 3.14; // Declare variable Pi
console.log(Pi); // 3.14
```

A variable declared with `const` cannot be reassigned.

```js
const Pi = 3.14;
Pi = 1; // will throw an error because you cannot change a constant variable.
```

`const` declarations only prevent *reassignments* — they don't prevent *mutations* of the variable's value, if it's an object.

```js
const obj = {};
obj.a = 1; // no error
console.log(obj); // { a: 1 }
```

`var` declarations can have surprising behaviors (for example, they are not block-scoped), and they are discouraged in modern JavaScript code.

If you declare a variable without assigning any value to it, its value is `undefined`. You can't declare a `const` variable without an initializer, because you can't change it later anyway.

`let` and `const` declared variables still occupy the entire scope they are defined in, and are in a region known as the temporal dead zone before the actual line of declaration. This has some interesting interactions with variable shadowing, which don't occur in other languages.

```js
function foo(x, condition) {
  if (condition) {
    console.log(x);
    const x = 2;
    console.log(x);
  }
}

foo(1, true);
```

In most other languages, this would log "1" and "2", because before the `const x = 2` line, `x` should still refer to the parameter `x` in the upper scope. In JavaScript, because each declaration occupies the entire scope, this would throw an error on the first `console.log`: "Cannot access 'x' before initialization". For more information, see the reference page of `let`.

JavaScript is *dynamically typed*. Types (as described in the previous section) are only associated with values, but not with variables. For `let`-declared variables, you can always change its type through reassignment.

```js
let a = 1;
a = "foo";
```

Operators
---------

JavaScript's numeric operators include `+`, `-`, `*`, `/`, `%` (remainder), and `**` (exponentiation). Values are assigned using `=`. Each binary operator also has a compound assignment counterpart such as `+=` and `-=`, which extend out to `x = x operator y`.

```js
x += 5;
x = x + 5;
```

You can use `++` and `--` to increment and decrement respectively. These can be used as a prefix or postfix operators.

The `+` operator also does string concatenation:

```js
"hello" + " world"; // "hello world"
```

If you add a string to a number (or other value) everything is converted into a string first. This might trip you up:

```js
"3" + 4 + 5; // "345"
3 + 4 + "5"; // "75"
```

Adding an empty string to something is a useful way of converting it to a string itself.

Comparisons in JavaScript can be made using `<`, `>`, `<=` and `>=`, which work for both strings and numbers. For equality, the double-equals operator performs type coercion if you give it different types, with sometimes interesting results. On the other hand, the triple-equals operator does not attempt type coercion, and is usually preferred.

```js
123 == "123"; // true
1 == true; // true

123 === "123"; // false
1 === true; // false
```

The double-equals and triple-equals also have their inequality counterparts: `!=` and `!==`.

JavaScript also has bitwise operators and logical operators. Notably, logical operators don't work with boolean values only — they work by the "truthiness" of the value.

```js
const a = 0 && "Hello"; // 0 because 0 is "falsy"
const b = "Hello" || "world"; // "Hello" because both "Hello" and "world" are "truthy"
```

The `&&` and `||` operators use short-circuit logic, which means whether they will execute their second operand is dependent on the first. This is useful for checking for null objects before accessing their attributes:

```js
const name = o && o.getName();
```

Or for caching values (when falsy values are invalid):

```js
const name = cachedName || (cachedName = getName());
```

For a comprehensive list of operators, see the guide page or reference section. You may be especially interested in the operator precedence.

Grammar
-------

JavaScript grammar is very similar to the C family. There are a few points worth mentioning:

* Identifiers can have Unicode characters, but they cannot be one of the reserved words.
* Comments are commonly `//` or `/* */`, while many other scripting languages like Perl, Python, and Bash use `#`.
* Semicolons are optional in JavaScript — the language automatically inserts them when needed. However, there are certain caveats to watch out for, since unlike Python, semicolons are still part of the syntax.

For an in-depth look at the JavaScript grammar, see the reference page for lexical grammar.

Control structures
------------------

JavaScript has a similar set of control structures to other languages in the C family. Conditional statements are supported by `if` and `else`; you can chain them together:

```js
let name = "kittens";
if (name === "puppies") {
  name += " woof";
} else if (name === "kittens") {
  name += " meow";
} else {
  name += "!";
}
name === "kittens meow";
```

JavaScript doesn't have `elif`, and `else if` is really just an `else` branch comprised of a single `if` statement.

JavaScript has `while` loops and `do...while` loops. The first is good for basic looping; the second is for loops where you wish to ensure that the body of the loop is executed at least once:

```js
while (true) {
  // an infinite loop!
}

let input;
do {
  input = get\_input();
} while (inputIsNotValid(input));
```

JavaScript's `for` loop is the same as that in C and Java: it lets you provide the control information for your loop on a single line.

```js
for (let i = 0; i < 5; i++) {
  // Will execute 5 times
}
```

JavaScript also contains two other prominent for loops: `for...of`, which iterates over iterables, most notably arrays, and `for...in`, which visits all enumerable properties of an object.

```js
for (const value of array) {
  // do something with value
}

for (const property in object) {
  // do something with object property
}
```

The `switch` statement can be used for multiple branches based on equality checking.

```js
switch (action) {
  case "draw":
    drawIt();
    break;
  case "eat":
    eatIt();
    break;
  default:
    doNothing();
}
```

Similar to C, case clauses are conceptually the same as labels, so if you don't add a `break` statement, execution will "fall through" to the next level. However, they are not actually jump tables — any expression can be part of the `case` clause, not just string or number literals, and they would be evaluated one-by-one until one equals the value being matched. Comparison takes place between the two using the `===` operator.

Unlike some languages like Rust, control-flow structures are statements in JavaScript, meaning you can't assign them to a variable, like `const a = if (x) { 1 } else { 2 }`.

JavaScript errors are handled using the `try...catch` statement.

```js
try {
  buildMySite("./website");
} catch (e) {
  console.error("Building site failed:", e);
}
```

Errors can be thrown using the `throw` statement. Many built-in operations may throw as well.

```js
function buildMySite(siteDirectory) {
  if (!pathExists(siteDirectory)) {
    throw new Error("Site directory does not exist");
  }
}
```

In general, you can't tell the type of the error you just caught, because anything can be thrown from a `throw` statement. However, you can usually assume it's an `Error` instance, as is the example above. There are some subclasses of `Error` built-in, like `TypeError` and `RangeError`, that you can use to provide extra semantics about the error. There's no conditional catch in JavaScript — if you only want to handle one type of error, you need to catch everything, identify the type of error using `instanceof`, and then rethrow the other cases.

```js
try {
  buildMySite("./website");
} catch (e) {
  if (e instanceof RangeError) {
    console.error("Seems like a parameter is out of range:", e);
    console.log("Retrying...");
    buildMySite("./website");
  } else {
    // Don't know how to handle other error types; throw them so
    // something else up in the call stack may catch and handle it
    throw e;
  }
}
```

If an error is uncaught by any `try...catch` in the call stack, the program will exit.

For a comprehensive list of control flow statements, see the reference section.

Objects
-------

JavaScript objects can be thought of as collections of key-value pairs. As such, they are similar to:

* Dictionaries in Python.
* Hashes in Perl and Ruby.
* Hash tables in C and C++.
* HashMaps in Java.
* Associative arrays in PHP.

JavaScript objects are hashes. Unlike objects in statically typed languages, objects in JavaScript do not have fixed shapes — properties can be added, deleted, re-ordered, mutated, or dynamically queried at any time. Object keys are always strings or symbols — even array indices, which are canonically integers, are actually strings under the hood.

Objects are usually created using the literal syntax:

```js
const obj = {
  name: "Carrot",
  for: "Max",
  details: {
    color: "orange",
    size: 12,
  },
};
```

Object properties can be accessed using dot (`.`) or square brackets (`[]`). When using the dot notation, the key must be a valid identifier. Square brackets, on the other hand, allow indexing the object with a dynamic key value.

```js
// Dot notation
obj.name = "Simon";
const name = obj.name;

// Bracket notation
obj["name"] = "Simon";
const name = obj["name"];

// Can use a variable to define a key
const userName = prompt("what is your key?");
obj[userName] = prompt("what is its value?");
```

Property access can be chained together:

```js
obj.details.color; // orange
obj["details"]["size"]; // 12
```

Objects are always references, so unless something is explicitly copying the object, mutations to an object would be visible to the outside.

```js
const obj = {};
function doSomething(o) {
  o.x = 1;
}
doSomething(obj);
console.log(obj.x); // 1
```

This also means two separately created objects will never be equal (`!==`), because they are different references. If you hold two references of the same object, mutating one would be observable through the other.

```js
const me = {};
const stillMe = me;
me.x = 1;
console.log(stillMe.x); // 1
```

For more on objects and prototypes, see the `Object` reference page. For more information on the object initializer syntax, see its reference page.

This page has omitted all details about object prototypes and inheritance because you can usually achieve inheritance with classes without touching the underlying mechanism (which you may have heard to be abstruse). To learn about them, see Inheritance and the prototype chain.

Arrays
------

Arrays in JavaScript are actually a special type of object. They work very much like regular objects (numerical properties can naturally be accessed only using `[]` syntax) but they have one magic property called `length`. This is always one more than the highest index in the array.

Arrays are usually created with array literals:

```js
const a = ["dog", "cat", "hen"];
a.length; // 3
```

JavaScript arrays are still objects — you can assign any properties to them, including arbitrary number indices. The only "magic" is that `length` will be automatically updated when you set a particular index.

```js
const a = ["dog", "cat", "hen"];
a[100] = "fox";
console.log(a.length); // 101
console.log(a); // ['dog', 'cat', 'hen', empty × 97, 'fox']
```

The array we got above is called a *sparse array* because there are uninhabited slots in the middle, and will cause the engine to deoptimize it from an array to a hash table. Make sure your array is densely populated!

Out-of-bounds indexing doesn't throw. If you query a non-existent array index, you'll get a value of `undefined` in return:

```js
const a = ["dog", "cat", "hen"];
console.log(typeof a[90]); // undefined
```

Arrays can have any elements and can grow or shrink arbitrarily.

```js
const arr = [1, "foo", true];
arr.push({});
// arr = [1, "foo", true, {}]
```

Arrays can be iterated with the `for` loop, as you can in other C-like languages:

```js
for (let i = 0; i < a.length; i++) {
  // Do something with a[i]
}
```

Or, since arrays are iterable, you can use the `for...of` loop, which is synonymous to C++/Java's `for (int x : arr)` syntax:

```js
for (const currentValue of a) {
  // Do something with currentValue
}
```

Arrays come with a plethora of array methods. Many of them would iterate the array — for example, `map()` would apply a callback to every array element, and return a new array:

```js
const babies = ["dog", "cat", "hen"].map((name) => `baby ${name}`);
// babies = ['baby dog', 'baby cat', 'baby hen']
```

Functions
---------

Along with objects, functions are the core component in understanding JavaScript. The most basic function declaration looks like this:

```js
function add(x, y) {
  const total = x + y;
  return total;
}
```

A JavaScript function can take 0 or more parameters. The function body can contain as many statements as you like and can declare its own variables which are local to that function. The `return` statement can be used to return a value at any time, terminating the function. If no return statement is used (or an empty return with no value), JavaScript returns `undefined`.

Functions can be called with more or fewer parameters than it specifies. If you call a function without passing the parameters it expects, they will be set to `undefined`. If you pass more parameters than it expects, the function will ignore the extra parameters.

```js
add(); // NaN
// Equivalent to add(undefined, undefined)

add(2, 3, 4); // 5
// added the first two; 4 was ignored
```

There are a number of other parameter syntaxes available. For example, the rest parameter syntax allows collecting all the extra parameters passed by the caller into an array, similar to Python's `*args`. (Since JS doesn't have named parameters on the language level, there's no `**kwargs`.)

```js
function avg(...args) {
  let sum = 0;
  for (const item of args) {
    sum += item;
  }
  return sum / args.length;
}

avg(2, 3, 4, 5); // 3.5
```

In the above code, the variable `args` holds all the values that were passed into the function.

The rest parameter will store all arguments *after* where it's declared, but not before. In other words, `function avg(firstValue, ...args)` will store the first value passed into the function in the `firstValue` variable and the remaining arguments in `args`.

If a function accepts a list of arguments and you already hold them in an array, you can use the spread syntax in the function call to *spread* the array as a list of elements. For instance: `avg(...numbers)`.

We mentioned that JavaScript doesn't have named parameters. It's possible, though, to implement them using object destructuring, which allows objects to be conveniently packed and unpacked.

```js
// Note the { } braces: this is destructuring an object
function area({ width, height }) {
  return width \* height;
}

// The { } braces here create a new object
console.log(area({ width: 2, height: 3 }));
```

There's also the *default parameter* syntax, which allows omitted parameters (or those passed as `undefined`) to have a default value.

```js
function avg(firstValue, secondValue, thirdValue = 0) {
  return (firstValue + secondValue + thirdValue) / 3;
}

avg(1, 2); // 1, instead of NaN
```

### Anonymous functions

JavaScript lets you create anonymous functions — that is, functions without names. In practice, anonymous functions are typically used as arguments to other functions, immediately assigned to a variable that can be used to invoke the function, or returned from another function.

```js
// Note that there's no function name before the parentheses
const avg = function (...args) {
  let sum = 0;
  for (const item of args) {
    sum += item;
  }
  return sum / args.length;
};
```

That makes the anonymous function invocable by calling `avg()` with some arguments — that is, it's semantically equivalent to declaring the function using the `function avg() {}` declaration syntax.

There's another way to define anonymous functions — using an arrow function expression.

```js
// Note that there's no function name before the parentheses
const avg = (...args) => {
  let sum = 0;
  for (const item of args) {
    sum += item;
  }
  return sum / args.length;
};

// You can omit the `return` when simply returning an expression
const sum = (a, b, c) => a + b + c;
```

Arrow functions are not semantically equivalent to function expressions — for more information, see its reference page.

There's another way that anonymous functions can be useful: it can be simultaneously declared and invoked in a single expression, called an Immediately invoked function expression (IIFE):

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

For use-cases of IIFEs, you can read emulating private methods with closures.

### Recursive functions

JavaScript allows you to call functions recursively. This is particularly useful for dealing with tree structures, such as those found in the browser DOM.

```js
function countChars(elm) {
  if (elm.nodeType === 3) {
    // TEXT\_NODE
    return elm.nodeValue.length;
  }
  let count = 0;
  for (let i = 0, child; (child = elm.childNodes[i]); i++) {
    count += countChars(child);
  }
  return count;
}
```

Function expressions can be named as well, which allows them to be recursive.

```js
const charsInBody = (function counter(elm) {
  if (elm.nodeType === 3) {
    // TEXT\_NODE
    return elm.nodeValue.length;
  }
  let count = 0;
  for (let i = 0, child; (child = elm.childNodes[i]); i++) {
    count += counter(child);
  }
  return count;
})(document.body);
```

The name provided to a function expression as above is only available to the function's own scope. This allows more optimizations to be done by the engine and results in more readable code. The name also shows up in the debugger and some stack traces, which can save you time when debugging.

If you are used to functional programming, beware of the performance implications of recursion in JavaScript. Although the language specification specifies tail-call optimization, only JavaScriptCore (used by Safari) has implemented it, due to the difficulty of recovering stack traces and debuggability. For deep recursion, consider using iteration instead to avoid stack overflow.

### Functions are first-class objects

JavaScript functions are first-class objects. This means that they can be assigned to variables, passed as arguments to other functions, and returned from other functions. In addition, JavaScript supports closures out-of-the-box without explicit capturing, allowing you to conveniently apply functional programming styles.

```js
// Function returning function
const add = (x) => (y) => x + y;
// Function accepting function
const babies = ["dog", "cat", "hen"].map((name) => `baby ${name}`);
```

Note that JavaScript functions are themselves objects — like everything else in JavaScript — and you can add or change properties on them just like we've seen earlier in the Objects section.

### Inner functions

JavaScript function declarations are allowed inside other functions. An important detail of nested functions in JavaScript is that they can access variables in their parent function's scope:

```js
function parentFunc() {
  const a = 1;

  function nestedFunc() {
    const b = 4; // parentFunc can't use this
    return a + b;
  }
  return nestedFunc(); // 5
}
```

This provides a great deal of utility in writing more maintainable code. If a called function relies on one or two other functions that are not useful to any other part of your code, you can nest those utility functions inside it. This keeps the number of functions that are in the global scope down.

This is also a great counter to the lure of global variables. When writing complex code, it is often tempting to use global variables to share values between multiple functions, which leads to code that is hard to maintain. Nested functions can share variables in their parent, so you can use that mechanism to couple functions together without polluting your global namespace.

Classes
-------

JavaScript offers the class syntax that's very similar to languages like Java.

```js
class Person {
  constructor(name) {
    this.name = name;
  }
  sayHello() {
    return `Hello, I'm ${this.name}!`;
  }
}

const p = new Person("Maria");
console.log(p.sayHello());
```

JavaScript classes are just functions that must be instantiated with the `new` operator. Every time a class is instantiated, it returns an object containing the methods and properties that the class specified. Classes don't enforce any code organization — for example, you can have functions returning classes, or you can have multiple classes per file. Here's an example of how ad hoc the creation of a class can be: it's just an expression returned from an arrow function. This pattern is called a mixin.

```js
const withAuthentication = (cls) =>
  class extends cls {
    authenticate() {
      // …
    }
  };

class Admin extends withAuthentication(Person) {
  // …
}
```

Static properties are created by prepending `static`. Private properties are created by prepending a hash `#` (not `private`). The hash is an integral part of the property name. (Think about `#` as `_` in Python.) Unlike most other languages, there's absolutely no way to read a private property outside the class body — not even in derived classes.

For a detailed guide on various class features, you can read the guide page.

Asynchronous programming
------------------------

JavaScript is single-threaded by nature. There's no paralleling; only concurrency. Asynchronous programming is powered by an event loop, which allows a set of tasks to be queued and polled for completion.

There are three idiomatic ways to write asynchronous code in JavaScript:

* Callback-based (such as `setTimeout()`)
* `Promise`-based
* `async`/`await`, which is a syntactic sugar for Promises

For example, here's what a file-read operation might look like in JavaScript:

```js
// Callback-based
fs.readFile(filename, (err, content) => {
  // This callback is invoked when the file is read, which could be after a while
  if (err) {
    throw err;
  }
  console.log(content);
});
// Code here will be executed while the file is waiting to be read

// Promise-based
fs.readFile(filename)
  .then((content) => {
    // What to do when the file is read
    console.log(content);
  })
  .catch((err) => {
    throw err;
  });
// Code here will be executed while the file is waiting to be read

// Async/await
async function readFile(filename) {
  const content = await fs.readFile(filename);
  console.log(content);
}
```

The core language doesn't specify any asynchronous programming features, but it's crucial when interacting with the external environment — from asking user permissions, to fetching data, to reading files. Keeping the potentially long-running operations async ensures that other processes can still run while this one waits — for example, the browser will not freeze while waiting for the user to click a button to grant permission.

If you have an async value, it's not possible to get its value synchronously. For example, if you have a promise, you can only access the eventual result via the `then()` method. Similarly, `await` can only be used in an async context, which is usually an async function or a module. Promises are *never blocking* — only the logic depending on the promise's result will be deferred; everything else continues to execute in the meantime. If you are a functional programmer, you may recognize promises as monads which can be mapped with `then()` (however, they are not *proper* monads because they auto-flatten; i.e. you can't have a `Promise<Promise<T>>`).

In fact, the single-threaded model has made Node.js a popular choice for server-side programming due to its non-blocking IO, making handling a large number of database or file-system requests very performant. However, CPU-bound (computationally intensive) tasks that are pure JavaScript will still block the main thread. To achieve real paralleling, you may need to use workers.

To learn more about asynchronous programming, you can read about using promises or follow the asynchronous JavaScript tutorial.

Modules
-------

JavaScript also specifies a module system supported by most runtimes. A module is usually a file, identified by its file path or URL. You can use the `import` and `export` statements to exchange data between modules:

```js
import { foo } from "./foo.js";

// Unexported variables are local to the module
const b = 2;

export const a = 1;
```

Unlike Haskell, Python, Java, etc., JavaScript module resolution is entirely host-defined — it's usually based on URLs or file paths, so relative file paths "just work" and are relative to the current module's path instead of some project root path.

However, the JavaScript language doesn't offer standard library modules — all core functionalities are powered by global variables like `Math` and `Intl` instead. This is due to the long history of JavaScript lacking a module system, and the fact that opting into the module system involves some changes to the runtime setup.

Different runtimes may use different module systems. For example, Node.js uses the package manager npm and is mostly file-system based, while Deno and browsers are fully URL-based and modules can be resolved from HTTP URLs.

For more information, see the modules guide page.

Language and runtime
--------------------

Throughout this page, we've constantly mentioned that certain features are *language-level* while others are *runtime-level*.

JavaScript is a general-purpose scripting language. The core language specification focuses on pure computational logic. It doesn't deal with any input/output — in fact, without extra runtime-level APIs (most notably `console.log()`), a JavaScript program's behavior is entirely unobservable.

A runtime, or a host, is something that feeds data to the JavaScript engine (the interpreter), provides extra global properties, and provides hooks for the engine to interact with the outside world. Module resolution, reading data, printing messages, sending network requests, etc. are all runtime-level operations. Since its inception, JavaScript has been adopted in various environments, such as browsers (which provide APIs like DOM), Node.js (which provides APIs like file system access), etc. JavaScript has been successfully integrated in web (which was its primary purpose), mobile apps, desktop apps, server-side apps, serverless, embedded systems, and more. While you learn about JavaScript core features, it's also important to understand host-provided features in order to put the knowledge to use. For example, you can read about all web platform APIs, which are implemented by browsers, and sometimes non-browsers.

Further exploration
-------------------

This page offers a very basic insight into how various JavaScript features compare with other languages. If you want to learn more about the language itself and the nuances of each feature, you can read the JavaScript guide and the JavaScript reference.

There are some essential parts of the language that we have omitted due to space and complexity, but you can explore on your own:

* Inheritance and the prototype chain
* Closures
* Regular expressions
* Iteration


JavaScript Guide - JavaScript

JavaScript Guide
================

The JavaScript Guide shows you how to use JavaScript and gives an overview of the language. If you need exhaustive information about a language feature, have a look at the JavaScript reference.

This Guide is divided into the following chapters.

Introduction
------------

Overview: Introduction

* About this guide
* About JavaScript
* JavaScript and Java
* ECMAScript
* Tools
* Hello World
Grammar and types
-----------------

Overview: Grammar and types

* Basic syntax & comments
* Declarations
* Variable scope
* Variable hoisting
* Data structures and types
* Literals
Control flow and error handling
-------------------------------

Overview: Control flow and error handling

* `if...else`
* `switch`
* `try`/`catch`/`throw`
* Error objects
Loops and iteration
-------------------

Overview: Loops and iteration

* `for`
* `while`
* `do...while`
* `continue`
* `break`
* `for...in`
* `for...of`
Functions
---------

Overview: Functions

* Defining functions
* Calling functions
* Function scope
* Closures
* Arguments & parameters
* Arrow functions
Expressions and operators
-------------------------

Overview: Expressions and operators

* Assignment & Comparisons
* Arithmetic operators
* Bitwise & logical operators
* Conditional (ternary) operator
Numbers and dates
-----------------

Overview: Numbers and dates

* Number literals
* `Number` object
* `Math` object
* `Date` object
Text formatting
---------------

Overview: Text formatting

* String literals
* `String` object
* Template literals
* Internationalization
* Regular Expressions
Indexed collections
-------------------

Overview: Indexed collections

Keyed collections
-----------------

Overview: Keyed collections

* `Map`
* `WeakMap`
* `Set`
* `WeakSet`
Working with objects
--------------------

Overview: Working with objects

* Objects and properties
* Creating objects
* Defining methods
* Getter and setter
Using classes
-------------

Overview: Using classes

* Declaring a class
* Various class features
* Extends and inheritance
* Why classes?
Promises
--------

Overview: Promises

* Guarantees
* Chaining
* Error handling
* Composition
* Timing
Typed arrays
------------

Overview: Typed arrays

Iterators and generators
------------------------

Overview: Iterators and generators

* Iterators
* Iterables
* Generators
Meta programming
----------------

Overview: Meta programming

* `Proxy`
* Handlers and traps
* Revocable Proxy
* `Reflect`
JavaScript modules
------------------

Overview: JavaScript modules

* Exporting
* Importing
* Default exports
* Renaming features
* Aggregating modules
* Dynamic module loading
* Next »


Regular expressions - JavaScript

Regular expressions
===================

A **regular expression** (*regex* for short) allow developers to match strings against a pattern, extract submatch information, or simply test if the string conforms to that pattern. Regular expressions are used in many programming languages, and JavaScript's syntax is inspired by Perl.

You are encouraged to read the regular expressions guide to get an overview of the available regex syntaxes and how they work.

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

*Regular expressions* are a important concept in formal language theory. They are a way to describe a possibly infinite set of character strings (called a *language*). A regular expression, at its core, needs the following features:

* A set of *characters* that can be used in the language, called the *alphabet*.
* *Concatenation*: `ab` means "the character `a` followed by the character `b`".
* *Union*: `a|b` means "either `a` or `b`".
* *Kleene star*: `a*` means "zero or more `a` characters".

Assuming a finite alphabet (such as the 26 letters of the English alphabet, or the entire Unicode character set), all regular languages can be generated by the features above. Of course, many patterns are very tedious to express this way (such as "10 digits" or "a character that's not a space"), so JavaScript regular expressions include many shorthands, introduced below.

**Note:** JavaScript regular expressions are in fact not regular, due to the existence of backreferences (regular expressions must have finite states). However, they are still a very useful feature.

### Creating regular expressions

A regular expression is typically created as a literal by enclosing a pattern in forward slashes (`/`):

```js
const regex1 = /ab+c/g;
```

Regular expressions can also be created with the `RegExp()` constructor:

```js
const regex2 = new RegExp("ab+c", "g");
```

They have no runtime differences, although they may have implications on performance, static analyzability, and authoring ergonomic issues with escaping characters. For more information, see the `RegExp` reference.

### Regex flags

Flags are special parameters that can change the way a regular expression is interpreted or the way it interacts with the input text. Each flag corresponds to one accessor property on the `RegExp` object.

| Flag | Description | Corresponding property |
| --- | --- | --- |
| `d` | Generate indices for substring matches. | `hasIndices` |
| `g` | Global search. | `global` |
| `i` | Case-insensitive search. | `ignoreCase` |
| `m` | Allows `^` and `$` to match next to newline characters. | `multiline` |
| `s` | Allows `.` to match newline characters. | `dotAll` |
| `u` | "Unicode"; treat a pattern as a sequence of Unicode code points. | `unicode` |
| `v` | An upgrade to the `u` mode with more Unicode features. | `unicodeSets` |
| `y` | Perform a "sticky" search that matches starting at the current position in the target string. | `sticky` |

The sections below list all available regex syntaxes, grouped by their syntactic nature.

### Assertions

Assertions are constructs that test whether the string meets a certain condition at the specified position, but not consume characters. Assertions cannot be quantified.

Input boundary assertion: `^`, `$`

Asserts that the current position is the start or end of input, or start or end of a line if the `m` flag is set.

Lookahead assertion: `(?=...)`, `(?!...)`

Asserts that the current position is followed or not followed by a certain pattern.

Lookbehind assertion: `(?<=...)`, `(?<!...)`

Asserts that the current position is preceded or not preceded by a certain pattern.

Word boundary assertion: `\b`, `\B`

Asserts that the current position is a word boundary.

### Atoms

Atoms are the most basic units of a regular expression. Each atom *consumes* one or more characters in the string, and either fails the match or allows the pattern to continue matching with the next atom.

Backreference: `\1`, `\2`

Matches a previously matched subpattern captured with a capturing group.

Capturing group: `(...)`

Matches a subpattern and remembers information about the match.

Character class: `[...]`, `[^...]`

Matches any character in or not in a set of characters. When the `v` flag is enabled, it can also be used to match finite-length strings.

Character class escape: `\d`, `\D`, `\w`, `\W`, `\s`, `\S`

Matches any character in or not in a predefined set of characters.

Character escape: `\n`, `\u{...}`

Matches a character that may not be able to be conveniently represented in its literal form.

Literal character: `a`, `b`

Matches a specific character.

Named backreference: `\k<name>`

Matches a previously matched subpattern captured with a named capturing group.

Named capturing group: `(?<name>...)`

Matches a subpattern and remembers information about the match. The group can later be identified by a custom name instead of by its index in the pattern.

Non-capturing group: `(?:...)`

Matches a subpattern without remembering information about the match.

Unicode character class escape: `\p{...}`, `\P{...}`

Matches a set of characters specified by a Unicode property. When the `v` flag is enabled, it can also be used to match finite-length strings.

Wildcard: `.`

Matches any character except line terminators, unless the `s` flag is set.

### Other features

These features do not specify any pattern themselves, but are used to compose patterns.

Disjunction: `|`

Matches any of a set of alternatives separated by the `|` character.

Quantifier: `*`, `+`, `?`, `{n}`, `{n,}`, `{n,m}`

Matches an atom a certain number of times.

### Escape sequences

*Escape sequences* in regexes refer to any kind of syntax formed by `\` followed by one or more characters. They may serve very different purposes depending on what follow `\`. Below is a list of all valid "escape sequences":

| Escape sequence | Followed by | Meaning |
| --- | --- | --- |
| `\B` | None | Non-word-boundary assertion |
| `\D` | None | Character class escape representing non-digit characters |
| `\P` | `{`, a Unicode property and/or value, then `}` | Unicode character class escape representing characters without the specified Unicode property |
| `\S` | None | Character class escape representing non-white-space characters |
| `\W` | None | Character class escape representing non-word characters |
| `\b` | None | Word boundary assertion; inside character classes, represents U+0008 (BACKSPACE) |
| `\c` | A letter from `A` to `Z` or `a` to `z` | A character escape representing the control character with value equal to the letter's character value modulo 32 |
| `\d` | None | Character class escape representing digit characters (`0` to `9`) |
| `\f` | None | Character escape representing U+000C (FORM FEED) |
| `\k` | `<`, an identifier, then `>` | A named backreference |
| `\n` | None | Character escape representing U+000A (LINE FEED) |
| `\p` | `{`, a Unicode property and/or value, then `}` | Unicode character class escape representing characters with the specified Unicode property |
| `\q` | `{`, a string, then a `}` | Only valid inside `v`-mode character classes; represents the string to be matched literally |
| `\r` | None | Character escape representing U+000D (CARRIAGE RETURN) |
| `\s` | None | Character class escape representing whitespace characters |
| `\t` | None | Character escape representing U+0009 (CHARACTER TABULATION) |
| `\u` | 4 hexadecimal digits; or `{`, 1 to 6 hexadecimal digits, then `}` | Character escape representing the character with the given code point |
| `\v` | None | Character escape representing U+000B (LINE TABULATION) |
| `\w` | None | Character class escape representing word characters (`A` to `Z`, `a` to `z`, `0` to `9`, `_`) |
| `\x` | 2 hexadecimal digits | Character escape representing the character with the given value |
| `\0` | None | Character escape representing U+0000 (NULL) |

`\` followed by any other digit character becomes a legacy octal escape sequence, which is forbidden in Unicode-aware mode.

In addition, `\` can be followed by some non-letter-or-digit characters, in which case the escape sequence is always a character escape representing the escaped character itself:

* `\$`, `\(`, `\)`, `\*`, `\+`, `\.`, `\/`, `\?`, `\[`, `\\`, `\]`, `\^`, `{`, `\|`, `}`: valid everywhere
* `\-`: only valid inside character classes
* `\!`, `\#`, `\%`, `\&`, `\,`, `\:`, `\;`, `\<`, `\=`, `\>`, `\@`, `\``, `\~`: only valid inside `v`-mode character classes

The other ASCII characters, namely space character, `"`, `'`, `_`, and any letter character not mentioned above, are not valid escape sequences. In Unicode-unaware mode, escape sequences that are not one of the above become *identity escapes*: they represent the character that follows the backslash. For example, `\a` represents the character `a`. This behavior limits the ability to introduce new escape sequences without causing backward compatibility issues, and is therefore forbidden in Unicode-aware mode.

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-DecimalEscape |
| ECMAScript Language Specification # prod-Atom |
| ECMAScript Language Specification # prod-CharacterClass |
| ECMAScript Language Specification # prod-CharacterClassEscape |
| ECMAScript Language Specification # prod-CharacterEscape |
| ECMAScript Language Specification # prod-Disjunction |
| ECMAScript Language Specification # prod-Assertion |
| ECMAScript Language Specification # prod-PatternCharacter |
| ECMAScript Language Specification # prod-AtomEscape |
| ECMAScript Language Specification # prod-Quantifier |

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

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

See also
--------

* Regular expressions guide
* `RegExp`


Iteration protocols - JavaScript

Iteration protocols
===================

**Iteration protocols** aren't new built-ins or syntax, but *protocols*. These protocols can be implemented by any object by following some conventions.

There are two protocols: The iterable protocol and the iterator protocol.

The iterable protocol
---------------------

**The iterable protocol** allows JavaScript objects to define or customize their iteration behavior, such as what values are looped over in a `for...of` construct. Some built-in types are built-in iterables with a default iteration behavior, such as `Array` or `Map`, while other types (such as `Object`) are not.

In order to be **iterable**, an object must implement the **`@@iterator`** method, meaning that the object (or one of the objects up its prototype chain) must have a property with a `@@iterator` key which is available via constant `Symbol.iterator`:

`[Symbol.iterator]`

A zero-argument function that returns an object, conforming to the iterator protocol.

Whenever an object needs to be iterated (such as at the beginning of a `for...of` loop), its `@@iterator` method is called with no arguments, and the returned **iterator** is used to obtain the values to be iterated.

Note that when this zero-argument function is called, it is invoked as a method on the iterable object. Therefore inside of the function, the `this` keyword can be used to access the properties of the iterable object, to decide what to provide during the iteration.

This function can be an ordinary function, or it can be a generator function, so that when invoked, an iterator object is returned. Inside of this generator function, each entry can be provided by using `yield`.

The iterator protocol
---------------------

**The iterator protocol** defines a standard way to produce a sequence of values (either finite or infinite), and potentially a return value when all values have been generated.

An object is an iterator when it implements a **`next()`** method with the following semantics:

`next()`

A function that accepts zero or one argument and returns an object conforming to the `IteratorResult` interface (see below). If a non-object value gets returned (such as `false` or `undefined`) when a built-in language feature (such as `for...of`) is using the iterator, a `TypeError` (`"iterator.next() returned a non-object value"`) will be thrown.

All iterator protocol methods (`next()`, `return()`, and `throw()`) are expected to return an object implementing the `IteratorResult` interface. It must have the following properties:

`done` Optional

A boolean that's `false` if the iterator was able to produce the next value in the sequence. (This is equivalent to not specifying the `done` property altogether.)

Has the value `true` if the iterator has completed its sequence. In this case, `value` optionally specifies the return value of the iterator.

`value` Optional

Any JavaScript value returned by the iterator. Can be omitted when `done` is `true`.

In practice, neither property is strictly required; if an object without either property is returned, it's effectively equivalent to `{ done: false, value: undefined }`.

If an iterator returns a result with `done: true`, any subsequent calls to `next()` are expected to return `done: true` as well, although this is not enforced on the language level.

The `next` method can receive a value which will be made available to the method body. No built-in language feature will pass any value. The value passed to the `next` method of generators will become the value of the corresponding `yield` expression.

Optionally, the iterator can also implement the **`return(value)`** and **`throw(exception)`** methods, which, when called, tells the iterator that the caller is done with iterating it and can perform any necessary cleanup (such as closing database connection).

`return(value)` Optional

A function that accepts zero or one argument and returns an object conforming to the `IteratorResult` interface, typically with `value` equal to the `value` passed in and `done` equal to `true`. Calling this method tells the iterator that the caller does not intend to make any more `next()` calls and can perform any cleanup actions.

`throw(exception)` Optional

A function that accepts zero or one argument and returns an object conforming to the `IteratorResult` interface, typically with `done` equal to `true`. Calling this method tells the iterator that the caller detects an error condition, and `exception` is typically an `Error` instance.

**Note:** It is not possible to know reflectively (i.e. without actually calling `next()` and validating the returned result) whether a particular object implements the iterator protocol.

It is very easy to make an iterator also iterable: just implement an `[@@iterator]()` method that returns `this`.

```js
// Satisfies both the Iterator Protocol and Iterable
const myIterator = {
  next() {
    // ...
  },
  [Symbol.iterator]() {
    return this;
  },
};
```

Such object is called an *iterable iterator*. Doing so allows an iterator to be consumed by the various syntaxes expecting iterables — therefore, it is seldom useful to implement the Iterator Protocol without also implementing Iterable. (In fact, almost all syntaxes and APIs expect *iterables*, not *iterators*.) The generator object is an example:

```js
const aGeneratorObject = (function\* () {
  yield 1;
  yield 2;
  yield 3;
})();

console.log(typeof aGeneratorObject.next);
// "function" — it has a next method (which returns the right result), so it's an iterator

console.log(typeof aGeneratorObject[Symbol.iterator]);
// "function" — it has an @@iterator method (which returns the right iterator), so it's an iterable

console.log(aGeneratorObject[Symbol.iterator]() === aGeneratorObject);
// true — its @@iterator method returns itself (an iterator), so it's an iterable iterator
```

All built-in iterators inherit from `Iterator.prototype`, which implements the `[@@iterator]()` method as returning `this`, so that built-in iterators are also iterable.

However, when possible, it's better for `iterable[Symbol.iterator]` to return different iterators that always start from the beginning, like `Set.prototype[@@iterator]()` does.

The async iterator and async iterable protocols
-----------------------------------------------

There are another pair of protocols used for async iteration, named **async iterator** and **async iterable** protocols. They have very similar interfaces compared to the iterable and iterator protocols, except that each return value from the calls to the iterator methods is wrapped in a promise.

An object implements the async iterable protocol when it implements the following methods:

`[Symbol.asyncIterator]`

A zero-argument function that returns an object, conforming to the async iterator protocol.

An object implements the async iterator protocol when it implements the following methods:

`next()`

A function that accepts zero or one argument and returns a promise. The promise fulfills to an object conforming to the `IteratorResult` interface, and the properties have the same semantics as those of the sync iterator's.

`return(value)` Optional

A function that accepts zero or one argument and returns a promise. The promise fulfills to an object conforming to the `IteratorResult` interface, and the properties have the same semantics as those of the sync iterator's.

`throw(exception)` Optional

A function that accepts zero or one argument and returns a promise. The promise fulfills to an object conforming to the `IteratorResult` interface, and the properties have the same semantics as those of the sync iterator's.

Interactions between the language and iteration protocols
---------------------------------------------------------

The language specifies APIs that either produce or consume iterables and iterators.

### Built-in iterables

`String`, `Array`, `TypedArray`, `Map`, `Set`, and `Segments` (returned by `Intl.Segmenter.prototype.segment()`) are all built-in iterables, because each of their `prototype` objects implements an `@@iterator` method. In addition, the `arguments` object and some DOM collection types such as `NodeList` are also iterables.
 There is no object in the core JavaScript language that is async iterable. Some web APIs, such as `ReadableStream`, have the `Symbol.asyncIterator` method set by default.

Generator functions return generator objects, which are iterable iterators. Async generator functions return async generator objects, which are async iterable iterators.

The iterators returned from built-in iterables actually all inherit from a common class `Iterator`, which implements the aforementioned `[Symbol.iterator]() { return this; }` method, making them all iterable iterators. The `Iterator` class also provides additional helper methods in addition to the `next()` method required by the iterator protocol. You can inspect an iterator's prototype chain by logging it in a graphical console.
```

console.log([][Symbol.iterator]());

Array Iterator {}
  [[Prototype]]: Array Iterator     ==> This is the prototype shared by all array iterators
    next: ƒ next()
    Symbol(Symbol.toStringTag): "Array Iterator"
    [[Prototype]]: Object           ==> This is the prototype shared by all built-in iterators
      Symbol(Symbol.iterator): ƒ [Symbol.iterator]()
      [[Prototype]]: Object         ==> This is Object.prototype
```

### Built-in APIs accepting iterables

There are many APIs that accept iterables. Some examples include:

* `Map()`
* `WeakMap()`
* `Set()`
* `WeakSet()`
* `Promise.all()`
* `Promise.allSettled()`
* `Promise.race()`
* `Promise.any()`
* `Array.from()`
* `Object.groupBy()`
* `Map.groupBy()`

```js
const myObj = {};

new WeakSet(
  (function\* () {
    yield {};
    yield myObj;
    yield {};
  })(),
).has(myObj); // true
```

### Syntaxes expecting iterables

Some statements and expressions expect iterables, for example the `for...of` loops, array and parameter spreading, `yield*`, and array destructuring:

```js
for (const value of ["a", "b", "c"]) {
  console.log(value);
}
// "a"
// "b"
// "c"

console.log([..."abc"]); // ["a", "b", "c"]

function\* gen() {
  yield\* ["a", "b", "c"];
}

console.log(gen().next()); // { value: "a", done: false }

[a, b, c] = new Set(["a", "b", "c"]);
console.log(a); // "a"
```

When built-in syntaxes are iterating an iterator, and the last result's `done` is `false` (i.e. the iterator is able to produce more values) but no more values are needed, the `return` method will get called if present. This can happen, for example, if a `break` or `return` is encountered in a `for...of` loop, or if all identifiers are already bound in an array destructuring.

```js
const obj = {
  [Symbol.iterator]() {
    let i = 0;
    return {
      next() {
        i++;
        console.log("Returning", i);
        if (i === 3) return { done: true, value: i };
        return { done: false, value: i };
      },
      return() {
        console.log("Closing");
        return { done: true };
      },
    };
  },
};

const [a] = obj;
// Returning 1
// Closing

const [b, c, d] = obj;
// Returning 1
// Returning 2
// Returning 3
// Already reached the end (the last call returned `done: true`),
// so `return` is not called

for (const b of obj) {
  break;
}
// Returning 1
// Closing
```

The `for await...of` loop and `yield*` in async generator functions (but not sync generator functions) are the only ways to interact with async iterables. Using `for...of`, array spreading, etc. on an async iterable that's not also a sync iterable (i.e. it has `[@@asyncIterator]()` but no `[@@iterator]()`) will throw a TypeError: x is not iterable.

### Non-well-formed iterables

If an iterable's `@@iterator` method doesn't return an iterator object, then it's considered a *non-well-formed* iterable.

Using one is likely to result in runtime errors or buggy behavior:

```js
const nonWellFormedIterable = {};
nonWellFormedIterable[Symbol.iterator] = () => 1;
[...nonWellFormedIterable]; // TypeError: [Symbol.iterator]() returned a non-object value
```

Examples
--------

### User-defined iterables

You can make your own iterables like this:

```js
const myIterable = {
  \*[Symbol.iterator]() {
    yield 1;
    yield 2;
    yield 3;
  },
};

console.log([...myIterable]); // [1, 2, 3]
```

### Simple iterator

Iterators are stateful by nature. If you don't define it as a generator function (as the example above shows), you would likely want to encapsulate the state in a closure.

```js
function makeIterator(array) {
  let nextIndex = 0;
  return {
    next() {
      return nextIndex < array.length
        ? {
            value: array[nextIndex++],
            done: false,
          }
        : {
            done: true,
          };
    },
  };
}

const it = makeIterator(["yo", "ya"]);

console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done); // true
```

### Infinite iterator

```js
function idMaker() {
  let index = 0;
  return {
    next() {
      return {
        value: index++,
        done: false,
      };
    },
  };
}

const it = idMaker();

console.log(it.next().value); // 0
console.log(it.next().value); // 1
console.log(it.next().value); // 2
// ...
```

### Defining an iterable with a generator

```js
function\* makeSimpleGenerator(array) {
  let nextIndex = 0;
  while (nextIndex < array.length) {
    yield array[nextIndex++];
  }
}

const gen = makeSimpleGenerator(["yo", "ya"]);

console.log(gen.next().value); // 'yo'
console.log(gen.next().value); // 'ya'
console.log(gen.next().done); // true

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

const it = idMaker();

console.log(it.next().value); // 0
console.log(it.next().value); // 1
console.log(it.next().value); // 2
// ...
```

### Defining an iterable with a class

State encapsulation can be done with private properties as well.

```js
class SimpleClass {
  #data;

  constructor(data) {
    this.#data = data;
  }

  [Symbol.iterator]() {
    // Use a new index for each iterator. This makes multiple
    // iterations over the iterable safe for non-trivial cases,
    // such as use of break or nested looping over the same iterable.
    let index = 0;

    return {
      // Note: using an arrow function allows `this` to point to the
      // one of `[@@iterator]()` instead of `next()`
      next: () => {
        if (index < this.#data.length) {
          return { value: this.#data[index++], done: false };
        } else {
          return { done: true };
        }
      },
    };
  }
}

const simple = new SimpleClass([1, 2, 3, 4, 5]);

for (const val of simple) {
  console.log(val); // 1 2 3 4 5
}
```

### Overriding built-in iterables

For example, a `String` is a built-in iterable object:

```js
const someString = "hi";
console.log(typeof someString[Symbol.iterator]); // "function"
```

`String`'s default iterator returns the string's code points one by one:

```js
const iterator = someString[Symbol.iterator]();
console.log(`${iterator}`); // "[object String Iterator]"

console.log(iterator.next()); // { value: "h", done: false }
console.log(iterator.next()); // { value: "i", done: false }
console.log(iterator.next()); // { value: undefined, done: true }
```

You can redefine the iteration behavior by supplying our own `@@iterator`:

```js
// need to construct a String object explicitly to avoid auto-boxing
const someString = new String("hi");

someString[Symbol.iterator] = function () {
  return {
    // this is the iterator object, returning a single element (the string "bye")
    next() {
      return this._first
        ? { value: "bye", done: (this._first = false) }
        : { done: true };
    },
    \_first: true,
  };
};
```

Notice how redefining `@@iterator` affects the behavior of built-in constructs that use the iteration protocol:

```js
console.log([...someString]); // ["bye"]
console.log(`${someString}`); // "hi"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-iteration |

See also
--------

* Iterators and generators guide
* `function*`
* `Symbol.iterator`
* `Iterator`


Template literals (Template strings) - JavaScript

Template literals (Template strings)
====================================

**Template literals** are literals delimited with backtick (```) characters, allowing for multi-line strings, string interpolation with embedded expressions, and special constructs called tagged templates.

Template literals are sometimes informally called *template strings*, because they are used most commonly for string interpolation (to create strings by doing substitution of placeholders). However, a tagged template literal may not result in a string; it can be used with a custom tag function to perform whatever operations you want on the different parts of the template literal.

Syntax
------

```js
`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tagFunction`string text ${expression} string text`
```

### Parameters

`string text`

The string text that will become part of the template literal. Almost all characters are allowed literally, including line breaks and other whitespace characters. However, invalid escape sequences will cause a syntax error, unless a tag function is used.

`expression`

An expression to be inserted in the current position, whose value is converted to a string or passed to `tagFunction`.

`tagFunction`

If specified, it will be called with the template strings array and substitution expressions, and the return value becomes the value of the template literal. See tagged templates.

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

Template literals are enclosed by backtick (```) characters instead of double or single quotes.

Along with having normal strings, template literals can also contain other parts called *placeholders*, which are embedded expressions delimited by a dollar sign and curly braces: `${expression}`. The strings and placeholders get passed to a function — either a default function, or a function you supply. The default function (when you don't supply your own) just performs string interpolation to do substitution of the placeholders and then concatenate the parts into a single string.

To supply a function of your own, precede the template literal with a function name; the result is called a **tagged template**. In that case, the template literal is passed to your tag function, where you can then perform whatever operations you want on the different parts of the template literal.

To escape a backtick in a template literal, put a backslash (`\`) before the backtick.

```js
`\`` === "`"; // true
```

Dollar signs can be escaped as well to prevent interpolation.

```js
`\${1}` === "${1}"; // true
```

### Multi-line strings

Any newline characters inserted in the source are part of the template literal.

Using normal strings, you would have to use the following syntax in order to get multi-line strings:

```js
console.log("string text line 1\n" + "string text line 2");
// "string text line 1
// string text line 2"
```

Using template literals, you can do the same with this:

```js
console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"
```

### String interpolation

Without template literals, when you want to combine output from expressions with strings, you'd concatenate them using the addition operator `+`:

```js
const a = 5;
const b = 10;
console.log("Fifteen is " + (a + b) + " and\nnot " + (2 \* a + b) + ".");
// "Fifteen is 15 and
// not 20."
```

That can be hard to read – especially when you have multiple expressions.

With template literals, you can avoid the concatenation operator — and improve the readability of your code — by using placeholders of the form `${expression}` to perform substitutions for embedded expressions:

```js
const a = 5;
const b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 \* a + b}.`);
// "Fifteen is 15 and
// not 20."
```

Note that there's a mild difference between the two syntaxes. Template literals coerce their expressions directly to strings, while addition coerces its operands to primitives first. For more information, see the reference page for the `+` operator.

### Nesting templates

In certain cases, nesting a template is the easiest (and perhaps more readable) way to have configurable strings. Within a backtick-delimited template, it is simple to allow inner backticks by using them inside an `${expression}` placeholder within the template.

For example, without template literals, if you wanted to return a certain value based on a particular condition, you could do something like the following:

```js
let classes = "header";
classes += isLargeScreen()
  ? ""
  : item.isCollapsed
    ? " icon-expander"
    : " icon-collapser";
```

With a template literal but without nesting, you could do this:

```js
const classes = `header ${
 isLargeScreen() ? "" : item.isCollapsed ? "icon-expander" : "icon-collapser"
}`;
```

With nesting of template literals, you can do this:

```js
const classes = `header ${
 isLargeScreen() ? "" : `icon-${item.isCollapsed ? "expander" : "collapser"}`
}`;
```

### Tagged templates

A more advanced form of template literals are *tagged* templates.

Tags allow you to parse template literals with a function. The first argument of a tag function contains an array of string values. The remaining arguments are related to the expressions.

The tag function can then perform whatever operations on these arguments you wish, and return the manipulated string. (Alternatively, it can return something completely different, as described in one of the following examples.)

The name of the function used for the tag can be whatever you want.

```js
const person = "Mike";
const age = 28;

function myTag(strings, personExp, ageExp) {
  const str0 = strings[0]; // "That "
  const str1 = strings[1]; // " is a "
  const str2 = strings[2]; // "."

  const ageStr = ageExp < 100 ? "youngster" : "centenarian";

  // We can even return a string built using a template literal
  return `${str0}${personExp}${str1}${ageStr}${str2}`;
}

const output = myTag`That ${person} is a ${age}.`;

console.log(output);
// That Mike is a youngster.
```

The tag does not have to be a plain identifier. You can use any expression with precedence greater than 16, which includes property access, function call, new expression, or even another tagged template literal.

```js
console.log`Hello`; // [ 'Hello' ]
console.log.bind(1, 2)`Hello`; // 2 [ 'Hello' ]
new Function("console.log(arguments)")`Hello`; // [Arguments] { '0': [ 'Hello' ] }

function recursive(strings, ...values) {
  console.log(strings, values);
  return recursive;
}
recursive`Hello``World`;
// [ 'Hello' ] []
// [ 'World' ] []
```

While technically permitted by the syntax, *untagged* template literals are strings and will throw a `TypeError` when chained.

```js
console.log(`Hello``World`); // TypeError: "Hello" is not a function
```

The only exception is optional chaining, which will throw a syntax error.

```js
console.log?.`Hello`; // SyntaxError: Invalid tagged template on optional chain
console?.log`Hello`; // SyntaxError: Invalid tagged template on optional chain
```

Note that these two expressions are still parsable. This means they would not be subject to automatic semicolon insertion, which will only insert semicolons to fix code that's otherwise unparsable.

```js
// Still a syntax error
const a = console?.log
`Hello`
```

Tag functions don't even need to return a string!

```js
function template(strings, ...keys) {
  return (...values) => {
    const dict = values[values.length - 1] || {};
    const result = [strings[0]];
    keys.forEach((key, i) => {
      const value = Number.isInteger(key) ? values[key] : dict[key];
      result.push(value, strings[i + 1]);
    });
    return result.join("");
  };
}

const t1Closure = template`${0}${1}${0}!`;
// const t1Closure = template(["","","","!"],0,1,0);
t1Closure("Y", "A"); // "YAY!"

const t2Closure = template`${0} ${"foo"}!`;
// const t2Closure = template([""," ","!"],0,"foo");
t2Closure("Hello", { foo: "World" }); // "Hello World!"

const t3Closure = template`I'm ${"name"}. I'm almost ${"age"} years old.`;
// const t3Closure = template(["I'm ", ". I'm almost ", " years old."], "name", "age");
t3Closure("foo", { name: "MDN", age: 30 }); // "I'm MDN. I'm almost 30 years old."
t3Closure({ name: "MDN", age: 30 }); // "I'm MDN. I'm almost 30 years old."
```

The first argument received by the tag function is an array of strings. For any template literal, its length is equal to the number of substitutions (occurrences of `${…}`) plus one, and is therefore always non-empty.

For any particular tagged template literal expression, the tag function will always be called with the exact same literal array, no matter how many times the literal is evaluated.

```js
const callHistory = [];

function tag(strings, ...values) {
  callHistory.push(strings);
  // Return a freshly made object
  return {};
}

function evaluateLiteral() {
  return tag`Hello, ${"world"}!`;
}

console.log(evaluateLiteral() === evaluateLiteral()); // false; each time `tag` is called, it returns a new object
console.log(callHistory[0] === callHistory[1]); // true; all evaluations of the same tagged literal would pass in the same strings array
```

This allows the tag to cache the result based on the identity of its first argument. To further ensure the array value's stability, the first argument and its `raw` property are both frozen, so you can't mutate them in any way.

### Raw strings

The special `raw` property, available on the first argument to the tag function, allows you to access the raw strings as they were entered, without processing escape sequences.

```js
function tag(strings) {
  console.log(strings.raw[0]);
}

tag`string text line 1 \n string text line 2`;
// Logs "string text line 1 \n string text line 2" ,
// including the two characters '\' and 'n'
```

In addition, the `String.raw()` method exists to create raw strings just like the default template function and string concatenation would create.

```js
const str = String.raw`Hi\n${2 + 3}!`;
// "Hi\\n5!"

str.length;
// 6

Array.from(str).join(",");
// "H,i,\\,n,5,!"
```

`String.raw` functions like an "identity" tag if the literal doesn't contain any escape sequences. In case you want an actual identity tag that always works as if the literal is untagged, you can make a custom function that passes the "cooked" (i.e. escape sequences are processed) literal array to `String.raw`, pretending they are raw strings.

```js
const identity = (strings, ...values) =>
  String.raw({ raw: strings }, ...values);
console.log(identity`Hi\n${2 + 3}!`);
// Hi
// 5!
```

This is useful for many tools which give special treatment to literals tagged by a particular name.

```js
const html = (strings, ...values) => String.raw({ raw: strings }, ...values);
// Some formatters will format this literal's content as HTML
const doc = html`<!doctype html>
 <html lang="en-US">
 <head>
 <title>Hello</title>
 </head>
 <body>
 <h1>Hello world!</h1>
 </body>
 </html>`;
```

### Tagged templates and escape sequences

In normal template literals, the escape sequences in string literals are all allowed. Any other non-well-formed escape sequence is a syntax error. This includes:

* `\` followed by any decimal digit other than `0`, or `\0` followed by a decimal digit; for example `\9` and `\07` (which is a deprecated syntax)
* `\x` followed by fewer than two hex digits (including none); for example `\xz`
* `\u` not followed by `{` and followed by fewer than four hex digits (including none); for example `\uz`
* `\u{}` enclosing an invalid Unicode code point — it contains a non-hex digit, or its value is greater than `10FFFF`; for example `\u{110000}` and `\u{z}`

**Note:** `\` followed by other characters, while they may be useless since nothing is escaped, are not syntax errors.

However, this is problematic for tagged templates, which, in addition to the "cooked" literal, also have access to the raw literals (escape sequences are preserved as-is).

Tagged templates should allow the embedding of languages (for example DSLs, or LaTeX), where other escapes sequences are common. Therefore, the syntax restriction of well-formed escape sequences is removed from tagged templates.

```js
latex`\unicode`;
// Throws in older ECMAScript versions (ES2016 and earlier)
// SyntaxError: malformed Unicode character escape sequence
```

However, illegal escape sequences must still be represented in the "cooked" representation. They will show up as `undefined` element in the "cooked" array:

```js
function latex(str) {
  return { cooked: str[0], raw: str.raw[0] };
}

latex`\unicode`;

// { cooked: undefined, raw: "\\unicode" }
```

Note that the escape-sequence restriction is only dropped from *tagged* templates, but not from *untagged* template literals:

```js
const bad = `bad escape sequence: \unicode`;
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-template-literals |

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

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

See also
--------

* Text formatting guide
* `String`
* `String.raw()`
* Lexical grammar
* ES6 in Depth: Template strings on hacks.mozilla.org (2015)


Functions - JavaScript

Functions
=========

Generally speaking, a function is a "subprogram" that can be *called* by code external (or internal, in the case of recursion) to the function. Like the program itself, a function is composed of a sequence of statements called the *function body*. Values can be *passed* to a function as parameters, and the function will *return* a value.

In JavaScript, functions are first-class objects, because they can be passed to other functions, returned from functions, and assigned to variables and properties. They can also have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called.

For more examples and explanations, see the JavaScript guide about functions.

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

Function values are typically instances of `Function`. See `Function` for information on properties and methods of `Function` objects. Callable values cause `typeof` to return `"function"` instead of `"object"`.

**Note:** Not all callable values are `instanceof Function`. For example, the `Function.prototype` object is callable but not an instance of `Function`. You can also manually set the prototype chain of your function so it no longer inherits from `Function.prototype`. However, such cases are extremely rare.

### Return value

By default, if a function's execution doesn't end at a `return` statement, or if the `return` keyword doesn't have an expression after it, then the return value is `undefined`. The `return` statement allows you to return an arbitrary value from the function. One function call can only return one value, but you can simulate the effect of returning multiple values by returning an object or array and destructuring the result.

**Note:** Constructors called with `new` have a different set of logic to determine their return values.

### Passing arguments

Parameters and arguments have slightly different meanings, but in MDN web docs, we often use them interchangeably. For a quick reference:

```js
function formatNumber(num) {
  return num.toFixed(2);
}

formatNumber(2);
```

In this example, the `num` variable is called the function's *parameter*: it's declared in the parenthesis-enclosed list of the function's definition. The function expects the `num` parameter to be a number — although this is not enforceable in JavaScript without writing runtime validation code. In the `formatNumber(2)` call, the number `2` is the function's *argument*: it's the value that is actually passed to the function in the function call. The argument value can be accessed inside the function body through the corresponding parameter name or the `arguments` object.

Arguments are always *passed by value* and never *passed by reference*. This means that if a function reassigns a parameter, the value won't change outside the function. More precisely, object arguments are *passed by sharing*, which means if the object's properties are mutated, the change will impact the outside of the function. For example:

```js
function updateBrand(obj) {
  // Mutating the object is visible outside the function
  obj.brand = "Toyota";
  // Try to reassign the parameter, but this won't affect
  // the variable's value outside the function
  obj = null;
}

const car = {
  brand: "Honda",
  model: "Accord",
  year: 1998,
};

console.log(car.brand); // Honda

// Pass object reference to the function
updateBrand(car);

// updateBrand mutates car
console.log(car.brand); // Toyota
```

The `this` keyword refers to the object that the function is accessed on — it does not refer to the currently executing function, so you must refer to the function value by name, even within the function body.

### Defining functions

Broadly speaking, JavaScript has four kinds of functions:

* Regular function: can return anything; always runs to completion after invocation
* Generator function: returns a `Generator` object; can be paused and resumed with the `yield` operator
* Async function: returns a `Promise`; can be paused and resumed with the `await` operator
* Async generator function: returns an `AsyncGenerator` object; both the `await` and `yield` operators can be used

For every kind of function, there are three ways to define it:

Declaration

`function`, `function*`, `async function`, `async function*`

Expression

`function`, `function*`, `async function`, `async function*`

Constructor

`Function()`, `GeneratorFunction()`, `AsyncFunction()`, `AsyncGeneratorFunction()`

In addition, there are special syntaxes for defining arrow functions and methods, which provide more precise semantics for their usage. Classes are conceptually not functions (because they throw an error when called without `new`), but they also inherit from `Function.prototype` and have `typeof MyClass === "function"`.

```js
// Constructor
const multiply = new Function("x", "y", "return x \* y");

// Declaration
function multiply(x, y) {
  return x \* y;
} // No need for semicolon here

// Expression; the function is anonymous but assigned to a variable
const multiply = function (x, y) {
  return x \* y;
};
// Expression; the function has its own name
const multiply = function funcName(x, y) {
  return x \* y;
};

// Arrow function
const multiply = (x, y) => x \* y;

// Method
const obj = {
  multiply(x, y) {
    return x \* y;
  },
};
```

All syntaxes do approximately the same thing, but there are some subtle behavior differences.

* The `Function()` constructor, `function` expression, and `function` declaration syntaxes create full-fledged function objects, which can be constructed with `new`. However, arrow functions and methods cannot be constructed. Async functions, generator functions, and async generator functions are not constructible regardless of syntax.
* The `function` declaration creates functions that are *hoisted*. Other syntaxes do not hoist the function and the function value is only visible after the definition.
* The arrow function and `Function()` constructor always create *anonymous* functions, which means they can't easily call themselves recursively. One way to call an arrow function recursively is by assigning it to a variable.
* The arrow function syntax does not have access to `arguments` or `this`.
* The `Function()` constructor cannot access any local variables — it only has access to the global scope.
* The `Function()` constructor causes runtime compilation and is often slower than other syntaxes.

For `function` expressions, there is a distinction between the function name and the variable the function is assigned to. The function name cannot be changed, while the variable the function is assigned to can be reassigned. The function name can be different from the variable the function is assigned to — they have no relation to each other. The function name can be used only within the function's body. Attempting to use it outside the function's body results in an error (or gets another value, if the same name is declared elsewhere). For example:

```js
const y = function x() {};
console.log(x); // ReferenceError: x is not defined
```

On the other hand, the variable the function is assigned to is limited only by its scope, which is guaranteed to include the scope in which the function is declared.

A function declaration also creates a variable with the same name as the function name. Thus, unlike those defined by function expressions, functions defined by function declarations can be accessed by their name in the scope they were defined in, as well as in their own body.

A function defined by `new Function` will dynamically have its source assembled, which is observable when you serialize it. For example, `console.log(new Function().toString())` gives:

```js
function anonymous(
) {

}
```

This is the actual source used to compile the function. However, although the `Function()` constructor will create the function with name `anonymous`, this name is not added to the scope of the body. The body only ever has access to global variables. For example, the following would result in an error:

```js
new Function("alert(anonymous);")();
```

A function defined by a function expression or by a function declaration inherits the current scope. That is, the function forms a closure. On the other hand, a function defined by a `Function` constructor does not inherit any scope other than the global scope (which all functions inherit).

```js
// p is a global variable
globalThis.p = 5;
function myFunc() {
  // p is a local variable
  const p = 9;

  function decl() {
    console.log(p);
  }
  const expr = function () {
    console.log(p);
  };
  const cons = new Function("\tconsole.log(p);");

  decl();
  expr();
  cons();
}
myFunc();

// Logs:
// 9 (for 'decl' by function declaration (current scope))
// 9 (for 'expr' by function expression (current scope))
// 5 (for 'cons' by Function constructor (global scope))
```

Functions defined by function expressions and function declarations are parsed only once, while a function defined by the `Function` constructor parses the string passed to it each and every time the constructor is called. Although a function expression creates a closure every time, the function body is not reparsed, so function expressions are still faster than `new Function(...)`. Therefore the `Function` constructor should generally be avoided whenever possible.

A function declaration may be unintentionally turned into a function expression when it appears in an expression context.

```js
// A function declaration
function foo() {
  console.log("FOO!");
}

doSomething(
  // A function expression passed as an argument
  function foo() {
    console.log("FOO!");
  },
);
```

On the other hand, a function expression may also be turned into a function declaration. An expression statement cannot begin with the `function` or `async function` keywords, which is a common mistake when implementing IIFEs (Immediately Invoked Function Expressions).

```js
function () { // SyntaxError: Function statements require a function name
  console.log("FOO!");
}();

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

Instead, start the expression statement with something else, so that the `function` keyword unambiguously starts a function expression. Common options include grouping and using `void`.

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

void function () {
  console.log("FOO!");
}();
```

### Function parameters

Each function parameter is a simple identifier that you can access in the local scope.

```js
function myFunc(a, b, c) {
  // You can access the values of a, b, and c here
}
```

There are three special parameter syntaxes:

* *Default parameters* allow formal parameters to be initialized with default values if no value or `undefined` is passed.
* The *rest parameter* allows representing an indefinite number of arguments as an array.
* *Destructuring* allows unpacking elements from arrays, or properties from objects, into distinct variables.

```js
function myFunc({ a, b }, c = 1, ...rest) {
  // You can access the values of a, b, c, and rest here
}
```

There are some consequences if one of the above non-simple parameter syntaxes is used:

* You cannot apply `"use strict"` to the function body — this causes a syntax error.
* Even if the function is not in strict mode, the `arguments` object stops syncing with the named parameters, and `arguments.callee` throws an error when accessed.
### The arguments object

You can refer to a function's arguments within the function by using the `arguments` object.

`arguments`

An array-like object containing the arguments passed to the currently executing function.

`arguments.callee`

The currently executing function.

`arguments.length`

The number of arguments passed to the function.

### Getter and setter functions

You can define accessor properties on any standard built-in object or user-defined object that supports the addition of new properties. Within object literals and classes, you can use special syntaxes to define the getter and setter of an accessor property.

get

Binds an object property to a function that will be called when that property is looked up.

set

Binds an object property to a function to be called when there is an attempt to set that property.

Note that these syntaxes create an *object property*, not a *method*. The getter and setter functions themselves can only be accessed using reflective APIs such as `Object.getOwnPropertyDescriptor()`.

### Block-level functions

In strict mode, functions inside blocks are scoped to that block. Prior to ES2015, block-level functions were forbidden in strict mode.

```js
"use strict";

function f() {
  return 1;
}

{
  function f() {
    return 2;
  }
}

f() === 1; // true

// f() === 2 in non-strict mode
```

### Block-level functions in non-strict code

In a word: **Don't.**

In non-strict code, function declarations inside blocks behave strangely. For example:

```js
if (shouldDefineZero) {
  function zero() {
    // DANGER: compatibility risk
    console.log("This is zero.");
  }
}
```

The semantics of this in strict mode are well-specified — `zero` only ever exists within that scope of the `if` block. If `shouldDefineZero` is false, then `zero` should never be defined, since the block never executes. However, historically, this was left unspecified, so different browsers implemented it differently in non-strict mode. For more information, see the `function` declaration reference.

A safer way to define functions conditionally is to assign a function expression to a variable:

```js
// Using a var makes it available as a global variable,
// with closer behavior to a top-level function declaration
var zero;
if (shouldDefineZero) {
  zero = function () {
    console.log("This is zero.");
  };
}
```

Examples
--------

### Returning a formatted number

The following function returns a string containing the formatted representation of a number padded with leading zeros.

```js
// This function returns a string padded with leading zeros
function padZeros(num, totalLen) {
  let numStr = num.toString(); // Initialize return value as string
  const numZeros = totalLen - numStr.length; // Calculate no. of zeros
  for (let i = 1; i <= numZeros; i++) {
    numStr = `0${numStr}`;
  }
  return numStr;
}
```

The following statements call the `padZeros` function.

```js
let result;
result = padZeros(42, 4); // returns "0042"
result = padZeros(42, 2); // returns "42"
result = padZeros(5, 4); // returns "0005"
```

### Determining whether a function exists

You can determine whether a function exists by using the `typeof` operator. In the following example, a test is performed to determine if the `window` object has a property called `noFunc` that is a function. If so, it is used; otherwise, some other action is taken.

```js
if (typeof window.noFunc === "function") {
  // use noFunc()
} else {
  // do something else
}
```

Note that in the `if` test, a reference to `noFunc` is used — there are no parentheses `()` after the function name so the actual function is not called.

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
* Classes
* `function`
* `function` expression
* `Function`