Control flow and error handling - JavaScript

Control flow and error handling
===============================

* « Previous
* Next »

 JavaScript supports a compact set of statements, specifically
 control flow statements, that you can use to incorporate a great deal of interactivity
 in your application. This chapter provides an overview of these statements.

 The JavaScript reference
 contains exhaustive details about the statements in this chapter. The semicolon
 (`;`) character is used to separate statements in JavaScript code.

 Any JavaScript expression is also a statement.
 See Expressions and operators
 for complete information about expressions.

Block statement
---------------

 The most basic statement is a *block statement*, which is used to group
 statements. The block is delimited by a pair of curly braces:

```js
{
  statement1;
  statement2;
  // …
  statementN;
}
```

### Example

 Block statements are commonly used with control flow statements (`if`,
 `for`, `while`).

```js
while (x < 10) {
  x++;
}
```

Here, `{ x++; }` is the block statement.

**Note:** `var`-declared variables are not block-scoped, but are scoped to the containing function or script, and the effects of setting them persist beyond the block itself. For example:

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

This outputs `2` because the `var x` statement within the block is in the same scope as the `var x` statement before the block. (In C or Java, the equivalent code would have output `1`.)

This scoping effect can be mitigated by using `let` or `const`.

Conditional statements
----------------------

 A conditional statement is a set of commands that executes if a specified condition is
 true. JavaScript supports two conditional statements: `if...else` and
 `switch`.

### if...else statement

 Use the `if` statement to execute a statement if a logical condition is
 `true`. Use the optional `else` clause to execute a statement if
 the condition is `false`.

An `if` statement looks like this:

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

 Here, the `condition` can be any expression that evaluates to
 `true` or `false`. (See Boolean
 for an explanation of what evaluates to `true` and `false`.)

 If `condition` evaluates to `true`,
 `statement_1` is executed. Otherwise,
 `statement_2` is executed. `statement_1` and
 `statement_2` can be any statement, including further nested
 `if` statements.

 You can also compound the statements using `else if` to have multiple
 conditions tested in sequence, as follows:

```js
if (condition1) {
  statement1;
} else if (condition2) {
  statement2;
} else if (conditionN) {
  statementN;
} else {
  statementLast;
}
```

 In the case of multiple conditions, only the first logical condition which evaluates to
 `true` will be executed. To execute multiple statements, group them within a
 block statement (`{ /* … */ }`).

#### Best practice

 In general, it's good practice to always use block statements—*especially* when
 nesting `if` statements:

```js
if (condition) {
  // Statements for when condition is true
  // …
} else {
  // Statements for when condition is false
  // …
}
```

In general it's good practice to not have an `if...else` with an assignment like `x = y` as a condition:

```js
if (x = y) {
  // statements here
}
```

However, in the rare case you find yourself wanting to do something like that, the `while` documentation has a Using an assignment as a condition section with guidance on a general best-practice syntax you should know about and follow.

#### Falsy values

The following values evaluate to `false` (also known as Falsy values):

* `false`
* `undefined`
* `null`
* `0`
* `NaN`
* the empty string (`""`)

 All other values—including all objects—evaluate to `true` when passed to a
 conditional statement.

**Note:** Do not confuse the primitive boolean values
 `true` and `false` with the true and false values of the
 `Boolean` object!

For example:

```js
const b = new Boolean(false);
if (b) {
  // this condition evaluates to true
}
if (b == true) {
  // this condition evaluates to false
}
```

#### Example

 In the following example, the function `checkData` returns `true`
 if the number of characters in a `Text` object is three. Otherwise, it
 displays an alert and returns `false`.

```js
function checkData() {
  if (document.form1.threeChar.value.length === 3) {
    return true;
  } else {
    alert(
      `Enter exactly three characters. ${document.form1.threeChar.value} is not valid.`,
    );
    return false;
  }
}
```

### switch statement

 A `switch` statement allows a program to evaluate an expression and attempt
 to match the expression's value to a `case` label. If a match is found, the
 program executes the associated statement.

A `switch` statement looks like this:

```js
switch (expression) {
  case label1:
    statements1;
    break;
  case label2:
    statements2;
    break;
  // …
  default:
    statementsDefault;
}
```

JavaScript evaluates the above switch statement as follows:

* The program first looks for a `case` clause with a label matching the
 value of expression and then transfers control to that clause, executing the
 associated statements.
* If no matching label is found, the program looks for the optional
 `default` clause:
    + If a `default` clause is found, the program transfers control to that
     clause, executing the associated statements.
    + If no `default` clause is found, the program resumes execution at the
     statement following the end of `switch`.
    + (By convention, the `default` clause is written as the last clause,
     but it does not need to be so.)

#### break statements

 The optional `break` statement associated with each `case` clause
 ensures that the program breaks out of `switch` once the matched statement is
 executed, and then continues execution at the statement following `switch`.
 If `break` is omitted, the program continues execution inside the
 `switch` statement (and will execute statements under the next `case`, and so on).

##### Example

 In the following example, if `fruitType` evaluates to
 `'Bananas'`, the program matches the value with case `'Bananas'`
 and executes the associated statement. When `break` is encountered, the
 program exits the `switch` and continues execution from the statement
 following `switch`. If `break` were omitted, the statement for
 `case 'Cherries'` would also be executed.

```js
switch (fruitType) {
  case "Oranges":
    console.log("Oranges are $0.59 a pound.");
    break;
  case "Apples":
    console.log("Apples are $0.32 a pound.");
    break;
  case "Bananas":
    console.log("Bananas are $0.48 a pound.");
    break;
  case "Cherries":
    console.log("Cherries are $3.00 a pound.");
    break;
  case "Mangoes":
    console.log("Mangoes are $0.56 a pound.");
    break;
  case "Papayas":
    console.log("Mangoes and papayas are $2.79 a pound.");
    break;
  default:
    console.log(`Sorry, we are out of ${fruitType}.`);
}
console.log("Is there anything else you'd like?");
```

Exception handling statements
-----------------------------

 You can throw exceptions using the `throw` statement and handle them using
 the `try...catch` statements.

* `throw` statement
* `try...catch` statement
### Exception types

 Just about any object can be thrown in JavaScript. Nevertheless, not all thrown objects
 are created equal. While it is common to throw numbers or strings as errors, it is
 frequently more effective to use one of the exception types specifically created for
 this purpose:

* ECMAScript exceptions
* `DOMException`
### throw statement

 Use the `throw` statement to throw an exception. A `throw`
 statement specifies the value to be thrown:

```js
throw expression;
```

 You may throw any expression, not just expressions of a specific type. The following
 code throws several exceptions of varying types:

```js
throw "Error2"; // String type
throw 42; // Number type
throw true; // Boolean type
throw {
  toString() {
    return "I'm an object!";
  },
};
```

### `try...catch` statement

 The `try...catch` statement marks a block of statements to try, and
 specifies one or more responses should an exception be thrown. If an exception is
 thrown, the `try...catch` statement catches it.

 The `try...catch` statement consists of a `try` block, which
 contains one or more statements, and a `catch` block, containing statements
 that specify what to do if an exception is thrown in the `try` block.

 In other words, you want the `try` block to succeed—but if it does not, you
 want control to pass to the `catch` block. If any statement within the
 `try` block (or in a function called from within the `try` block)
 throws an exception, control *immediately* shifts to the `catch`
 block. If no exception is thrown in the `try` block, the `catch`
 block is skipped. The `finally` block executes after the `try` and
 `catch` blocks execute but before the statements following the
 `try...catch` statement.

 The following example uses a `try...catch` statement. The example calls a
 function that retrieves a month name from an array based on the value passed to the
 function. If the value does not correspond to a month number
 (`1` – `12`), an exception is thrown with the value
 `'InvalidMonthNo'` and the statements in the `catch` block set the
 `monthName` variable to `'unknown'`.

```js
function getMonthName(mo) {
  mo--; // Adjust month number for array index (so that 0 = Jan, 11 = Dec)
  const months = [
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
  ];
  if (months[mo]) {
    return months[mo];
  } else {
    throw new Error("InvalidMonthNo"); // throw keyword is used here
  }
}

try {
  // statements to try
  monthName = getMonthName(myMonth); // function could throw exception
} catch (e) {
  monthName = "unknown";
  logMyErrors(e); // pass exception object to error handler (i.e. your own function)
}
```

#### The catch block

 You can use a `catch` block to handle all exceptions that may be generated
 in the `try` block.

```js
catch (exception) {
  statements
}
```

 The `catch` block specifies an identifier (`exception`
 in the preceding syntax) that holds the value specified by the `throw`
 statement. You can use this identifier to get information about the exception that was
 thrown.

 JavaScript creates this identifier when the `catch` block is entered. The
 identifier lasts only for the duration of the `catch` block. Once the
 `catch` block finishes executing, the identifier no longer exists.

 For example, the following code throws an exception. When the exception occurs, control
 transfers to the `catch` block.

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

**Note:** When logging errors to the console inside
 a `catch` block, using `console.error()` rather than
 `console.log()` is advised for debugging. It formats the message as an
 error, and adds it to the list of error messages generated by the page.

#### The finally block

 The `finally` block contains statements to be executed *after* the
 `try` and `catch` blocks execute. Additionally, the
 `finally` block executes *before* the code that follows the
 `try…catch…finally` statement.

 It is also important to note that the `finally` block will execute
 *whether or not* an exception is thrown. If an exception is thrown, however, the
 statements in the `finally` block execute even if no `catch` block
 handles the exception that was thrown.

 You can use the `finally` block to make your script fail gracefully when an
 exception occurs. For example, you may need to release a resource that your script has
 tied up.

 The following example opens a file and then executes statements that use the file.
 (Server-side JavaScript allows you to access files.) If an exception is thrown while the
 file is open, the `finally` block closes the file before the script fails.
 Using `finally` here *ensures* that the file is never left open, even
 if an error occurs.

```js
openMyFile();
try {
  writeMyFile(theData); // This may throw an error
} catch (e) {
  handleError(e); // If an error occurred, handle it
} finally {
  closeMyFile(); // Always close the resource
}
```

 If the `finally` block returns a value, this value becomes the return value
 of the entire `try…catch…finally` production, regardless of any
 `return` statements in the `try` and `catch` blocks:

```js
function f() {
  try {
    console.log(0);
    throw "bogus";
  } catch (e) {
    console.log(1);
    // This return statement is suspended
    // until finally block has completed
    return true;
    console.log(2); // not reachable
  } finally {
    console.log(3);
    return false; // overwrites the previous "return"
    console.log(4); // not reachable
  }
  // "return false" is executed now
  console.log(5); // not reachable
}
console.log(f()); // 0, 1, 3, false
```

 Overwriting of return values by the `finally` block also applies to
 exceptions thrown or re-thrown inside of the `catch` block:

```js
function f() {
  try {
    throw "bogus";
  } catch (e) {
    console.log('caught inner "bogus"');
    // This throw statement is suspended until
    // finally block has completed
    throw e;
  } finally {
    return false; // overwrites the previous "throw"
  }
  // "return false" is executed now
}

try {
  console.log(f());
} catch (e) {
  // this is never reached!
  // while f() executes, the `finally` block returns false,
  // which overwrites the `throw` inside the above `catch`
  console.log('caught outer "bogus"');
}

// Logs:
// caught inner "bogus"
// false
```

#### Nesting try...catch statements

You can nest one or more `try...catch` statements.

 If an inner `try` block does *not* have a corresponding
 `catch` block:

1. it *must* contain a `finally` block, and
2. the enclosing `try...catch` statement's `catch` block is
 checked for a match.

 For more information, see nested try-blocks
 on the `try...catch`
 reference page.

### Utilizing Error objects

 Depending on the type of error, you may be able to use the `name` and
 `message` properties to get a more refined message.

 The `name` property provides the general class of `Error` (such
 as `DOMException` or `Error`), while `message`
 generally provides a more succinct message than one would get by converting the error
 object to a string.

 If you are throwing your own exceptions, in order to take advantage of these properties
 (such as if your `catch` block doesn't discriminate between your own
 exceptions and system ones), you can use the `Error` constructor.

For example:

```js
function doSomethingErrorProne() {
  if (ourCodeMakesAMistake()) {
    throw new Error("The message");
  } else {
    doSomethingToGetAJavaScriptError();
  }
}

try {
  doSomethingErrorProne();
} catch (e) {
  // Now, we actually use `console.error()`
  console.error(e.name); // 'Error'
  console.error(e.message); // 'The message', or a JavaScript error message
}
```

* « Previous
* Next »


Indexed collections - JavaScript

Indexed collections
===================

* « Previous
* Next »

This chapter introduces collections of data which are ordered by an index value. This includes arrays and array-like constructs such as `Array` objects and `TypedArray` objects.

An *array* is an ordered list of values that you refer to with a name and an index.

For example, consider an array called `emp`, which contains employees' names indexed by their numerical employee number. So `emp[0]` would be employee number zero, `emp[1]` employee number one, and so on.

JavaScript does not have an explicit array data type. However, you can use the predefined `Array` object and its methods to work with arrays in your applications. The `Array` object has methods for manipulating arrays in various ways, such as joining, reversing, and sorting them. It has a property for determining the array length and other properties for use with regular expressions.

We will be focusing on arrays in this article, but many of the same concepts apply to typed arrays as well, since arrays and typed arrays share many similar methods. For more information on typed arrays, see the typed array guide.

Creating an array
-----------------

The following statements create equivalent arrays:

```js
const arr1 = new Array(element0, element1, /\* …, \*/ elementN);
const arr2 = Array(element0, element1, /\* …, \*/ elementN);
const arr3 = [element0, element1, /\* …, \*/ elementN];
```

`element0, element1, …, elementN` is a list of values for the array's elements. When these values are specified, the array is initialized with them as the array's elements. The array's `length` property is set to the number of arguments.

The bracket syntax is called an "array literal" or "array initializer." It's shorter than other forms of array creation, and so is generally preferred. See Array literals for details.

To create an array with non-zero length, but without any items, either of the following can be used:

```js
// This...
const arr1 = new Array(arrayLength);

// ...results in the same array as this
const arr2 = Array(arrayLength);

// This has exactly the same effect
const arr3 = [];
arr3.length = arrayLength;
```

**Note:** In the above code, `arrayLength` must be a `Number`. Otherwise, an array with a single element (the provided value) will be created. Calling `arr.length` will return `arrayLength`, but the array doesn't contain any elements. A `for...in` loop will not find any property on the array.

In addition to a newly defined variable as shown above, arrays can also be assigned as a property of a new or an existing object:

```js
const obj = {};
// …
obj.prop = [element0, element1, /\* …, \*/ elementN];

// OR
const obj = { prop: [element0, element1, /\* …, \*/ elementN] };
```

If you wish to initialize an array with a single element, and the element happens to be a `Number`, you must use the bracket syntax. When a single `Number` value is passed to the `Array()` constructor or function, it is interpreted as an `arrayLength`, not as a single element.

This creates an array with only one element: the number 42.

```js
const arr = [42];
```

This creates an array with no elements and `arr.length` set to 42.

```js
const arr = Array(42);
```

This is equivalent to:

```js
const arr = [];
arr.length = 42;
```

Calling `Array(N)` results in a `RangeError`, if `N` is a non-whole number whose fractional portion is non-zero. The following example illustrates this behavior.

```js
const arr = Array(9.3); // RangeError: Invalid array length
```

If your code needs to create arrays with single elements of an arbitrary data type, it is safer to use array literals. Alternatively, create an empty array first before adding the single element to it.

You can also use the `Array.of` static method to create arrays with single element.

```js
const wisenArray = Array.of(9.3); // wisenArray contains only one element 9.3
```

Referring to array elements
---------------------------

Because elements are also properties, you can access them using property accessors. Suppose you define the following array:

```js
const myArray = ["Wind", "Rain", "Fire"];
```

You can refer to the first element of the array as `myArray[0]`, the second element of the array as `myArray[1]`, etc… The index of the elements begins with zero.

**Note:** You can also use property accessors to access other properties of the array, like with an object.

```js
const arr = ["one", "two", "three"];
arr[2]; // three
arr["length"]; // 3
```

Populating an array
-------------------

You can populate an array by assigning values to its elements. For example:

```js
const emp = [];
emp[0] = "Casey Jones";
emp[1] = "Phil Lesh";
emp[2] = "August West";
```

**Note:** If you supply a non-integer value to the array operator in the code above, a property will be created in the object representing the array, instead of an array element.

```js
const arr = [];
arr[3.4] = "Oranges";
console.log(arr.length); // 0
console.log(Object.hasOwn(arr, 3.4)); // true
```

You can also populate an array when you create it:

```js
const myArray = new Array("Hello", myVar, 3.14159);
// OR
const myArray = ["Mango", "Apple", "Orange"];
```

### Understanding length

At the implementation level, JavaScript's arrays actually store their elements as standard object properties, using the array index as the property name.

The `length` property is special. Its value is always a positive integer greater than the index of the last element if one exists. (In the example below, `'Dusty'` is indexed at `30`, so `cats.length` returns `30 + 1`).

Remember, JavaScript Array indexes are 0-based: they start at `0`, not `1`. This means that the `length` property will be one more than the highest index stored in the array:

```js
const cats = [];
cats[30] = ["Dusty"];
console.log(cats.length); // 31
```

You can also assign to the `length` property.

Writing a value that is shorter than the number of stored items truncates the array. Writing `0` empties it entirely:

```js
const cats = ["Dusty", "Misty", "Twiggy"];
console.log(cats.length); // 3

cats.length = 2;
console.log(cats); // [ 'Dusty', 'Misty' ] - Twiggy has been removed

cats.length = 0;
console.log(cats); // []; the cats array is empty

cats.length = 3;
console.log(cats); // [ <3 empty items> ]
```

### Iterating over arrays

A common operation is to iterate over the values of an array, processing each one in some way. The simplest way to do this is as follows:

```js
const colors = ["red", "green", "blue"];
for (let i = 0; i < colors.length; i++) {
  console.log(colors[i]);
}
```

If you know that none of the elements in your array evaluate to `false` in a boolean context—if your array consists only of DOM nodes, for example—you can use a more efficient idiom:

```js
const divs = document.getElementsByTagName("div");
for (let i = 0, div; (div = divs[i]); i++) {
  /\* Process div in some way \*/
}
```

This avoids the overhead of checking the length of the array, and ensures that the `div` variable is reassigned to the current item each time around the loop for added convenience.

The `forEach()` method provides another way of iterating over an array:

```js
const colors = ["red", "green", "blue"];
colors.forEach((color) => console.log(color));
// red
// green
// blue
```

The function passed to `forEach` is executed once for every item in the array, with the array item passed as the argument to the function. Unassigned values are not iterated in a `forEach` loop.

Note that the elements of an array that are omitted when the array is defined are not listed when iterating by `forEach`, but *are* listed when `undefined` has been manually assigned to the element:

```js
const sparseArray = ["first", "second", , "fourth"];

sparseArray.forEach((element) => {
  console.log(element);
});
// Logs:
// first
// second
// fourth

if (sparseArray[2] === undefined) {
  console.log("sparseArray[2] is undefined"); // true
}

const nonsparseArray = ["first", "second", undefined, "fourth"];

nonsparseArray.forEach((element) => {
  console.log(element);
});
// Logs:
// first
// second
// undefined
// fourth
```

Since JavaScript array elements are saved as standard object properties, it is not advisable to iterate through JavaScript arrays using `for...in` loops, because normal elements and all enumerable properties will be listed.

### Array methods

The `Array` object has the following methods:

The `concat()` method joins two or more arrays and returns a new array.

```js
let myArray = ["1", "2", "3"];
myArray = myArray.concat("a", "b", "c");
// myArray is now ["1", "2", "3", "a", "b", "c"]
```

The `join()` method joins all elements of an array into a string.

```js
const myArray = ["Wind", "Rain", "Fire"];
const list = myArray.join(" - "); // list is "Wind - Rain - Fire"
```

The `push()` method adds one or more elements to the end of an array and returns the resulting `length` of the array.

```js
const myArray = ["1", "2"];
myArray.push("3"); // myArray is now ["1", "2", "3"]
```

The `pop()` method removes the last element from an array and returns that element.

```js
const myArray = ["1", "2", "3"];
const last = myArray.pop();
// myArray is now ["1", "2"], last = "3"
```

The `shift()` method removes the first element from an array and returns that element.

```js
const myArray = ["1", "2", "3"];
const first = myArray.shift();
// myArray is now ["2", "3"], first is "1"
```

The `unshift()` method adds one or more elements to the front of an array and returns the new length of the array.

```js
const myArray = ["1", "2", "3"];
myArray.unshift("4", "5");
// myArray becomes ["4", "5", "1", "2", "3"]
```

The `slice()` method extracts a section of an array and returns a new array.

```js
let myArray = ["a", "b", "c", "d", "e"];
myArray = myArray.slice(1, 4); // [ "b", "c", "d"]
// starts at index 1 and extracts all elements
// until index 3
```

The `at()` method returns the element at the specified index in the array, or `undefined` if the index is out of range. It's notably used for negative indices that access elements from the end of the array.

```js
const myArray = ["a", "b", "c", "d", "e"];
myArray.at(-2); // "d", the second-last element of myArray
```

The `splice()` method removes elements from an array and (optionally) replaces them. It returns the items which were removed from the array.

```js
const myArray = ["1", "2", "3", "4", "5"];
myArray.splice(1, 3, "a", "b", "c", "d");
// myArray is now ["1", "a", "b", "c", "d", "5"]
// This code started at index one (or where the "2" was),
// removed 3 elements there, and then inserted all consecutive
// elements in its place.
```

The `reverse()` method transposes the elements of an array, in place: the first array element becomes the last and the last becomes the first. It returns a reference to the array.

```js
const myArray = ["1", "2", "3"];
myArray.reverse();
// transposes the array so that myArray = ["3", "2", "1"]
```

The `flat()` method returns a new array with all sub-array elements concatenated into it recursively up to the specified depth.

```js
let myArray = [1, 2, [3, 4]];
myArray = myArray.flat();
// myArray is now [1, 2, 3, 4], since the [3, 4] subarray is flattened
```

The `sort()` method sorts the elements of an array in place, and returns a reference to the array.

```js
const myArray = ["Wind", "Rain", "Fire"];
myArray.sort();
// sorts the array so that myArray = ["Fire", "Rain", "Wind"]
```

`sort()` can also take a callback function to determine how array elements are compared. The callback function is called with two arguments, which are two values from the array. The function compares these two values and returns a positive number, negative number, or zero, indicating the order of the two values. For instance, the following will sort the array by the last letter of a string:

```js
const sortFn = (a, b) => {
  if (a[a.length - 1] < b[b.length - 1]) {
    return -1; // Negative number => a < b, a comes before b
  } else if (a[a.length - 1] > b[b.length - 1]) {
    return 1; // Positive number => a > b, a comes after b
  }
  return 0; // Zero => a = b, a and b keep their original order
};
myArray.sort(sortFn);
// sorts the array so that myArray = ["Wind","Fire","Rain"]
```

* if `a` is less than `b` by the sorting system, return `-1` (or any negative number)
* if `a` is greater than `b` by the sorting system, return `1` (or any positive number)
* if `a` and `b` are considered equivalent, return `0`.

The `indexOf()` method searches the array for `searchElement` and returns the index of the first match.

```js
const a = ["a", "b", "a", "b", "a"];
console.log(a.indexOf("b")); // 1

// Now try again, starting from after the last match
console.log(a.indexOf("b", 2)); // 3
console.log(a.indexOf("z")); // -1, because 'z' was not found
```

The `lastIndexOf()` method works like `indexOf`, but starts at the end and searches backwards.

```js
const a = ["a", "b", "c", "d", "a", "b"];
console.log(a.lastIndexOf("b")); // 5

// Now try again, starting from before the last match
console.log(a.lastIndexOf("b", 4)); // 1
console.log(a.lastIndexOf("z")); // -1
```

The `forEach()` method executes `callback` on every array item and returns `undefined`.

```js
const a = ["a", "b", "c"];
a.forEach((element) => {
  console.log(element);
});
// Logs:
// a
// b
// c
```

The `forEach` method (and others below) that take a callback are known as *iterative methods*, because they iterate over the entire array in some fashion. Each one takes an optional second argument called `thisArg`. If provided, `thisArg` becomes the value of the `this` keyword inside the body of the callback function. If not provided, as with other cases where a function is invoked outside of an explicit object context, `this` will refer to the global object (`window`, `globalThis`, etc.) when the function is not strict, or `undefined` when the function is strict.

**Note:** The `sort()` method introduced above is not an iterative method, because its callback function is only used for comparison and may not be called in any particular order based on element order. `sort()` does not accept the `thisArg` parameter either.

The `map()` method returns a new array of the return value from executing `callback` on every array item.

```js
const a1 = ["a", "b", "c"];
const a2 = a1.map((item) => item.toUpperCase());
console.log(a2); // ['A', 'B', 'C']
```

The `flatMap()` method runs `map()` followed by a `flat()` of depth 1.

```js
const a1 = ["a", "b", "c"];
const a2 = a1.flatMap((item) => [item.toUpperCase(), item.toLowerCase()]);
console.log(a2); // ['A', 'a', 'B', 'b', 'C', 'c']
```

The `filter()` method returns a new array containing the items for which `callback` returned `true`.

```js
const a1 = ["a", 10, "b", 20, "c", 30];
const a2 = a1.filter((item) => typeof item === "number");
console.log(a2); // [10, 20, 30]
```

The `find()` method returns the first item for which `callback` returned `true`.

```js
const a1 = ["a", 10, "b", 20, "c", 30];
const i = a1.find((item) => typeof item === "number");
console.log(i); // 10
```

The `findLast()` method returns the last item for which `callback` returned `true`.

```js
const a1 = ["a", 10, "b", 20, "c", 30];
const i = a1.findLast((item) => typeof item === "number");
console.log(i); // 30
```

The `findIndex()` method returns the index of the first item for which `callback` returned `true`.

```js
const a1 = ["a", 10, "b", 20, "c", 30];
const i = a1.findIndex((item) => typeof item === "number");
console.log(i); // 1
```

The `findLastIndex()` method returns the index of the last item for which `callback` returned `true`.

```js
const a1 = ["a", 10, "b", 20, "c", 30];
const i = a1.findLastIndex((item) => typeof item === "number");
console.log(i); // 5
```

The `every()` method returns `true` if `callback` returns `true` for every item in the array.

```js
function isNumber(value) {
  return typeof value === "number";
}
const a1 = [1, 2, 3];
console.log(a1.every(isNumber)); // true
const a2 = [1, "2", 3];
console.log(a2.every(isNumber)); // false
```

The `some()` method returns `true` if `callback` returns `true` for at least one item in the array.

```js
function isNumber(value) {
  return typeof value === "number";
}
const a1 = [1, 2, 3];
console.log(a1.some(isNumber)); // true
const a2 = [1, "2", 3];
console.log(a2.some(isNumber)); // true
const a3 = ["1", "2", "3"];
console.log(a3.some(isNumber)); // false
```

The `reduce()` method applies `callback(accumulator, currentValue, currentIndex, array)` for each value in the array for the purpose of reducing the list of items down to a single value. The `reduce` function returns the final value returned by `callback` function.

If `initialValue` is specified, then `callback` is called with `initialValue` as the first parameter value and the value of the first item in the array as the second parameter value.

If `initialValue` is *not* specified, then `callback`'s first two parameter values will be the first and second elements of the array. On *every* subsequent call, the first parameter's value will be whatever `callback` returned on the previous call, and the second parameter's value will be the next value in the array.

If `callback` needs access to the index of the item being processed, or access to the entire array, they are available as optional parameters.

```js
const a = [10, 20, 30];
const total = a.reduce(
  (accumulator, currentValue) => accumulator + currentValue,
  0,
);
console.log(total); // 60
```

The `reduceRight()` method works like `reduce()`, but starts with the last element.

`reduce` and `reduceRight` are the least obvious of the iterative array methods. They should be used for algorithms that combine two values recursively in order to reduce a sequence down to a single value.

Array transformations
---------------------

You can transform back and forth between arrays and other data structures.

### Grouping the elements of an array

The `Object.groupBy()` method can be used to group the elements of an array, using a test function that returns a string indicating the group of the current element.

Here we have a simple inventory array that contains "food" objects that have a `name` and a `type`.

```js
const inventory = [
  { name: "asparagus", type: "vegetables" },
  { name: "bananas", type: "fruit" },
  { name: "goat", type: "meat" },
  { name: "cherries", type: "fruit" },
  { name: "fish", type: "meat" },
];
```

To use `Object.groupBy()`, you supply a callback function that is called with the current element, and optionally the current index and array, and returns a string indicating the group of the element.

The code below uses an arrow function to return the `type` of each array element (this uses object destructuring syntax for function arguments to unpack the `type` element from the passed object). The result is an object that has properties named after the unique strings returned by the callback. Each property is assigned an array containing the elements in the group.

```js
const result = Object.groupBy(inventory, ({ type }) => type);
console.log(result.vegetables);
// [{ name: "asparagus", type: "vegetables" }]
```

Note that the returned object references the *same* elements as the original array (not deep copies). Changing the internal structure of these elements will be reflected in both the original array and the returned object.

If you can't use a string as the key, for example, if the information to group is associated with an object that might change, then you can instead use `Map.groupBy()`. This is very similar to `Object.groupBy()` except that it groups the elements of the array into a `Map` that can use an arbitrary value (object or primitive) as a key.

Sparse arrays
-------------

Arrays can contain "empty slots", which are not the same as slots filled with the value `undefined`. Empty slots can be created in one of the following ways:

```js
// Array constructor:
const a = Array(5); // [ <5 empty items> ]

// Consecutive commas in array literal:
const b = [1, 2, , , 5]; // [ 1, 2, <2 empty items>, 5 ]

// Directly setting a slot with index greater than array.length:
const c = [1, 2];
c[4] = 5; // [ 1, 2, <2 empty items>, 5 ]

// Elongating an array by directly setting .length:
const d = [1, 2];
d.length = 5; // [ 1, 2, <3 empty items> ]

// Deleting an element:
const e = [1, 2, 3, 4, 5];
delete e[2]; // [ 1, 2, <1 empty item>, 4, 5 ]
```

In some operations, empty slots behave as if they are filled with `undefined`.

```js
const arr = [1, 2, , , 5]; // Create a sparse array

// Indexed access
console.log(arr[2]); // undefined

// For...of
for (const i of arr) {
  console.log(i);
}
// Logs: 1 2 undefined undefined 5

// Spreading
const another = [...arr]; // "another" is [ 1, 2, undefined, undefined, 5 ]
```

But in others (most notably array iteration methods), empty slots are skipped.

```js
const mapped = arr.map((i) => i + 1); // [ 2, 3, <2 empty items>, 6 ]
arr.forEach((i) => console.log(i)); // 1 2 5
const filtered = arr.filter(() => true); // [ 1, 2, 5 ]
const hasFalsy = arr.some((k) => !k); // false

// Property enumeration
const keys = Object.keys(arr); // [ '0', '1', '4' ]
for (const key in arr) {
  console.log(key);
}
// Logs: '0' '1' '4'
// Spreading into an object uses property enumeration, not the array's iterator
const objectSpread = { ...arr }; // { '0': 1, '1': 2, '4': 5 }
```

For a complete list of how array methods behave with sparse arrays, see the `Array` reference page.

Multi-dimensional arrays
------------------------

Arrays can be nested, meaning that an array can contain another array as an element. Using this characteristic of JavaScript arrays, multi-dimensional arrays can be created.

The following code creates a two-dimensional array.

```js
const a = new Array(4);
for (let i = 0; i < 4; i++) {
  a[i] = new Array(4);
  for (let j = 0; j < 4; j++) {
    a[i][j] = `[${i}, ${j}]`;
  }
}
```

This example creates an array with the following rows:
```

Row 0: [0, 0] [0, 1] [0, 2] [0, 3]
Row 1: [1, 0] [1, 1] [1, 2] [1, 3]
Row 2: [2, 0] [2, 1] [2, 2] [2, 3]
Row 3: [3, 0] [3, 1] [3, 2] [3, 3]
```

Using arrays to store other properties
--------------------------------------

Arrays can also be used like objects, to store related information.

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

For example, when an array is the result of a match between a regular expression and a string, the array returns properties and elements that provide information about the match. An array is the return value of `RegExp.prototype.exec()`, `String.prototype.match()`, and `String.prototype.split()`. For information on using arrays with regular expressions, see Regular Expressions.

Working with array-like objects
-------------------------------

Some JavaScript objects, such as the `NodeList` returned by `document.getElementsByTagName()` or the `arguments` object made available within the body of a function, look and behave like arrays on the surface but do not share all of their methods. The `arguments` object provides a `length` attribute but does not implement array methods like `forEach()`.

Array methods cannot be called directly on array-like objects.

```js
function printArguments() {
  arguments.forEach((item) => {
    console.log(item);
  }); // TypeError: arguments.forEach is not a function
}
```

But you can call them indirectly using `Function.prototype.call()`.

```js
function printArguments() {
  Array.prototype.forEach.call(arguments, (item) => {
    console.log(item);
  });
}
```

Array prototype methods can be used on strings as well, since they provide sequential access to their characters in a similar way to arrays:

```js
Array.prototype.forEach.call("a string", (chr) => {
  console.log(chr);
});
```

* « Previous
* Next »


Loops and iteration - JavaScript

Loops and iteration
===================

* « Previous
* Next »

 Loops offer a quick and easy way to do something repeatedly. This
 chapter of the JavaScript Guide
 introduces the different iteration statements available to JavaScript.

 You can think of a loop as a computerized version of the game where you tell someone to
 take *X* steps in one direction, then *Y* steps in another. For example,
 the idea "Go five steps to the east" could be expressed this way as a loop:

```js
for (let step = 0; step < 5; step++) {
  // Runs 5 times, with values of step 0 through 4.
  console.log("Walking east one step");
}
```

 There are many different kinds of loops, but they all essentially do the same thing:
 they repeat an action some number of times. (Note that it's possible that number could
 be zero!)

 The various loop mechanisms offer different ways to determine the start and end points
 of the loop. There are various situations that are more easily served by one type of
 loop over the others.

The statements for loops provided in JavaScript are:

* for statement
* do...while statement
* while statement
* labeled statement
* break statement
* continue statement
* for...in statement
* for...of statement
for statement
-------------

A `for` loop repeats until a specified condition evaluates to false. The JavaScript `for` loop is similar to the Java and C `for` loop.

A `for` statement looks as follows:

```js
for (initialization; condition; afterthought)
  statement
```

When a `for` loop executes, the following occurs:

1. The initializing expression `initialization`, if any, is executed. This expression usually initializes one or more loop counters, but the syntax allows an expression of any degree of complexity. This expression can also declare variables.
2. The `condition` expression is evaluated. If the value of `condition` is true, the loop statements execute. Otherwise, the `for` loop terminates. (If the `condition` expression is omitted entirely, the condition is assumed to be true.)
3. The `statement` executes. To execute multiple statements, use a block statement (`{ }`) to group those statements.
4. If present, the update expression `afterthought` is executed.
5. Control returns to Step 2.
### Example

 In the example below, the function contains a `for` statement that counts
 the number of selected options in a scrolling list (a `<select>`
 element that allows multiple selections).

#### HTML

```html
<form name="selectForm">
  <label for="musicTypes"
 >Choose some music types, then click the button below:</label
 >
  <select id="musicTypes" name="musicTypes" multiple>
    <option selected>R&B</option>
    <option>Jazz</option>
    <option>Blues</option>
    <option>New Age</option>
    <option>Classical</option>
    <option>Opera</option>
  </select>
  <button id="btn" type="button">How many are selected?</button>
</form>
```

#### JavaScript

Here, the `for` statement declares the variable `i` and initializes it to `0`. It checks that `i` is less than the number of options in the `<select>` element, performs the succeeding `if` statement, and increments `i` by 1 after each pass through the loop.

```js
function countSelected(selectObject) {
  let numberSelected = 0;
  for (let i = 0; i < selectObject.options.length; i++) {
    if (selectObject.options[i].selected) {
      numberSelected++;
    }
  }
  return numberSelected;
}

const btn = document.getElementById("btn");

btn.addEventListener("click", () => {
  const musicTypes = document.selectForm.musicTypes;
  console.log(`You have selected ${countSelected(musicTypes)} option(s).`);
});
```

do...while statement
--------------------

 The `do...while` statement repeats until a
 specified condition evaluates to false.

A `do...while` statement looks as follows:

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

`statement` is always executed once before the condition is
 checked. (To execute multiple statements, use a block statement (`{ }`)
 to group those statements.)

 If `condition` is `true`, the statement executes again. At the
 end of every execution, the condition is checked. When the condition is
 `false`, execution stops, and control passes to the statement following
 `do...while`.

### Example

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

```js
let i = 0;
do {
  i += 1;
  console.log(i);
} while (i < 5);
```

while statement
---------------

 A `while` statement executes its statements as long as a
 specified condition evaluates to `true`. A `while` statement looks
 as follows:

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

 If the `condition` becomes `false`,
 `statement` within the loop stops executing and control passes to the
 statement following the loop.

 The condition test occurs *before* `statement` in the loop is
 executed. If the condition returns `true`, `statement` is executed
 and the `condition` is tested again. If the condition returns
 `false`, execution stops, and control is passed to the statement following
 `while`.

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

### Example 1

 The following `while` loop iterates as long as `n` is
 less than `3`:

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

 With each iteration, the loop increments `n` and adds that value to
 `x`. Therefore, `x` and `n` take on the following
 values:

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

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

### Example 2

 Avoid infinite loops. Make sure the condition in a loop eventually becomes
 `false`—otherwise, the loop will never terminate! The statements in the
 following `while` loop execute forever because the condition never becomes
 `false`:

```js
// Infinite loops are bad!
while (true) {
  console.log("Hello, world!");
}
```

labeled statement
-----------------

 A `label` provides a statement with an identifier that
 lets you refer to it elsewhere in your program. For example, you can use a label to
 identify a loop, and then use the `break` or `continue` statements
 to indicate whether a program should interrupt the loop or continue its execution.

The syntax of the labeled statement looks like the following:

```js
label:
  statement
```

 The value of `label` may be any JavaScript identifier that is not a
 reserved word. The `statement` that you identify with a label may be
 any statement. For examples of using labeled statements, see the examples of `break` and `continue` below.

break statement
---------------

 Use the `break` statement to terminate a loop,
 `switch`, or in conjunction with a labeled statement.

* When you use `break` without a label, it terminates the innermost
 enclosing `while`, `do-while`, `for`, or
 `switch` immediately and transfers control to the following statement.
* When you use `break` with a label, it terminates the specified labeled
 statement.

The syntax of the `break` statement looks like this:

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

1. The first form of the syntax terminates the innermost enclosing loop or `switch`.
2. The second form of the syntax terminates the specified enclosing labeled statement.
### Example 1

 The following example iterates through the elements in an array until it finds the
 index of an element whose value is `theValue`:

```js
for (let i = 0; i < a.length; i++) {
  if (a[i] === theValue) {
    break;
  }
}
```

### Example 2: Breaking to a label

```js
let x = 0;
let z = 0;
labelCancelLoops: while (true) {
  console.log("Outer loops:", x);
  x += 1;
  z = 1;
  while (true) {
    console.log("Inner loops:", z);
    z += 1;
    if (z === 10 && x === 10) {
      break labelCancelLoops;
    } else if (z === 10) {
      break;
    }
  }
}
```

continue statement
------------------

 The `continue` statement can be used to restart a
 `while`, `do-while`, `for`, or `label`
 statement.

* When you use `continue` without a label, it terminates the current
 iteration of the innermost enclosing `while`, `do-while`, or
 `for` statement and continues execution of the loop with the next
 iteration. In contrast to the `break` statement, `continue` does
 not terminate the execution of the loop entirely. In a `while` loop, it
 jumps back to the condition. In a `for` loop, it jumps to the
 `increment-expression`.
* When you use `continue` with a label, it applies to the looping statement
 identified with that label.

The syntax of the `continue` statement looks like the following:

```js
continue;
continue label;
```

### Example 1

 The following example shows a `while` loop with a `continue`
 statement that executes when the value of `i` is `3`. Thus,
 `n` takes on the values `1`, `3`, `7`, and
 `12`.

```js
let i = 0;
let n = 0;
while (i < 5) {
  i++;
  if (i === 3) {
    continue;
  }
  n += i;
  console.log(n);
}
// Logs:
// 1 3 7 12
```

If you comment out the `continue;`, the loop would run till the end and you would see `1,3,6,10,15`.

### Example 2

 A statement labeled `checkiandj` contains a statement labeled
 `checkj`. If `continue` is encountered, the program
 terminates the current iteration of `checkj` and begins the next
 iteration. Each time `continue` is encountered, `checkj`
 reiterates until its condition returns `false`. When `false` is
 returned, the remainder of the `checkiandj` statement is completed,
 and `checkiandj` reiterates until its condition returns
 `false`. When `false` is returned, the program continues at the
 statement following `checkiandj`.

 If `continue` had a label of `checkiandj`, the program
 would continue at the top of the `checkiandj` statement.

```js
let i = 0;
let j = 10;
checkiandj: while (i < 4) {
  console.log(i);
  i += 1;
  checkj: while (j > 4) {
    console.log(j);
    j -= 1;
    if (j % 2 === 0) {
      continue checkj;
    }
    console.log(j, "is odd.");
  }
  console.log("i =", i);
  console.log("j =", j);
}
```

for...in statement
------------------

 The `for...in` statement iterates a specified
 variable over all the enumerable properties of an object. For each distinct property,
 JavaScript executes the specified statements. A `for...in` statement looks as
 follows:

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

### Example

 The following function takes as its argument an object and the object's name. It then
 iterates over all the object's properties and returns a string that lists the property
 names and their values.

```js
function dumpProps(obj, objName) {
  let result = "";
  for (const i in obj) {
    result += `${objName}.${i} = ${obj[i]}<br>`;
  }
  result += "<hr>";
  return result;
}
```

For an object `car` with properties `make` and `model`, `result` would be:
```

car.make = Ford
car.model = Mustang
```

### Arrays

 Although it may be tempting to use this as a way to iterate over `Array`
 elements, the `for...in` statement will return the name of your user-defined
 properties in addition to the numeric indexes.

 Therefore, it is better to use a traditional `for` loop
 with a numeric index when iterating over arrays, because the `for...in`
 statement iterates over user-defined properties in addition to the array elements, if
 you modify the Array object (such as adding custom properties or methods).

for...of statement
------------------

 The `for...of` statement creates a loop Iterating
 over iterable objects (including
 `Array`, `Map`, `Set`,
 `arguments` object and so on), invoking a custom
 iteration hook with statements to be executed for the value of each distinct property.

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

 The following example shows the difference between a `for...of` loop and a
 `for...in` loop. While `for...in` iterates
 over property names, `for...of` iterates over property values:

```js
const arr = [3, 5, 7];
arr.foo = "hello";

for (const i in arr) {
  console.log(i);
}
// "0" "1" "2" "foo"

for (const i of arr) {
  console.log(i);
}
// Logs: 3 5 7
```

The `for...of` and `for...in` statements can also be used with destructuring. For example, you can simultaneously loop over the keys and values of an object using `Object.entries()`.

```js
const obj = { foo: 1, bar: 2 };

for (const [key, val] of Object.entries(obj)) {
  console.log(key, val);
}
// "foo" 1
// "bar" 2
```

* « Previous
* Next »


Meta programming - JavaScript

Meta programming
================

* « Previous
* Next »

The `Proxy` and `Reflect` objects allow you to intercept and define custom behavior for fundamental language operations (e.g. property lookup, assignment, enumeration, function invocation, etc.). With the help of these two objects you are able to program at the meta level of JavaScript.

Proxies
-------

`Proxy` objects allow you to intercept certain operations and to implement custom behaviors.

For example, getting a property on an object:

```js
const handler = {
  get(target, name) {
    return name in target ? target[name] : 42;
  },
};

const p = new Proxy({}, handler);
p.a = 1;
console.log(p.a, p.b); // 1, 42
```

The `Proxy` object defines a `target` (an empty object here) and a `handler` object, in which a `get` *trap* is implemented. Here, an object that is proxied will not return `undefined` when getting undefined properties, but will instead return the number `42`.

Additional examples are available on the `Proxy` reference page.

### Terminology

The following terms are used when talking about the functionality of proxies.

handler

Placeholder object which contains traps.

traps

The methods that provide property access. (This is analogous to the concept of *traps* in operating systems.)

target

Object which the proxy virtualizes. It is often used as storage backend for the proxy. Invariants (semantics that remain unchanged) regarding object non-extensibility or non-configurable properties are verified against the target.

invariants

Semantics that remain unchanged when implementing custom operations are called *invariants*. If you violate the invariants of a handler, a `TypeError` will be thrown.

Handlers and traps
------------------

The following table summarizes the available traps available to `Proxy` objects. See the reference pages for detailed explanations and examples.

| Handler / trap | Interceptions | Invariants |
| --- | --- | --- |
| `handler.getPrototypeOf()` | `Object.getPrototypeOf()``Reflect.getPrototypeOf()``__proto__``Object.prototype.isPrototypeOf()``instanceof` | * `getPrototypeOf` method must return an object or
 `null`.
* If `target` is not extensible,
 `Object.getPrototypeOf(proxy)` method must
 return the same value as
 `Object.getPrototypeOf(target)`.
 |
| `handler.setPrototypeOf()` | `Object.setPrototypeOf()``Reflect.setPrototypeOf()` |
 If `target` is not extensible, the
 `prototype` parameter must be the same value as
 `Object.getPrototypeOf(target)`.
  |
| `handler.isExtensible()` | `Object.isExtensible()``Reflect.isExtensible()` | `Object.isExtensible(proxy)` must return the same
 value as `Object.isExtensible(target)`.
  |
| `handler.preventExtensions()` | `Object.preventExtensions()``Reflect.preventExtensions()` | `Object.preventExtensions(proxy)` only returns
 `true` if
 `Object.isExtensible(proxy)` is
 `false`.
  |
| `handler.getOwnPropertyDescriptor()` | `Object.getOwnPropertyDescriptor()``Reflect.getOwnPropertyDescriptor()` | * `getOwnPropertyDescriptor` must return an object or
 `undefined`.
* A property cannot be reported as non-existent if it exists as a
 non-configurable own property of `target`.
* A property cannot be reported as non-existent if it exists as an own
 property of `target` and
 `target` is not extensible.
* A property cannot be reported as existent if it does not exists as
 an own property of `target` and
 `target` is not extensible.
* A property cannot be reported as non-configurable if it does not
 exist as an own property of `target` or if it
 exists as a configurable own property of
 `target`.
* The result of
 `Object.getOwnPropertyDescriptor(target)` can
 be applied to `target` using
 `Object.defineProperty` and will not throw an exception.
 |
| `handler.defineProperty()` | `Object.defineProperty()``Reflect.defineProperty()` | * A property cannot be added if `target` is not extensible.
* A property cannot be added as (or modified to be)
 non-configurable if it does not exist as a non-configurable own
 property of `target`.
* A property may not be non-configurable if a corresponding
 configurable property of `target` exists.
* If a property has a corresponding target object property, then
 `Object.defineProperty(target, prop,
descriptor)`
 will not throw an exception.
* In strict mode, a `false` value returned from the
 `defineProperty` handler will throw a
 `TypeError` exception.
 |
| `handler.has()` |
Property query
`foo in proxy`
Inherited property query
`foo in Object.create(proxy)``Reflect.has()`
 | * A property cannot be reported as non-existent, if it exists as a
 non-configurable own property of `target`.
* A property cannot be reported as non-existent if it exists as an own
 property of `target` and
 `target` is not extensible.
 |
| `handler.get()` |
Property access
`proxy[foo]``proxy.bar`
Inherited property access
`Object.create(proxy)[foo]``Reflect.get()`
 | * The value reported for a property must be the same as the value of
 the corresponding `target` property if
 `target`'s property is a non-writable, non-configurable data property.
* The value reported for a property must be `undefined` if
 the corresponding `target` property is
 non-configurable accessor property that has undefined as its
 `[[Get]]` attribute.
 |
| `handler.set()` |
Property assignment
`proxy[foo] = bar``proxy.foo = bar`
Inherited property assignment
`Object.create(proxy)[foo] = bar``Reflect.set()`
 | * Cannot change the value of a property to be different from the value
 of the corresponding `target` property if the
 corresponding `target` property is a
 non-writable, non-configurable data property.
* Cannot set the value of a property if the corresponding
 `target` property is a non-configurable
 accessor property that has `undefined` as its
 `[[Set]]` attribute.
* In strict mode, a `false` return value from the
 `set` handler will throw a
 `TypeError` exception.
 |
| `handler.deleteProperty()` |
Property deletion
`delete proxy[foo]``delete proxy.foo``Reflect.deleteProperty()`
 |
 A property cannot be deleted if it exists as a non-configurable own
 property of `target`.
  |
| `handler.ownKeys()` | `Object.getOwnPropertyNames()``Object.getOwnPropertySymbols()``Object.keys()``Reflect.ownKeys()` | * The result of `ownKeys` is a List.
* The Type of each result List element is either
 `String` or `Symbol`.
* The result List must contain the keys of all non-configurable own
 properties of `target`.
* If the `target` object is not extensible, then
 the result List must contain all the keys of the own properties of
 `target` and no other values.
 |
| `handler.apply()` | `proxy(..args)``Function.prototype.apply()` and
 `Function.prototype.call()``Reflect.apply()` |
 There are no invariants for the
 `handler.apply` method.
  |
| `handler.construct()` | `new proxy(...args)``Reflect.construct()` | The result must be an `Object`. |

Revocable `Proxy`
-----------------

The `Proxy.revocable()` method is used to create a revocable `Proxy` object. This means that the proxy can be revoked via the function `revoke` and switches the proxy off.

Afterwards, any operation on the proxy leads to a `TypeError`.

```js
const revocable = Proxy.revocable(
  {},
  {
    get(target, name) {
      return `[[${name}]]`;
    },
  },
);
const proxy = revocable.proxy;
console.log(proxy.foo); // "[[foo]]"

revocable.revoke();

console.log(proxy.foo); // TypeError: Cannot perform 'get' on a proxy that has been revoked
proxy.foo = 1; // TypeError: Cannot perform 'set' on a proxy that has been revoked
delete proxy.foo; // TypeError: Cannot perform 'deleteProperty' on a proxy that has been revoked
console.log(typeof proxy); // "object", typeof doesn't trigger any trap
```

Reflection
----------

`Reflect` is a built-in object that provides methods for interceptable JavaScript operations. The methods are the same as those of the proxy handler's.

`Reflect` is not a function object.

`Reflect` helps with forwarding default operations from the handler to the `target`.

With `Reflect.has()` for example, you get the `in` operator as a function:

```js
Reflect.has(Object, "assign"); // true
```

### A better apply() function

Before `Reflect`, you typically use the `Function.prototype.apply()` method to call a function with a given `this` value and `arguments` provided as an array (or an array-like object).

```js
Function.prototype.apply.call(Math.floor, undefined, [1.75]);
```

With `Reflect.apply` this becomes less verbose and easier to understand:

```js
Reflect.apply(Math.floor, undefined, [1.75]);
// 1

Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
// "hello"

Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index;
// 4

Reflect.apply("".charAt, "ponies", [3]);
// "i"
```

### Checking if property definition has been successful

With `Object.defineProperty`, which returns an object if successful, or throws a `TypeError` otherwise, you would use a `try...catch` block to catch any error that occurred while defining a property. Because `Reflect.defineProperty()` returns a Boolean success status, you can just use an `if...else` block here:

```js
if (Reflect.defineProperty(target, property, attributes)) {
  // success
} else {
  // failure
}
```

* « Previous
* Next »


Introduction - JavaScript

Introduction
============

* « Previous
* Next »

This chapter introduces JavaScript and discusses some of its fundamental concepts.

What you should already know
----------------------------

This guide assumes you have the following basic background:

* A general understanding of the Internet and the World Wide Web (WWW).
* Good working knowledge of HyperText Markup Language (HTML).
* Some programming experience. If you are new to programming, try one of the tutorials linked on the main page about JavaScript.
Where to find JavaScript information
------------------------------------

The JavaScript documentation on MDN includes the following:

* Learn Web Development provides information for beginners and introduces basic concepts of programming and the Internet.
* JavaScript Guide (this guide) provides an overview about the JavaScript language and its objects.
* JavaScript Reference provides detailed reference material for JavaScript.

If you are new to JavaScript, start with the articles in the learning area and the JavaScript Guide. Once you have a firm grasp of the fundamentals, you can use the JavaScript Reference to get more details on individual objects and statements.

What is JavaScript?
-------------------

JavaScript is a cross-platform, object-oriented scripting language used to make webpages interactive (e.g., having complex animations, clickable buttons, popup menus, etc.). There are also more advanced server side versions of JavaScript such as Node.js, which allow you to add more functionality to a website than downloading files (such as realtime collaboration between multiple computers). Inside a host environment (for example, a web browser), JavaScript can be connected to the objects of its environment to provide programmatic control over them.

JavaScript contains a standard library of objects, such as `Array`, `Date`, and `Math`, and a core set of language elements such as operators, control structures, and statements. Core JavaScript can be extended for a variety of purposes by supplementing it with additional objects; for example:

* *Client-side JavaScript* extends the core language by supplying objects to control a browser and its *Document Object Model* (DOM). For example, client-side extensions allow an application to place elements on an HTML form and respond to user events such as mouse clicks, form input, and page navigation.
* *Server-side JavaScript* extends the core language by supplying objects relevant to running JavaScript on a server. For example, server-side extensions allow an application to communicate with a database, provide continuity of information from one invocation to another of the application, or perform file manipulations on a server.

This means that in the browser, JavaScript can change the way the webpage (DOM) looks. And, likewise, Node.js JavaScript on the server can respond to custom requests sent by code executed in the browser.

JavaScript and Java
-------------------

JavaScript and Java are similar in some ways but fundamentally different in some others. The JavaScript language resembles Java but does not have Java's static typing and strong type checking. JavaScript follows most Java expression syntax, naming conventions and basic control-flow constructs which was the reason why it was renamed from LiveScript to JavaScript.

In contrast to Java's compile-time system of classes built by declarations, JavaScript supports a runtime system based on a small number of data types representing numeric, Boolean, and string values. JavaScript has a prototype-based object model instead of the more common class-based object model. The prototype-based model provides dynamic inheritance; that is, what is inherited can vary for individual objects. JavaScript also supports functions without any special declarative requirements. Functions can be properties of objects, executing as loosely typed methods.

JavaScript is a very free-form language compared to Java. You do not have to declare all variables, classes, and methods. You do not have to be concerned with whether methods are public, private, or protected, and you do not have to implement interfaces. Variables, parameters, and function return types are not explicitly typed.

Java is a class-based programming language designed for fast execution and type safety. Type safety means, for instance, that you can't cast a Java integer into an object reference or access private memory by corrupting the Java bytecode. Java's class-based model means that programs consist exclusively of classes and their methods. Java's class inheritance and strong typing generally require tightly coupled object hierarchies. These requirements make Java programming more complex than JavaScript programming.

In contrast, JavaScript descends in spirit from a line of smaller, dynamically typed languages such as HyperTalk and dBASE. These scripting languages offer programming tools to a much wider audience because of their easier syntax, specialized built-in functionality, and minimal requirements for object creation.

| JavaScript | Java |
| --- | --- |
| Object-oriented. No distinction between types of objects. Inheritance is through the prototype mechanism, and properties and methods can be added to any object dynamically. | Class-based. Objects are divided into classes and instances with all inheritance through the class hierarchy. Classes and instances cannot have properties or methods added dynamically. |
| Variable data types are not declared (dynamic typing, loosely typed). | Variable data types must be declared (static typing, strongly typed). |
| Cannot automatically write to hard disk. | Can automatically write to hard disk. |

JavaScript and the ECMAScript specification
-------------------------------------------

JavaScript is standardized at Ecma International — the European association for standardizing information and communication systems (ECMA was formerly an acronym for the European Computer Manufacturers Association) to deliver a standardized, international programming language based on JavaScript. This standardized version of JavaScript, called ECMAScript, behaves the same way in all applications that support the standard. Companies can use the open standard language to develop their implementation of JavaScript. The ECMAScript standard is documented in the ECMA-262 specification.

The ECMA-262 standard is also approved by the ISO (International Organization for Standardization) as ISO-16262. You can also find the specification on the Ecma International website. The ECMAScript specification does not describe the Document Object Model (DOM), which is standardized by the World Wide Web Consortium (W3C) and/or WHATWG (Web Hypertext Application Technology Working Group). The DOM defines the way in which HTML document objects are exposed to your script. To get a better idea about the different technologies that are used when programming with JavaScript, consult the article JavaScript technologies overview.

### JavaScript documentation versus the ECMAScript specification

The ECMAScript specification is a set of requirements for implementing ECMAScript. It is useful if you want to implement standards-compliant language features in your ECMAScript implementation or engine (such as SpiderMonkey in Firefox, or V8 in Chrome).

The ECMAScript document is *not* intended to help script programmers. Use the JavaScript documentation for information when writing scripts.

The ECMAScript specification uses terminology and syntax that may be unfamiliar to a JavaScript programmer. Although the description of the language may differ in ECMAScript, the language itself remains the same. JavaScript supports all functionality outlined in the ECMAScript specification.

The JavaScript documentation describes aspects of the language that are appropriate for a JavaScript programmer.

Getting started with JavaScript
-------------------------------

To get started with JavaScript, all you need is a modern web browser. Recent versions of Firefox, Chrome, Microsoft Edge, and Safari all support the features discussed in this guide.

A very useful tool for exploring JavaScript is the JavaScript Console (sometimes called the Web Console, or just the console): this is a tool which enables you to enter JavaScript and run it in the current page.

The screenshots here show the Firefox Web Console, but all modern browsers ship with a console that works in a similar way.

### Opening the console

The exact instructions for opening the console vary from one browser to another:

* Opening the console in Firefox
* Opening the console in Chrome
* Opening the console in Microsoft Edge
### Entering and running JavaScript

The console appears at the bottom of the browser window. Along the bottom of the console is an input line that you can use to enter JavaScript, and the output appears in the panel above:

![A browser window with the web console open at the bottom, containing two lines of input and output. Text can be entered below that.](/en-US/docs/Web/JavaScript/Guide/Introduction/2019-04-04_00-15-29.png)

The console works the exact same way as `eval`: the last expression entered is returned. For the sake of simplicity, it can be imagined that every time something is entered into the console, it is actually surrounded by `console.log` around `eval`, like so:

```js
console.log(eval("3 + 5"));
```

### Multi-line input in the console

By default, if you press `Enter` (or `Return`, depending on your keyboard) after entering a line of code, then the string you typed is executed. To enter multi-line input:

* If the string you typed was incomplete (for example, you typed `function foo() {`) then the console will treat `Enter` as a line break, and let you type another line.
* If you hold down `Shift` while pressing `Enter`, then the console will treat this as a line break, and let you type another line.
* In Firefox only, you can activate multi-line input mode, in which you can enter multiple lines in a mini-editor, then run the whole thing when you are ready.

To get started with writing JavaScript, open the console, copy the following code, and paste it in at the prompt:

```js
(function () {
  "use strict";
  /\* Start of your code \*/
  function greetMe(yourName) {
    alert(`Hello ${yourName}`);
  }

  greetMe("World");
  /\* End of your code \*/
})();
```

Press `Enter` to watch it unfold in your browser!

What's next
-----------

In the following pages, this guide introduces you to the JavaScript syntax and language features, so that you will be able to write more complex applications.

But for now, remember to always include the `(function(){"use strict";` before your code, and add `})();` to the end of your code. The strict mode and IIFE articles explain what those do, but for now they can be thought of as doing the following:

1. Prevent semantics in JavaScript that trip up beginners.
2. Prevent code snippets executed in the console from interacting with one another (e.g., having something created in one console execution being used for a different console execution).
* « Previous
* Next »