Proxy - JavaScript

Proxy
=====

The **`Proxy`** object enables you to create a proxy for another object, which can intercept and redefine fundamental operations for that object.

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

The `Proxy` object allows you to create an object that can be used in place of the original object, but which may redefine fundamental `Object` operations like getting, setting, and defining properties. Proxy objects are commonly used to log property accesses, validate, format, or sanitize inputs, and so on.

You create a `Proxy` with two parameters:

* `target`: the original object which you want to proxy
* `handler`: an object that defines which operations will be intercepted and how to redefine intercepted operations.

For example, this code creates a proxy for the `target` object.

```js
const target = {
  message1: "hello",
  message2: "everyone",
};

const handler1 = {};

const proxy1 = new Proxy(target, handler1);
```

Because the handler is empty, this proxy behaves just like the original target:

```js
console.log(proxy1.message1); // hello
console.log(proxy1.message2); // everyone
```

To customize the proxy, we define functions on the handler object:

```js
const target = {
  message1: "hello",
  message2: "everyone",
};

const handler2 = {
  get(target, prop, receiver) {
    return "world";
  },
};

const proxy2 = new Proxy(target, handler2);
```

Here we've provided an implementation of the `get()` handler, which intercepts attempts to access properties in the target.

Handler functions are sometimes called *traps*, presumably because they trap calls to the target object. The very simple trap in `handler2` above redefines all property accessors:

```js
console.log(proxy2.message1); // world
console.log(proxy2.message2); // world
```

Proxies are often used with the `Reflect` object, which provides some methods with the same names as the `Proxy` traps. The `Reflect` methods provide the reflective semantics for invoking the corresponding object internal methods. For example, we can call `Reflect.get` if we don't wish to redefine the object's behavior:

```js
const target = {
  message1: "hello",
  message2: "everyone",
};

const handler3 = {
  get(target, prop, receiver) {
    if (prop === "message2") {
      return "world";
    }
    return Reflect.get(...arguments);
  },
};

const proxy3 = new Proxy(target, handler3);

console.log(proxy3.message1); // hello
console.log(proxy3.message2); // world
```

The `Reflect` method still interacts with the object through object internal methods — it doesn't "de-proxify" the proxy if it's invoked on a proxy. If you use `Reflect` methods within a proxy trap, and the `Reflect` method call gets intercepted by the trap again, there may be infinite recursion.

### Terminology

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

handler

The object passed as the second argument to the `Proxy` constructor. It contains the traps which define the behavior of the proxy.

trap

The function that define the behavior for the corresponding object internal method. (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. If your trap implementation violates the invariants of a handler, a `TypeError` will be thrown.

### Object internal methods

Objects are collections of properties. However, the language doesn't provide any machinery to *directly* manipulate data stored in the object — rather, the object defines some internal methods specifying how it can be interacted with. For example, when you read `obj.x`, you may expect the following to happen:

* The `x` property is searched up the prototype chain until it is found.
* If `x` is a data property, the property descriptor's `value` attribute is returned.
* If `x` is an accessor property, the getter is invoked, and the return value of the getter is returned.

There isn't anything special about this process in the language — it's just because ordinary objects, by default, have a `[[Get]]` internal method that is defined with this behavior. The `obj.x` property access syntax simply invokes the `[[Get]]` method on the object, and the object uses its own internal method implementation to determine what to return.

As another example, arrays differ from normal objects, because they have a magic `length` property that, when modified, automatically allocates empty slots or removes elements from the array. Similarly, adding array elements automatically changes the `length` property. This is because arrays have a `[[DefineOwnProperty]]` internal method that knows to update `length` when an integer index is written to, or update the array contents when `length` is written to. Such objects whose internal methods have different implementations from ordinary objects are called *exotic objects*. `Proxy` enable developers to define their own exotic objects with full capacity.

All objects have the following internal methods:

| Internal method | Corresponding trap |
| --- | --- |
| `[[GetPrototypeOf]]` | `getPrototypeOf()` |
| `[[SetPrototypeOf]]` | `setPrototypeOf()` |
| `[[IsExtensible]]` | `isExtensible()` |
| `[[PreventExtensions]]` | `preventExtensions()` |
| `[[GetOwnProperty]]` | `getOwnPropertyDescriptor()` |
| `[[DefineOwnProperty]]` | `defineProperty()` |
| `[[HasProperty]]` | `has()` |
| `[[Get]]` | `get()` |
| `[[Set]]` | `set()` |
| `[[Delete]]` | `deleteProperty()` |
| `[[OwnPropertyKeys]]` | `ownKeys()` |

Function objects also have the following internal methods:

| Internal method | Corresponding trap |
| --- | --- |
| `[[Call]]` | `apply()` |
| `[[Construct]]` | `construct()` |

It's important to realize that all interactions with an object eventually boils down to the invocation of one of these internal methods, and that they are all customizable through proxies. This means almost no behavior (except certain critical invariants) is guaranteed in the language — everything is defined by the object itself. When you run `delete obj.x`, there's no guarantee that `"x" in obj` returns `false` afterwards — it depends on the object's implementations of `[[Delete]]` and `[[HasProperty]]`. A `delete obj.x` may log things to the console, modify some global state, or even define a new property instead of deleting the existing one, although these semantics should be avoided in your own code.

All internal methods are called by the language itself, and are not directly accessible in JavaScript code. The `Reflect` namespace offers methods that do little more than call the internal methods, besides some input normalization/validation. In each trap's page, we list several typical situations when the trap is invoked, but these internal methods are called in *a lot* of places. For example, array methods read and write to array through these internal methods, so methods like `push()` would also invoke `get()` and `set()` traps.

Most of the internal methods are straightforward in what they do. The only two that may be confusable are `[[Set]]` and `[[DefineOwnProperty]]`. For normal objects, the former invokes setters; the latter doesn't. (And `[[Set]]` calls `[[DefineOwnProperty]]` internally if there's no existing property or the property is a data property.) While you may know that the `obj.x = 1` syntax uses `[[Set]]`, and `Object.defineProperty()` uses `[[DefineOwnProperty]]`, it's not immediately apparent what semantics other built-in methods and syntaxes use. For example, class fields use the `[[DefineOwnProperty]]` semantic, which is why setters defined in the superclass are not invoked when a field is declared on the derived class.

Constructor
-----------

`Proxy()`

Creates a new `Proxy` object.

**Note:** There's no `Proxy.prototype` property, so `Proxy` instances do not have any special properties or methods.

Static methods
--------------

`Proxy.revocable()`

Creates a revocable `Proxy` object.

Examples
--------

### Basic example

In this simple example, the number `37` gets returned as the default value when the property name is not in the object. It is using the `get()` handler.

```js
const handler = {
  get(obj, prop) {
    return prop in obj ? obj[prop] : 37;
  },
};

const p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;

console.log(p.a, p.b); // 1, undefined

console.log("c" in p, p.c); // false, 37
```

### No-op forwarding proxy

In this example, we are using a native JavaScript object to which our proxy will forward all operations that are applied to it.

```js
const target = {};
const p = new Proxy(target, {});

p.a = 37; // Operation forwarded to the target

console.log(target.a); // 37 (The operation has been properly forwarded!)
```

Note that while this "no-op" works for plain JavaScript objects, it does not work for native objects, such as DOM elements, `Map` objects, or anything that has internal slots. See no private property forwarding for more information.

### No private property forwarding

A proxy is still another object with a different identity — it's a *proxy* that operates between the wrapped object and the outside. As such, the proxy does not have direct access to the original object's private properties.

```js
class Secret {
  #secret;
  constructor(secret) {
    this.#secret = secret;
  }
  get secret() {
    return this.#secret.replace(/\d+/, "[REDACTED]");
  }
}

const aSecret = new Secret("123456");
console.log(aSecret.secret); // [REDACTED]
// Looks like a no-op forwarding...
const proxy = new Proxy(aSecret, {});
console.log(proxy.secret); // TypeError: Cannot read private member #secret from an object whose class did not declare it
```

This is because when the proxy's `get` trap is invoked, the `this` value is the `proxy` instead of the original `secret`, so `#secret` is not accessible. To fix this, use the original `secret` as `this`:

```js
const proxy = new Proxy(aSecret, {
  get(target, prop, receiver) {
    // By default, it looks like Reflect.get(target, prop, receiver)
    // which has a different value of `this`
    return target[prop];
  },
});
console.log(proxy.secret);
```

For methods, this means you have to redirect the method's `this` value to the original object as well:

```js
class Secret {
  #x = 1;
  x() {
    return this.#x;
  }
}

const aSecret = new Secret();
const proxy = new Proxy(aSecret, {
  get(target, prop, receiver) {
    const value = target[prop];
    if (value instanceof Function) {
      return function (...args) {
        return value.apply(this === receiver ? target : this, args);
      };
    }
    return value;
  },
});
console.log(proxy.x());
```

Some native JavaScript objects have properties called *internal slots*, which are not accessible from JavaScript code. For example, `Map` objects have an internal slot called `[[MapData]]`, which stores the key-value pairs of the map. As such, you cannot trivially create a forwarding proxy for a map:

```js
const proxy = new Proxy(new Map(), {});
console.log(proxy.size); // TypeError: get size method called on incompatible Proxy
```

You have to use the "`this`-recovering" proxy illustrated above to work around this.

### Validation

With a `Proxy`, you can easily validate the passed value for an object. This example uses the `set()` handler.

```js
const validator = {
  set(obj, prop, value) {
    if (prop === "age") {
      if (!Number.isInteger(value)) {
        throw new TypeError("The age is not an integer");
      }
      if (value > 200) {
        throw new RangeError("The age seems invalid");
      }
    }

    // The default behavior to store the value
    obj[prop] = value;

    // Indicate success
    return true;
  },
};

const person = new Proxy({}, validator);

person.age = 100;
console.log(person.age); // 100
person.age = "young"; // Throws an exception
person.age = 300; // Throws an exception
```

### Manipulating DOM nodes

In this example we use `Proxy` to toggle an attribute of two different elements: so when we set the attribute on one element, the attribute is unset on the other one.

We create a `view` object which is a proxy for an object with a `selected` property. The proxy handler defines the `set()` handler.

When we assign an HTML element to `view.selected`, the element's `'aria-selected'` attribute is set to `true`. If we then assign a different element to `view.selected`, this element's `'aria-selected'` attribute is set to `true` and the previous element's `'aria-selected'` attribute is automatically set to `false`.

```js
const view = new Proxy(
  {
    selected: null,
  },
  {
    set(obj, prop, newval) {
      const oldval = obj[prop];

      if (prop === "selected") {
        if (oldval) {
          oldval.setAttribute("aria-selected", "false");
        }
        if (newval) {
          newval.setAttribute("aria-selected", "true");
        }
      }

      // The default behavior to store the value
      obj[prop] = newval;

      // Indicate success
      return true;
    },
  },
);

const item1 = document.getElementById("item-1");
const item2 = document.getElementById("item-2");

// select item1:
view.selected = item1;

console.log(`item1: ${item1.getAttribute("aria-selected")}`);
// item1: true

// selecting item2 de-selects item1:
view.selected = item2;

console.log(`item1: ${item1.getAttribute("aria-selected")}`);
// item1: false

console.log(`item2: ${item2.getAttribute("aria-selected")}`);
// item2: true
```

### Value correction and an extra property

The `products` proxy object evaluates the passed value and converts it to an array if needed. The object also supports an extra property called `latestBrowser` both as a getter and a setter.

```js
const products = new Proxy(
  {
    browsers: ["Firefox", "Chrome"],
  },
  {
    get(obj, prop) {
      // An extra property
      if (prop === "latestBrowser") {
        return obj.browsers[obj.browsers.length - 1];
      }

      // The default behavior to return the value
      return obj[prop];
    },
    set(obj, prop, value) {
      // An extra property
      if (prop === "latestBrowser") {
        obj.browsers.push(value);
        return true;
      }

      // Convert the value if it is not an array
      if (typeof value === "string") {
        value = [value];
      }

      // The default behavior to store the value
      obj[prop] = value;

      // Indicate success
      return true;
    },
  },
);

console.log(products.browsers);
// ['Firefox', 'Chrome']

products.browsers = "Safari";
// pass a string (by mistake)

console.log(products.browsers);
// ['Safari'] <- no problem, the value is an array

products.latestBrowser = "Edge";

console.log(products.browsers);
// ['Safari', 'Edge']

console.log(products.latestBrowser);
// 'Edge'
```

### A complete traps list example

Now in order to create a complete sample `traps` list, for didactic purposes, we will try to proxify a *non-native* object that is particularly suited to this type of operation: the `docCookies` global object created by a simple cookie framework.

```js
/\*
 const docCookies = ... get the "docCookies" object here:
 https://reference.codeproject.com/dom/document/cookie/simple\_document.cookie\_framework
\*/

const docCookies = new Proxy(docCookies, {
  get(target, key) {
    return target[key] ?? target.getItem(key) ?? undefined;
  },
  set(target, key, value) {
    if (key in target) {
      return false;
    }
    return target.setItem(key, value);
  },
  deleteProperty(target, key) {
    if (!(key in target)) {
      return false;
    }
    return target.removeItem(key);
  },
  ownKeys(target) {
    return target.keys();
  },
  has(target, key) {
    return key in target || target.hasItem(key);
  },
  defineProperty(target, key, descriptor) {
    if (descriptor && "value" in descriptor) {
      target.setItem(key, descriptor.value);
    }
    return target;
  },
  getOwnPropertyDescriptor(target, key) {
    const value = target.getItem(key);
    return value
      ? {
          value,
          writable: true,
          enumerable: true,
          configurable: false,
        }
      : undefined;
  },
});

/\* Cookies test \*/

console.log((docCookies.myCookie1 = "First value"));
console.log(docCookies.getItem("myCookie1"));

docCookies.setItem("myCookie1", "Changed value");
console.log(docCookies.myCookie1);
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-proxy-objects |

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

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

See also
--------

* Proxies are awesome presentation by Brendan Eich at JSConf (2014)


Uint16Array - JavaScript

Uint16Array
===========

The **`Uint16Array`** typed array represents an array of 16-bit unsigned integers in the platform byte order. If control over byte order is needed, use `DataView` instead. The contents are initialized to `0`. Once established, you can reference elements in the array using the object's methods, or using standard array index syntax (that is, using bracket notation).

`Uint16Array` is a subclass of the hidden `TypedArray` class.

Constructor
-----------

`Uint16Array()`

Creates a new `Uint16Array` object.

Static properties
-----------------

*Also inherits static properties from its parent `TypedArray`*.

`Uint16Array.BYTES_PER_ELEMENT`

Returns a number value of the element size. `2` in the case of `Uint16Array`.

Static methods
--------------

*Inherits static methods from its parent `TypedArray`*.

Instance properties
-------------------

*Also inherits instance properties from its parent `TypedArray`*.

These properties are defined on `Uint16Array.prototype` and shared by all `Uint16Array` instances.

`Uint16Array.prototype.BYTES_PER_ELEMENT`

Returns a number value of the element size. `2` in the case of a `Uint16Array`.

`Uint16Array.prototype.constructor`

The constructor function that created the instance object. For `Uint16Array` instances, the initial value is the `Uint16Array` constructor.

Instance methods
----------------

*Inherits instance methods from its parent `TypedArray`*.

Examples
--------

### Different ways to create a Uint16Array

```js
// From a length
const uint16 = new Uint16Array(2);
uint16[0] = 42;
console.log(uint16[0]); // 42
console.log(uint16.length); // 2
console.log(uint16.BYTES\_PER\_ELEMENT); // 2

// From an array
const x = new Uint16Array([21, 31]);
console.log(x[1]); // 31

// From another TypedArray
const y = new Uint16Array(x);
console.log(y[0]); // 21

// From an ArrayBuffer
const buffer = new ArrayBuffer(16);
const z = new Uint16Array(buffer, 2, 4);
console.log(z.byteOffset); // 2

// From an iterable
const iterable = (function\* () {
  yield\* [1, 2, 3];
})();
const uint16FromIterable = new Uint16Array(iterable);
console.log(uint16FromIterable);
// Uint16Array [1, 2, 3]
```

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

| Specification |
| --- |
| ECMAScript Language Specification # table-49 |

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

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

See also
--------

* Polyfill of `Uint16Array` in `core-js`
* JavaScript typed arrays guide
* `TypedArray`
* `ArrayBuffer`
* `DataView`


Map - JavaScript

Map
===

 The **`Map`** object holds key-value pairs and remembers the original insertion order of the keys.
 Any value (both objects and primitive values) may be used as either a key or a value.

Try it
------

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

`Map` objects are collections of key-value pairs. A key in the `Map` **may only occur once**; it is unique in the `Map`'s collection. A `Map` object is iterated by key-value pairs — a `for...of` loop returns a 2-member array of `[key, value]` for each iteration. Iteration happens in *insertion order*, which corresponds to the order in which each key-value pair was first inserted into the map by the `set()` method (that is, there wasn't a key with the same value already in the map when `set()` was called).

The specification requires maps to be implemented "that, on average, provide access times that are sublinear on the number of elements in the collection". Therefore, it could be represented internally as a hash table (with O(1) lookup), a search tree (with O(log(N)) lookup), or any other data structure, as long as the complexity is better than O(N).

### Key equality

Value equality is based on the SameValueZero algorithm. (It used to use SameValue, which treated `0` and `-0` as different. Check browser compatibility.) This means `NaN` is considered the same as `NaN` (even though `NaN !== NaN`) and all other values are considered equal according to the semantics of the `===` operator.

### Objects vs. Maps

`Object` is similar to `Map`—both let you set keys to
 values, retrieve those values, delete keys, and detect whether something is
 stored at a key. For this reason (and because there were no built-in
 alternatives), `Object` has been used as `Map` historically.

 However, there are important differences that make `Map` preferable in some
 cases:

|  | Map | Object |
| --- | --- | --- |
| Accidental Keys |
 A `Map` does not contain any keys by default. It only
 contains what is explicitly put into it.
  |
 An `Object` has a prototype, so it contains default keys
 that could collide with your own keys if you're not careful.

**Note:** This can be bypassed by using
 `Object.create(null)`,
 but this is seldom done.

 |
| Security | A `Map` is safe to use with user-provided keys and values. |
 Setting user-provided key-value pairs on an `Object` may allow
 an attacker to override the object's prototype, which can lead to
 object injection attacks. Like the accidental keys issue, this can also be mitigated by using
 a `null`-prototype object.
  |
| Key Types |
 A `Map`'s keys can be any value (including functions,
 objects, or any primitive).
  |
 The keys of an `Object` must be either a
 `String` or a `Symbol`.
  |
| Key Order |
 The keys in `Map` are ordered in a simple, straightforward
 way: A `Map` object iterates entries, keys, and values in
 the order of entry insertion.
  |
 Although the keys of an ordinary `Object` are ordered now,
 this was not always the case, and the order is complex. As a result,
 it's best not to rely on property order.

 The order was first defined for own properties only in ECMAScript
 2015; ECMAScript 2020 defines order for inherited properties as well.
 But note that no single mechanism
 iterates
 **all** of an object's properties; the various mechanisms
 each include different subsets of properties.
 (`for-in`
 includes only enumerable string-keyed properties;
 `Object.keys` includes only own, enumerable,
 string-keyed properties;
 `Object.getOwnPropertyNames` includes own,
 string-keyed properties even if non-enumerable;
 `Object.getOwnPropertySymbols` does the same
 for just `Symbol`-keyed properties, etc.)
  |
| Size |
 The number of items in a `Map` is easily retrieved from its
 `size` property.
  | Determining the number of items in an `Object` is more roundabout and less efficient. A common way to do it is through the `length` of the array returned from `Object.keys()`. |
| Iteration |
 A `Map` is an
 iterable, so it can be directly iterated.
  |
`Object` does not implement an iteration protocol, and so objects are not directly iterable using the JavaScript
 for...of
 statement (by default).

**Note:**
* An object can implement the iteration protocol, or you can get an
 iterable for an object using `Object.keys` or `Object.entries`.
* The
 for...in
 statement allows you to iterate over the
 *enumerable* properties of an object.

 |
| Performance |
 Performs better in scenarios involving frequent additions and removals
 of key-value pairs.
  | Not optimized for frequent additions and removals of key-value pairs. |
| Serialization and parsing | No native support for serialization or parsing.

 (But you can build your own serialization and parsing support for
 `Map` by using `JSON.stringify()`
 with its *replacer* argument, and by using
 `JSON.parse()` with its
 *reviver* argument. See the Stack Overflow question
 How do you JSON.stringify an ES6 Map?).
  |
 Native support for serialization from `Object` to
 JSON, using `JSON.stringify()`.

 Native support for parsing from JSON to `Object`,
 using `JSON.parse()`.
  |

### Setting object properties

 Setting Object properties works for Map objects as well, and can cause
 considerable confusion.

Therefore, this appears to work in a way:

```js
const wrongMap = new Map();
wrongMap["bla"] = "blaa";
wrongMap["bla2"] = "blaaa2";

console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }
```

 But that way of setting a property does not interact with the Map data
 structure. It uses the feature of the generic object. The value of 'bla' is not
 stored in the Map for queries. Other operations on the data fail:

```js
wrongMap.has("bla"); // false
wrongMap.delete("bla"); // false
console.log(wrongMap); // Map { bla: 'blaa', bla2: 'blaaa2' }
```

 The correct usage for storing data in the Map is through the `set(key, value)`
 method.

```js
const contacts = new Map();
contacts.set("Jessie", { phone: "213-555-1234", address: "123 N 1st Ave" });
contacts.has("Jessie"); // true
contacts.get("Hilary"); // undefined
contacts.set("Hilary", { phone: "617-555-4321", address: "321 S 2nd St" });
contacts.get("Jessie"); // {phone: "213-555-1234", address: "123 N 1st Ave"}
contacts.delete("Raymond"); // false
contacts.delete("Jessie"); // true
console.log(contacts.size); // 1
```

### Map-like browser APIs

**Browser `Map`-like objects** (or "maplike objects") are Web API interfaces that behave in many ways like a `Map`.

 Just like `Map`, entries can be iterated in the same order that they were added to the object.
 `Map`-like objects and `Map` also have properties and methods that share the same name and behavior.
 However unlike `Map` they only allow specific predefined types for the keys and values of each entry.

 The allowed types are set in the specification IDL definition.
 For example, `RTCStatsReport` is a `Map`-like object that must use strings for keys and objects for values.
 This is defined in the specification IDL below:

```webidl
interface RTCStatsReport {
  readonly maplike<DOMString, object>;
};
```

`Map`-like objects are either read-only or read-writable (see the `readonly` keyword in the IDL above).

* Read-only `Map`-like objects have the property `size`, and the methods: `entries()`, `forEach()`, `get()`, `has()`, `keys()`, `values()`, and `@@iterator`.
* Writeable `Map`-like objects additionally have the methods: `clear()`, `delete()`, and `set()`.

The methods and properties have the same behavior as the equivalent entities in `Map`, except for the restriction on the types of the keys and values.

The following are examples of read-only `Map`-like browser objects:

* `AudioParamMap`
* `RTCStatsReport`
* `EventCounts`
* `KeyboardLayoutMap`
* `MIDIInputMap`
* `MIDIOutputMap`
Constructor
-----------

`Map()`

Creates a new `Map` object.

Static properties
-----------------

`Map[@@species]`

The constructor function that is used to create derived objects.

Static methods
--------------

`Map.groupBy()`

Groups the elements of a given iterable using the values returned by a provided callback function. The final returned `Map` uses the unique values from the test function as keys, which can be used to get the array of elements in each group.

Instance properties
-------------------

These properties are defined on `Map.prototype` and shared by all `Map` instances.

`Map.prototype.constructor`

The constructor function that created the instance object. For `Map` instances, the initial value is the `Map` constructor.

`Map.prototype.size`

Returns the number of key/value pairs in the `Map` object.

`Map.prototype[@@toStringTag]`

The initial value of the `@@toStringTag` property is the string `"Map"`. This property is used in `Object.prototype.toString()`.

Instance methods
----------------

`Map.prototype.clear()`

Removes all key-value pairs from the `Map` object.

`Map.prototype.delete()`

 Returns `true` if an element in the `Map` object existed and has been
 removed, or `false` if the element does not exist. `map.has(key)`
 will return `false` afterwards.

`Map.prototype.entries()`

Returns a new Iterator object that contains a two-member array of `[key, value]` for each element in the `Map` object in insertion order.

`Map.prototype.forEach()`

Calls `callbackFn` once for each key-value pair present in the `Map` object, in insertion order. If a `thisArg` parameter is provided to `forEach`, it will be used as the `this` value for each callback.

`Map.prototype.get()`

Returns the value associated to the passed key, or `undefined` if there is none.

`Map.prototype.has()`

Returns a boolean indicating whether a value has been associated with the passed key in the `Map` object or not.

`Map.prototype.keys()`

Returns a new Iterator object that contains the keys for each element in the `Map` object in insertion order.

`Map.prototype.set()`

Sets the value for the passed key in the `Map` object. Returns the `Map` object.

`Map.prototype.values()`

Returns a new Iterator object that contains the values for each element in the `Map` object in insertion order.

`Map.prototype[@@iterator]()`

Returns a new Iterator object that contains a two-member array of `[key, value]` for each element in the `Map` object in insertion order.

Examples
--------

### Using the Map object

```js
const myMap = new Map();

const keyString = "a string";
const keyObj = {};
const keyFunc = function () {};

// setting the values
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");

console.log(myMap.size); // 3

// getting the values
console.log(myMap.get(keyString)); // "value associated with 'a string'"
console.log(myMap.get(keyObj)); // "value associated with keyObj"
console.log(myMap.get(keyFunc)); // "value associated with keyFunc"

console.log(myMap.get("a string")); // "value associated with 'a string'", because keyString === 'a string'
console.log(myMap.get({})); // undefined, because keyObj !== {}
console.log(myMap.get(function () {})); // undefined, because keyFunc !== function () {}
```

### Using NaN as Map keys

`NaN` can also be used as a key. Even though every `NaN` is
 not equal to itself (`NaN !== NaN` is true), the following example works because
 `NaN`s are indistinguishable from each other:

```js
const myMap = new Map();
myMap.set(NaN, "not a number");

myMap.get(NaN);
// "not a number"

const otherNaN = Number("foo");
myMap.get(otherNaN);
// "not a number"
```

### Iterating Map with for...of

Maps can be iterated using a `for...of` loop:

```js
const myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");

for (const [key, value] of myMap) {
  console.log(`${key} = ${value}`);
}
// 0 = zero
// 1 = one

for (const key of myMap.keys()) {
  console.log(key);
}
// 0
// 1

for (const value of myMap.values()) {
  console.log(value);
}
// zero
// one

for (const [key, value] of myMap.entries()) {
  console.log(`${key} = ${value}`);
}
// 0 = zero
// 1 = one
```

### Iterating Map with forEach()

 Maps can be iterated using the
 `forEach()` method:

```js
myMap.forEach((value, key) => {
  console.log(`${key} = ${value}`);
});
// 0 = zero
// 1 = one
```

### Relation with Array objects

```js
const kvArray = [
  ["key1", "value1"],
  ["key2", "value2"],
];

// Use the regular Map constructor to transform a 2D key-value Array into a map
const myMap = new Map(kvArray);

console.log(myMap.get("key1")); // "value1"

// Use Array.from() to transform a map into a 2D key-value Array
console.log(Array.from(myMap)); // Will show you exactly the same Array as kvArray

// A succinct way to do the same, using the spread syntax
console.log([...myMap]);

// Or use the keys() or values() iterators, and convert them to an array
console.log(Array.from(myMap.keys())); // ["key1", "key2"]
```

### Cloning and merging Maps

Just like `Array`s, `Map`s can be cloned:

```js
const original = new Map([[1, "one"]]);

const clone = new Map(original);

console.log(clone.get(1)); // one
console.log(original === clone); // false (useful for shallow comparison)
```

**Note:** Keep in mind that *the data itself* is not cloned.

Maps can be merged, maintaining key uniqueness:

```js
const first = new Map([
  [1, "one"],
  [2, "two"],
  [3, "three"],
]);

const second = new Map([
  [1, "uno"],
  [2, "dos"],
]);

// Merge two maps. The last repeated key wins.
// Spread syntax essentially converts a Map to an Array
const merged = new Map([...first, ...second]);

console.log(merged.get(1)); // uno
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
```

Maps can be merged with Arrays, too:

```js
const first = new Map([
  [1, "one"],
  [2, "two"],
  [3, "three"],
]);

const second = new Map([
  [1, "uno"],
  [2, "dos"],
]);

// Merge maps with an array. The last repeated key wins.
const merged = new Map([...first, ...second, [1, "eins"]]);

console.log(merged.get(1)); // eins
console.log(merged.get(2)); // dos
console.log(merged.get(3)); // three
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-map-objects |

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

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

See also
--------

* Polyfill for `Map` in `core-js`
* `Set`
* `WeakMap`
* `WeakSet`


decodeURIComponent() - JavaScript

decodeURIComponent()
====================

The **`decodeURIComponent()`** function decodes a Uniform Resource Identifier (URI) component previously created by `encodeURIComponent()` or by a similar routine.

Try it
------

Syntax
------

```js
decodeURIComponent(encodedURI)
```

### Parameters

`encodedURI`

An encoded component of a Uniform Resource Identifier.

### Return value

A new string representing the decoded version of the given encoded Uniform Resource Identifier (URI) component.

### Exceptions

`URIError`

Thrown if `encodedURI` contains a `%` not followed by two hexadecimal digits, or if the escape sequence does not encode a valid UTF-8 character.

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

`decodeURIComponent()` is a function property of the global object.

`decodeURIComponent()` uses the same decoding algorithm as described in `decodeURI()`. It decodes *all* escape sequences, including those that are not created by `encodeURIComponent`, like `-.!~*'()`.

Examples
--------

### Decoding a Cyrillic URL component

```js
decodeURIComponent("JavaScript\_%D1%88%D0%B5%D0%BB%D0%BB%D1%8B");
// "JavaScript\_шеллы"
```

### Catching errors

```js
try {
  const a = decodeURIComponent("%E0%A4%A");
} catch (e) {
  console.error(e);
}

// URIError: malformed URI sequence
```

### Decoding query parameters from a URL

`decodeURIComponent()` cannot be used directly to parse query parameters from a URL. It needs a bit of preparation.

```js
function decodeQueryParam(p) {
  return decodeURIComponent(p.replace(/\+/g, " "));
}

decodeQueryParam("search+query%20%28correct%29");
// 'search query (correct)'
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-decodeuricomponent-encodeduricomponent |

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

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

See also
--------

* `decodeURI`
* `encodeURI`
* `encodeURIComponent`


AsyncFunction - JavaScript

AsyncFunction
=============

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

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

* Learn more
* See full compatibility
* Report feedback
The **`AsyncFunction`** object provides methods for async functions. In JavaScript, every async function is actually an `AsyncFunction` object.

Note that `AsyncFunction` is *not* a global object. It can be obtained with the following code:

```js
const AsyncFunction = async function () {}.constructor;
```

`AsyncFunction` is a subclass of `Function`.

Constructor
-----------

`AsyncFunction()`

Creates a new `AsyncFunction` object.

Instance properties
-------------------

*Also inherits instance properties from its parent `Function`*.

These properties are defined on `AsyncFunction.prototype` and shared by all `AsyncFunction` instances.

`AsyncFunction.prototype.constructor`

The constructor function that created the instance object. For `AsyncFunction` instances, the initial value is the `AsyncFunction` constructor.

`AsyncFunction.prototype[@@toStringTag]`

The initial value of the `@@toStringTag` property is the string `"AsyncFunction"`. This property is used in `Object.prototype.toString()`.

**Note:** `AsyncFunction` instances do not have the `prototype` property.

Instance methods
----------------

*Inherits instance methods from its parent `Function`*.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-async-function-objects |

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

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

See also
--------

* `async function`
* `async function` expression
* `Function`
* `AsyncGeneratorFunction`
* `GeneratorFunction`
* Functions


decodeURI() - JavaScript

decodeURI()
===========

The **`decodeURI()`** function decodes a Uniform Resource Identifier (URI) previously created by `encodeURI()` or a similar routine.

Try it
------

Syntax
------

```js
decodeURI(encodedURI)
```

### Parameters

`encodedURI`

A complete, encoded Uniform Resource Identifier.

### Return value

A new string representing the unencoded version of the given encoded Uniform Resource Identifier (URI).

### Exceptions

`URIError`

Thrown if `encodedURI` contains a `%` not followed by two hexadecimal digits, or if the escape sequence does not encode a valid UTF-8 character.

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

`decodeURI()` is a function property of the global object.

The `decodeURI()` function decodes the URI by treating each escape sequence in the form `%XX` as one UTF-8 code unit (one byte). In UTF-8, the number of leading 1 bits in the first byte, which may be 0 (for 1-byte ASCII characters), 2, 3, or 4, indicates the number of bytes in the character. So by reading the first escape sequence, `decodeURI()` can determine how many more escape sequences to consume. If `decodeURI()` fails to find the expected number of sequences, or if the escape sequences don't encode a valid UTF-8 character, a `URIError` is thrown.

`decodeURI()` decodes all escape sequences, but if the escape sequence encodes one of the following characters, the escape sequence is preserved in the output string (because they are part of the URI syntax):
```

; / ? : @ & = + $ , #
```

Examples
--------

### Decoding a Cyrillic URL

```js
decodeURI(
  "https://developer.mozilla.org/ru/docs/JavaScript\_%D1%88%D0%B5%D0%BB%D0%BB%D1%8B",
);
// "https://developer.mozilla.org/ru/docs/JavaScript\_шеллы"
```

### decodeURI() vs. decodeURIComponent()

`decodeURI()` assumes the input is a full URI, so it does not decode characters that are part of the URI syntax.

```js
decodeURI(
  "https://developer.mozilla.org/docs/JavaScript%3A%20a\_scripting\_language",
);
// "https://developer.mozilla.org/docs/JavaScript%3A a\_scripting\_language"

decodeURIComponent(
  "https://developer.mozilla.org/docs/JavaScript%3A%20a\_scripting\_language",
);
// "https://developer.mozilla.org/docs/JavaScript: a\_scripting\_language"
```

### Catching errors

```js
try {
  const a = decodeURI("%E0%A4%A");
} catch (e) {
  console.error(e);
}

// URIError: malformed URI sequence
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-decodeuri-encodeduri |

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

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

See also
--------

* `decodeURIComponent()`
* `encodeURI()`
* `encodeURIComponent()`


String - JavaScript

String
======

 The **`String`** object is used to represent and manipulate a
 sequence of characters.

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

 Strings are useful for holding data that can be represented in text form. Some of the
 most-used operations on strings are to check their `length`, to build and concatenate them using the
 `+` and `+=` string operators,
 checking for the existence or location of substrings with the
 `indexOf()` method, or extracting substrings
 with the `substring()` method.

### Creating strings

 Strings can be created as primitives, from string literals, or as objects, using the
 `String()` constructor:

```js
const string1 = "A string primitive";
const string2 = 'Also a string primitive';
const string3 = `Yet another string primitive`;
```

```js
const string4 = new String("A String object");
```

 String primitives and string objects share many behaviors, but have other important differences and caveats.
 See "String primitives and String objects" below.

 String literals can be specified using single or double quotes, which are treated
 identically, or using the backtick character ```. This last form specifies a template literal:
 with this form you can interpolate expressions. For more information on the syntax of string literals, see lexical grammar.

### Character access

 There are two ways to access an individual character in a string. The first is the
 `charAt()` method:

```js
"cat".charAt(1); // gives value "a"
```

The other way is to treat the string as an array-like object, where individual characters correspond to a numerical index:

```js
"cat"[1]; // gives value "a"
```

 When using bracket notation for character access, attempting to delete or assign a
 value to these properties will not succeed. The properties involved are neither writable
 nor configurable. (See `Object.defineProperty()` for more information.)

### Comparing strings

Use the less-than and greater-than operators to compare strings:

```js
const a = "a";
const b = "b";
if (a < b) {
  // true
  console.log(`${a} is less than ${b}`);
} else if (a > b) {
  console.log(`${a} is greater than ${b}`);
} else {
  console.log(`${a} and ${b} are equal.`);
}
```

Note that all comparison operators, including `===` and `==`, compare strings case-sensitively. A common way to compare strings case-insensitively is to convert both to the same case (upper or lower) before comparing them.

```js
function areEqualCaseInsensitive(str1, str2) {
  return str1.toUpperCase() === str2.toUpperCase();
}
```

The choice of whether to transform by `toUpperCase()` or `toLowerCase()` is mostly arbitrary, and neither one is fully robust when extending beyond the Latin alphabet. For example, the German lowercase letter `ß` and `ss` are both transformed to `SS` by `toUpperCase()`, while the Turkish letter `ı` would be falsely reported as unequal to `I` by `toLowerCase()` unless specifically using `toLocaleLowerCase("tr")`.

```js
const areEqualInUpperCase = (str1, str2) =>
  str1.toUpperCase() === str2.toUpperCase();
const areEqualInLowerCase = (str1, str2) =>
  str1.toLowerCase() === str2.toLowerCase();

areEqualInUpperCase("ß", "ss"); // true; should be false
areEqualInLowerCase("ı", "I"); // false; should be true
```

A locale-aware and robust solution for testing case-insensitive equality is to use the `Intl.Collator` API or the string's `localeCompare()` method — they share the same interface — with the `sensitivity` option set to `"accent"` or `"base"`.

```js
const areEqual = (str1, str2, locale = "en-US") =>
  str1.localeCompare(str2, locale, { sensitivity: "accent" }) === 0;

areEqual("ß", "ss", "de"); // false
areEqual("ı", "I", "tr"); // true
```

The `localeCompare()` method enables string comparison in a similar fashion as `strcmp()` — it allows sorting strings in a locale-aware manner.

### String primitives and String objects

 Note that JavaScript distinguishes between `String` objects and
 primitive string values. (The same is true of
 `Boolean` and `Numbers`.)

 String literals (denoted by double or single quotes) and strings returned from
 `String` calls in a non-constructor context (that is, called without using
 the `new` keyword) are primitive strings. In contexts where a
 method is to be invoked on a primitive string or a property lookup occurs, JavaScript
 will automatically wrap the string primitive and call the method or perform the property
 lookup on the wrapper object instead.

```js
const strPrim = "foo"; // A literal is a string primitive
const strPrim2 = String(1); // Coerced into the string primitive "1"
const strPrim3 = String(true); // Coerced into the string primitive "true"
const strObj = new String(strPrim); // String with new returns a string wrapper object.

console.log(typeof strPrim); // "string"
console.log(typeof strPrim2); // "string"
console.log(typeof strPrim3); // "string"
console.log(typeof strObj); // "object"
```

**Warning:** You should rarely find yourself using `String` as a constructor.

 String primitives and `String` objects also give different results when
 using `eval()`. Primitives passed to
 `eval` are treated as source code; `String` objects are treated as
 all other objects are, by returning the object. For example:

```js
const s1 = "2 + 2"; // creates a string primitive
const s2 = new String("2 + 2"); // creates a String object
console.log(eval(s1)); // returns the number 4
console.log(eval(s2)); // returns the string "2 + 2"
```

 For these reasons, the code may break when it encounters `String` objects
 when it expects a primitive string instead, although generally, authors need not worry
 about the distinction.

 A `String` object can always be converted to its primitive counterpart with
 the `valueOf()` method.

```js
console.log(eval(s2.valueOf())); // returns the number 4
```

### String coercion

Many built-in operations that expect strings first coerce their arguments to strings (which is largely why `String` objects behave similarly to string primitives). The operation can be summarized as follows:

* Strings are returned as-is.
* `undefined` turns into `"undefined"`.
* `null` turns into `"null"`.
* `true` turns into `"true"`; `false` turns into `"false"`.
* Numbers are converted with the same algorithm as `toString(10)`.
* BigInts are converted with the same algorithm as `toString(10)`.
* Symbols throw a `TypeError`.
* Objects are first converted to a primitive by calling its `[@@toPrimitive]()` (with `"string"` as hint), `toString()`, and `valueOf()` methods, in that order. The resulting primitive is then converted to a string.

There are several ways to achieve nearly the same effect in JavaScript.

* Template literal: ``${x}`` does exactly the string coercion steps explained above for the embedded expression.
* The `String()` function: `String(x)` uses the same algorithm to convert `x`, except that Symbols don't throw a `TypeError`, but return `"Symbol(description)"`, where `description` is the description of the Symbol.
* Using the `+` operator: `"" + x` coerces its operand to a *primitive* instead of a *string*, and, for some objects, has entirely different behaviors from normal string coercion. See its reference page for more details.

Depending on your use case, you may want to use ``${x}`` (to mimic built-in behavior) or `String(x)` (to handle symbol values without throwing an error), but you should not use `"" + x`.

### UTF-16 characters, Unicode code points, and grapheme clusters

Strings are represented fundamentally as sequences of UTF-16 code units. In UTF-16 encoding, every code unit is exact 16 bits long. This means there are a maximum of 216, or 65536 possible characters representable as single UTF-16 code units. This character set is called the basic multilingual plane (BMP), and includes the most common characters like the Latin, Greek, Cyrillic alphabets, as well as many East Asian characters. Each code unit can be written in a string with `\u` followed by exactly four hex digits.

However, the entire Unicode character set is much, much bigger than 65536. The extra characters are stored in UTF-16 as *surrogate pairs*, which are pairs of 16-bit code units that represent a single character. To avoid ambiguity, the two parts of the pair must be between `0xD800` and `0xDFFF`, and these code units are not used to encode single-code-unit characters. (More precisely, leading surrogates, also called high-surrogate code units, have values between `0xD800` and `0xDBFF`, inclusive, while trailing surrogates, also called low-surrogate code units, have values between `0xDC00` and `0xDFFF`, inclusive.) Each Unicode character, comprised of one or two UTF-16 code units, is also called a *Unicode code point*. Each Unicode code point can be written in a string with `\u{xxxxxx}` where `xxxxxx` represents 1–6 hex digits.

A "lone surrogate" is a 16-bit code unit satisfying one of the descriptions below:

* It is in the range `0xD800`–`0xDBFF`, inclusive (i.e. is a leading surrogate), but it is the last code unit in the string, or the next code unit is not a trailing surrogate.
* It is in the range `0xDC00`–`0xDFFF`, inclusive (i.e. is a trailing surrogate), but it is the first code unit in the string, or the previous code unit is not a leading surrogate.

Lone surrogates do not represent any Unicode character. Although most JavaScript built-in methods handle them correctly because they all work based on UTF-16 code units, lone surrogates are often not valid values when interacting with other systems — for example, `encodeURI()` will throw a `URIError` for lone surrogates, because URI encoding uses UTF-8 encoding, which does not have any encoding for lone surrogates. Strings not containing any lone surrogates are called *well-formed* strings, and are safe to be used with functions that do not deal with UTF-16 (such as `encodeURI()` or `TextEncoder`). You can check if a string is well-formed with the `isWellFormed()` method, or sanitize lone surrogates with the `toWellFormed()` method.

On top of Unicode characters, there are certain sequences of Unicode characters that should be treated as one visual unit, known as a *grapheme cluster*. The most common case is emojis: many emojis that have a range of variations are actually formed by multiple emojis, usually joined by the <ZWJ> (`U+200D`) character.

You must be careful which level of characters you are iterating on. For example, `split("")` will split by UTF-16 code units and will separate surrogate pairs. String indexes also refer to the index of each UTF-16 code unit. On the other hand, `@@iterator()` iterates by Unicode code points. Iterating through grapheme clusters will require some custom code.

```js
"😄".split(""); // ['\ud83d', '\ude04']; splits into two lone surrogates

// "Backhand Index Pointing Right: Dark Skin Tone"
[..."👉🏿"]; // ['👉', '🏿']
// splits into the basic "Backhand Index Pointing Right" emoji and
// the "Dark skin tone" emoji

// "Family: Man, Boy"
[..."👨👦"]; // [ '👨', '', '👦' ]
// splits into the "Man" and "Boy" emoji, joined by a ZWJ

// The United Nations flag
[..."🇺🇳"]; // [ '🇺', '🇳' ]
// splits into two "region indicator" letters "U" and "N".
// All flag emojis are formed by joining two region indicator letters
```

Constructor
-----------

`String()`

 Creates a new `String` object. It performs type conversion when called as
 a function, rather than as a constructor, which is usually more useful.

Static methods
--------------

`String.fromCharCode()`

Returns a string created by using the specified sequence of Unicode values.

`String.fromCodePoint()`

Returns a string created by using the specified sequence of code points.

`String.raw()`

Returns a string created from a raw template string.

Instance properties
-------------------

These properties are defined on `String.prototype` and shared by all `String` instances.

`String.prototype.constructor`

The constructor function that created the instance object. For `String` instances, the initial value is the `String` constructor.

These properties are own properties of each `String` instance.

`length`

Reflects the `length` of the string. Read-only.

Instance methods
----------------

`String.prototype.at()`

Returns the character (exactly one UTF-16 code unit) at the specified `index`. Accepts negative integers, which count back from the last string character.

`String.prototype.charAt()`

 Returns the character (exactly one UTF-16 code unit) at the specified
 `index`.

`String.prototype.charCodeAt()`

 Returns a number that is the UTF-16 code unit value at the given
 `index`.

`String.prototype.codePointAt()`

 Returns a nonnegative integer Number that is the code point value of the UTF-16
 encoded code point starting at the specified `pos`.

`String.prototype.concat()`

Combines the text of two (or more) strings and returns a new string.

`String.prototype.endsWith()`

 Determines whether a string ends with the characters of the string
 `searchString`.

`String.prototype.includes()`

Determines whether the calling string contains `searchString`.

`String.prototype.indexOf()`

 Returns the index within the calling `String` object of the first
 occurrence of `searchValue`, or `-1` if not found.

`String.prototype.isWellFormed()`

Returns a boolean indicating whether this string contains any lone surrogates.

`String.prototype.lastIndexOf()`

 Returns the index within the calling `String` object of the last
 occurrence of `searchValue`, or `-1` if not found.

`String.prototype.localeCompare()`

 Returns a number indicating whether the reference string
 `compareString` comes before, after, or is equivalent to the
 given string in sort order.

`String.prototype.match()`

Used to match regular expression `regexp` against a string.

`String.prototype.matchAll()`

Returns an iterator of all `regexp`'s matches.

`String.prototype.normalize()`

Returns the Unicode Normalization Form of the calling string value.

`String.prototype.padEnd()`

 Pads the current string from the end with a given string and returns a new string of
 the length `targetLength`.

`String.prototype.padStart()`

 Pads the current string from the start with a given string and returns a new string
 of the length `targetLength`.

`String.prototype.repeat()`

 Returns a string consisting of the elements of the object repeated
 `count` times.

`String.prototype.replace()`

 Used to replace occurrences of `searchFor` using
 `replaceWith`. `searchFor` may be a string
 or Regular Expression, and `replaceWith` may be a string or
 function.

`String.prototype.replaceAll()`

 Used to replace all occurrences of `searchFor` using
 `replaceWith`. `searchFor` may be a string
 or Regular Expression, and `replaceWith` may be a string or
 function.

`String.prototype.search()`

 Search for a match between a regular expression `regexp` and
 the calling string.

`String.prototype.slice()`

Extracts a section of a string and returns a new string.

`String.prototype.split()`

 Returns an array of strings populated by splitting the calling string at occurrences
 of the substring `sep`.

`String.prototype.startsWith()`

 Determines whether the calling string begins with the characters of string
 `searchString`.

`String.prototype.substr()`
Deprecated

Returns a portion of the string, starting at the specified index and extending for a given number of characters afterwards.

`String.prototype.substring()`

 Returns a new string containing characters of the calling string from (or between)
 the specified index (or indices).

`String.prototype.toLocaleLowerCase()`

 The characters within a string are converted to lowercase while respecting the
 current locale.

 For most languages, this will return the same as
 `toLowerCase()`.

`String.prototype.toLocaleUpperCase()`

 The characters within a string are converted to uppercase while respecting the
 current locale.

 For most languages, this will return the same as
 `toUpperCase()`.

`String.prototype.toLowerCase()`

Returns the calling string value converted to lowercase.

`String.prototype.toString()`

 Returns a string representing the specified object. Overrides the
 `Object.prototype.toString()` method.

`String.prototype.toUpperCase()`

Returns the calling string value converted to uppercase.

`String.prototype.toWellFormed()`

Returns a string where all lone surrogates of this string are replaced with the Unicode replacement character U+FFFD.

`String.prototype.trim()`

Trims whitespace from the beginning and end of the string.

`String.prototype.trimEnd()`

Trims whitespace from the end of the string.

`String.prototype.trimStart()`

Trims whitespace from the beginning of the string.

`String.prototype.valueOf()`

 Returns the primitive value of the specified object. Overrides the
 `Object.prototype.valueOf()` method.

`String.prototype[@@iterator]()`

 Returns a new iterator object that iterates over the code points of a String value,
 returning each code point as a String value.

### HTML wrapper methods

**Warning:** Deprecated. Avoid these methods.

They are of limited use, as they are based on a very old HTML standard and provide only a subset of the currently available HTML tags and attributes. Many of them create deprecated or non-standard markup today. In addition, they do simple string concatenation without any validation or sanitation, which makes them a potential security threat when directly inserted using `innerHTML`. Use DOM APIs such as `document.createElement()` instead.

`String.prototype.anchor()`
Deprecated

`<a name="name">` (hypertext target)

`String.prototype.big()`
Deprecated

`<big>`
`String.prototype.blink()`
Deprecated

`<blink>`

`String.prototype.bold()`
Deprecated

`<b>`
`String.prototype.fixed()`
Deprecated

`<tt>`
`String.prototype.fontcolor()`
Deprecated

`<font color="color">`

`String.prototype.fontsize()`
Deprecated

`<font size="size">`

`String.prototype.italics()`
Deprecated

`<i>`
`String.prototype.link()`
Deprecated

`<a href="url">` (link to URL)

`String.prototype.small()`
Deprecated

`<small>`
`String.prototype.strike()`
Deprecated

`<strike>`
`String.prototype.sub()`
Deprecated

`<sub>`
`String.prototype.sup()`
Deprecated

`<sup>`

Note that these methods do not check if the string itself contains HTML tags, so it's possible to create invalid HTML:

```js
"".bold(); //
```

The only escaping they do is to replace `"` in the attribute value (for `anchor()`, `fontcolor()`, `fontsize()`, and `link()`) with `"`.

```js
"foo".anchor('"Hello"'); // foo
```

Examples
--------

### String conversion

The `String()` function is a more reliable way of converting values to strings than calling the `toString()` method of the value, as the former works when used on `null` and `undefined`. For example:

```js
// You cannot access properties on null or undefined

const nullVar = null;
nullVar.toString(); // TypeError: Cannot read properties of null
String(nullVar); // "null"

const undefinedVar = undefined;
undefinedVar.toString(); // TypeError: Cannot read properties of undefined
String(undefinedVar); // "undefined"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-string-objects |

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

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

See also
--------

* Text formatting guide
* `RegExp`


Float32Array - JavaScript

Float32Array
============

The **`Float32Array`** typed array represents an array of 32-bit floating point numbers in the platform byte order. If control over byte order is needed, use `DataView` instead. The contents are initialized to `0`. Once established, you can reference elements in the array using the object's methods, or using standard array index syntax (that is, using bracket notation).

`Float32Array` is a subclass of the hidden `TypedArray` class.

Constructor
-----------

`Float32Array()`

Creates a new `Float32Array` object.

Static properties
-----------------

*Also inherits static properties from its parent `TypedArray`*.

`Float32Array.BYTES_PER_ELEMENT`

Returns a number value of the element size. `4` in the case of `Float32Array`.

Static methods
--------------

*Inherits static methods from its parent `TypedArray`*.

Instance properties
-------------------

*Also inherits instance properties from its parent `TypedArray`*.

These properties are defined on `Float32Array.prototype` and shared by all `Float32Array` instances.

`Float32Array.prototype.BYTES_PER_ELEMENT`

Returns a number value of the element size. `4` in the case of a `Float32Array`.

`Float32Array.prototype.constructor`

The constructor function that created the instance object. For `Float32Array` instances, the initial value is the `Float32Array` constructor.

Instance methods
----------------

*Inherits instance methods from its parent `TypedArray`*.

Examples
--------

### Different ways to create a Float32Array

```js
// From a length
const float32 = new Float32Array(2);
float32[0] = 42;
console.log(float32[0]); // 42
console.log(float32.length); // 2
console.log(float32.BYTES\_PER\_ELEMENT); // 4

// From an array
const x = new Float32Array([21, 31]);
console.log(x[1]); // 31

// From another TypedArray
const y = new Float32Array(x);
console.log(y[0]); // 21

// From an ArrayBuffer
const buffer = new ArrayBuffer(32);
const z = new Float32Array(buffer, 4, 4);
console.log(z.byteOffset); // 4

// From an iterable
const iterable = (function\* () {
  yield\* [1, 2, 3];
})();
const float32FromIterable = new Float32Array(iterable);
console.log(float32FromIterable);
// Float32Array [1, 2, 3]
```

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

| Specification |
| --- |
| ECMAScript Language Specification # table-49 |

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

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

See also
--------

* Polyfill of `Float32Array` in `core-js`
* JavaScript typed arrays guide
* `TypedArray`
* `ArrayBuffer`
* `DataView`


SharedArrayBuffer - JavaScript

SharedArrayBuffer
=================

The **`SharedArrayBuffer`** object is used to represent a generic raw binary data buffer, similar to the `ArrayBuffer` object, but in a way that they can be used to create views on shared memory. A `SharedArrayBuffer` is not a Transferable Object, unlike an `ArrayBuffer` which is transferable.

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

To share memory using `SharedArrayBuffer` objects from one agent in the cluster to another (an agent is either the web page's main program or one of its web workers), `postMessage` and structured cloning is used.

The structured clone algorithm accepts `SharedArrayBuffer` objects and typed arrays mapped onto `SharedArrayBuffer` objects. In both cases, the `SharedArrayBuffer` object is transmitted to the receiver resulting in a new, private `SharedArrayBuffer` object in the receiving agent (just as for `ArrayBuffer`). However, the shared data block referenced by the two `SharedArrayBuffer` objects is the same data block, and a side effect to the block in one agent will eventually become visible in the other agent.

```js
const sab = new SharedArrayBuffer(1024);
worker.postMessage(sab);
```

Shared memory can be created and updated simultaneously in workers or the main thread. Depending on the system (the CPU, the OS, the Browser) it can take a while until the change is propagated to all contexts. To synchronize, atomic operations are needed.

`SharedArrayBuffer` objects are used by some web APIs, such as:

* `WebGLRenderingContext.bufferData()`
* `WebGLRenderingContext.bufferSubData()`
* `WebGL2RenderingContext.getBufferSubData()`
### Security requirements

Shared memory and high-resolution timers were effectively disabled at the start of 2018 in light of Spectre. In 2020, a new, secure approach has been standardized to re-enable shared memory.

As a baseline requirement, your document needs to be in a secure context.

For top-level documents, two headers need to be set to cross-origin isolate your site:

* `Cross-Origin-Opener-Policy` with `same-origin` as value (protects your origin from attackers)
* `Cross-Origin-Embedder-Policy` with `require-corp` or `credentialless` as value (protects victims from your origin)

```http
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
```

To check if cross origin isolation has been successful, you can test against the `crossOriginIsolated` property available to window and worker contexts:

```js
const myWorker = new Worker("worker.js");

if (crossOriginIsolated) {
  const buffer = new SharedArrayBuffer(16);
  myWorker.postMessage(buffer);
} else {
  const buffer = new ArrayBuffer(16);
  myWorker.postMessage(buffer);
}
```

With these two headers set, `postMessage()` no longer throws for `SharedArrayBuffer` objects and shared memory across threads is therefore available.

Nested documents and dedicated workers need to set the `Cross-Origin-Embedder-Policy` header as well, with the same value. No further changes are needed for same-origin nested documents and subresources. Same-site (but cross-origin) nested documents and subresources need to set the `Cross-Origin-Resource-Policy` header with `same-site` as value. And their cross-origin (and cross-site) counterparts need to set the same header with `cross-origin` as value. Note that setting the `Cross-Origin-Resource-Policy` header to any other value than `same-origin` opens up the resource to potential attacks, such as Spectre.

Note that the `Cross-Origin-Opener-Policy` header limits your ability to retain a reference to popups. Direct access between two top-level window contexts essentially only work if they are same-origin and carry the same two headers with the same two values.

### API availability

Depending on whether the above security measures are taken, the various memory-sharing APIs have different availabilities:

* The `Atomics` object is always available.
* `SharedArrayBuffer` objects are in principle always available, but unfortunately the constructor on the global object is hidden, unless the two headers mentioned above are set, for compatibility with web content. There is hope that this restriction can be removed in the future. `WebAssembly.Memory` can still be used to get an instance.
* Unless the two headers mentioned above are set, the various `postMessage()` APIs will throw for `SharedArrayBuffer` objects. If they are set, `postMessage()` on `Window` objects and dedicated workers will function and allow for memory sharing.
### WebAssembly shared memory

`WebAssembly.Memory` objects can be created with the `shared` constructor flag. When this flag is set to `true`, the constructed `Memory` object can be shared between workers via `postMessage()`, just like `SharedArrayBuffer`, and the backing `buffer` of the `Memory` object is a `SharedArrayBuffer`. Therefore, the requirements listed above for sharing a `SharedArrayBuffer` between workers also apply to sharing a `WebAssembly.Memory`.

The WebAssembly Threads proposal also defines a new set of atomic instructions. Just as `SharedArrayBuffer` and its methods are unconditionally enabled (and only sharing between threads is gated on the new headers), the WebAssembly atomic instructions are also unconditionally allowed.

### Growing SharedArrayBuffers

`SharedArrayBuffer` objects can be made growable by including the `maxByteLength` option when calling the `SharedArrayBuffer()` constructor. You can query whether a `SharedArrayBuffer` is growable and what its maximum size is by accessing its `growable` and `maxByteLength` properties, respectively. You can assign a new size to a growable `SharedArrayBuffer` with a `grow()` call. New bytes are initialized to 0.

These features make growing `SharedArrayBuffer`s more efficient — otherwise, you have to make a copy of the buffer with a new size. It also gives JavaScript parity with WebAssembly in this regard (Wasm linear memory can be resized with `WebAssembly.Memory.prototype.grow()`).

For security reasons, `SharedArrayBuffer`s cannot be reduced in size, only grown.

Constructor
-----------

`SharedArrayBuffer()`

Creates a new `SharedArrayBuffer` object.

Static properties
-----------------

`SharedArrayBuffer[@@species]`

Returns the constructor used to construct return values from `SharedArrayBuffer` methods.

Instance properties
-------------------

These properties are defined on `SharedArrayBuffer.prototype` and shared by all `SharedArrayBuffer` instances.

`SharedArrayBuffer.prototype.byteLength`

The size, in bytes, of the array. This is established when the array is constructed and can only be changed using the `SharedArrayBuffer.prototype.grow()` method if the `SharedArrayBuffer` is growable.

`SharedArrayBuffer.prototype.constructor`

The constructor function that created the instance object. For `SharedArrayBuffer` instances, the initial value is the `SharedArrayBuffer` constructor.

`SharedArrayBuffer.prototype.growable`

Read-only. Returns `true` if the `SharedArrayBuffer` can be grown, or `false` if not.

`SharedArrayBuffer.prototype.maxByteLength`

The read-only maximum length, in bytes, that the `SharedArrayBuffer` can be grown to. This is established when the array is constructed and cannot be changed.

`SharedArrayBuffer.prototype[@@toStringTag]`

The initial value of the `@@toStringTag` property is the string `"SharedArrayBuffer"`. This property is used in `Object.prototype.toString()`.

Instance methods
----------------

`SharedArrayBuffer.prototype.grow()`

Grows the `SharedArrayBuffer` to the specified size, in bytes.

`SharedArrayBuffer.prototype.slice()`

Returns a new `SharedArrayBuffer` whose contents are a copy of this `SharedArrayBuffer`'s bytes from `begin`, inclusive, up to `end`, exclusive. If either `begin` or `end` is negative, it refers to an index from the end of the array, as opposed to from the beginning.

Examples
--------

### Creating a new SharedArrayBuffer

```js
const sab = new SharedArrayBuffer(1024);
```

### Slicing the SharedArrayBuffer

```js
sab.slice(); // SharedArrayBuffer { byteLength: 1024 }
sab.slice(2); // SharedArrayBuffer { byteLength: 1022 }
sab.slice(-2); // SharedArrayBuffer { byteLength: 2 }
sab.slice(0, 1); // SharedArrayBuffer { byteLength: 1 }
```

### Using it in a WebGL buffer

```js
const canvas = document.querySelector("canvas");
const gl = canvas.getContext("webgl");
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY\_BUFFER, buffer);
gl.bufferData(gl.ARRAY\_BUFFER, sab, gl.STATIC\_DRAW);
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-sharedarraybuffer-objects |

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

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

See also
--------

* `Atomics`
* `ArrayBuffer`
* JavaScript typed arrays guide
* Web Workers
* Shared Memory – a brief tutorial in the TC39 ecmascript-sharedmem proposal
* A Taste of JavaScript's New Parallel Primitives on hacks.mozilla.org (2016)
* COOP and COEP explained by the Chrome team (2020)
* `Cross-Origin-Opener-Policy`
* `Cross-Origin-Embedder-Policy`
* `Cross-Origin-Resource-Policy`
* `crossOriginIsolated`
* SharedArrayBuffer updates in Android Chrome 88 and Desktop Chrome 92 on developer.chrome.com (2021)


eval() - JavaScript

eval()
======

**Warning:** Executing JavaScript from a string is an enormous security risk. It is far too easy for a bad actor to run arbitrary code when you use `eval()`. See Never use eval()!, below.

The **`eval()`** function evaluates JavaScript code represented as a string and returns its completion value. The source is parsed as a script.

Try it
------

Syntax
------

```js
eval(script)
```

### Parameters

`script`

A string representing a JavaScript expression, statement, or sequence of statements. The expression can include variables and properties of existing objects. It will be parsed as a script, so `import` declarations (which can only exist in modules) are not allowed.

### Return value

The completion value of evaluating the given code. If the completion value is empty, `undefined` is returned. If `script` is not a string primitive, `eval()` returns the argument unchanged.

### Exceptions

Throws any exception that occurs during evaluation of the code, including `SyntaxError` if `script` fails to be parsed as a script.

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

`eval()` is a function property of the global object.

The argument of the `eval()` function is a string. It will evaluate the source string as a script body, which means both statements and expressions are allowed. It returns the completion value of the code. For expressions, it's the value the expression evaluates to. Many statements and declarations have completion values as well, but the result may be surprising (for example, the completion value of an assignment is the assigned value, but the completion value of `let` is undefined), so it's recommended to not rely on statements' completion values.

In strict mode, declaring a variable named `eval` or re-assigning `eval` is a `SyntaxError`.

```js
"use strict";

const eval = 1; // SyntaxError: Unexpected eval or arguments in strict mode
```

If the argument of `eval()` is not a string, `eval()` returns the argument unchanged. In the following example, passing a `String` object instead of a primitive causes `eval()` to return the `String` object rather than evaluating the string.

```js
eval(new String("2 + 2")); // returns a String object containing "2 + 2"
eval("2 + 2"); // returns 4
```

To work around the issue in a generic fashion, you can coerce the argument to a string yourself before passing it to `eval()`.

```js
const expression = new String("2 + 2");
eval(String(expression)); // returns 4
```

### Direct and indirect eval

There are two modes of `eval()` calls: *direct* eval and *indirect* eval. Direct eval, as the name implies, refers to *directly* calling the global `eval` function with `eval(...)`. Everything else, including invoking it via an aliased variable, via a member access or other expression, or through the optional chaining `?.` operator, is indirect.

```js
// Direct call
eval("x + y");

// Indirect call using the comma operator to return eval
(0, eval)("x + y");

// Indirect call through optional chaining
eval?.("x + y");

// Indirect call using a variable to store and return eval
const geval = eval;
geval("x + y");

// Indirect call through member access
const obj = { eval };
obj.eval("x + y");
```

Indirect eval can be seen as if the code is evaluated within a separate `<script>` tag. This means:

* Indirect eval works in the global scope rather than the local scope, and the code being evaluated doesn't have access to local variables within the scope where it's being called.

```js
function test() {
  const x = 2;
  const y = 4;
  // Direct call, uses local scope
  console.log(eval("x + y")); // Result is 6
  console.log(eval?.("x + y")); // Uses global scope, throws because x is undefined
}
```

* Indirect `eval` would not inherit the strictness of the surrounding context, and would only be in strict mode if the source string itself has a `"use strict"` directive.

```js
function strictContext() {
  "use strict";
  eval?.(`with (Math) console.log(PI);`);
}
function strictContextStrictEval() {
  "use strict";
  eval?.(`"use strict"; with (Math) console.log(PI);`);
}
strictContext(); // Logs 3.141592653589793
strictContextStrictEval(); // Throws a SyntaxError because the source string is in strict mode
```

On the other hand, direct eval inherits the strictness of the invoking context.

```js
function nonStrictContext() {
  eval(`with (Math) console.log(PI);`);
}
function strictContext() {
  "use strict";
  eval(`with (Math) console.log(PI);`);
}
nonStrictContext(); // Logs 3.141592653589793
strictContext(); // Throws a SyntaxError because it's in strict mode
```

* `var`-declared variables and function declarations would go into the surrounding scope if the source string is not interpreted in strict mode — for indirect eval, they become global variables. If it's a direct eval in a strict mode context, or if the `eval` source string itself is in strict mode, then `var` and function declarations do not "leak" into the surrounding scope.

```js
// Neither context nor source string is strict,
// so var creates a variable in the surrounding scope
eval("var a = 1;");
console.log(a); // 1
// Context is not strict, but eval source is strict,
// so b is scoped to the evaluated script
eval("'use strict'; var b = 1;");
console.log(b); // ReferenceError: b is not defined

function strictContext() {
  "use strict";
  // Context is strict, but this is indirect and the source
  // string is not strict, so c is still global
  eval?.("var c = 1;");
  // Direct eval in a strict context, so d is scoped
  eval("var d = 1;");
}
strictContext();
console.log(c); // 1
console.log(d); // ReferenceError: d is not defined
```

`let` and `const` declarations within the evaluated string are always scoped to that script.
* Direct eval may have access to additional contextual expressions. For example, in a function's body, one can use `new.target`:

```js
function Ctor() {
  eval("console.log(new.target)");
}
new Ctor(); // [Function: Ctor]
```

### Never use eval()!

Using direct `eval()` suffers from multiple problems:

* `eval()` executes the code it's passed with the privileges of the caller. If you run `eval()` with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, allowing third-party code to access the scope in which `eval()` was invoked (if it's a direct eval) can lead to possible attacks that reads or changes local variables.
* `eval()` is slower than the alternatives, since it has to invoke the JavaScript interpreter, while many other constructs are optimized by modern JS engines.
* Modern JavaScript interpreters convert JavaScript to machine code. This means that any concept of variable naming gets obliterated. Thus, any use of `eval()` will force the browser to do long expensive variable name lookups to figure out where the variable exists in the machine code and set its value. Additionally, new things can be introduced to that variable through `eval()`, such as changing the type of that variable, forcing the browser to re-evaluate all of the generated machine code to compensate.
* Minifiers give up on any minification if the scope is transitively depended on by `eval()`, because otherwise `eval()` cannot read the correct variable at runtime.

There are many cases where the use of `eval()` or related methods can be optimized or avoided altogether.

#### Using indirect eval()

Consider this code:

```js
function looseJsonParse(obj) {
  return eval(`(${obj})`);
}
console.log(looseJsonParse("{ a: 4 - 1, b: function () {}, c: new Date() }"));
```

Simply using indirect eval and forcing strict mode can make the code much better:

```js
function looseJsonParse(obj) {
  return eval?.(`"use strict";(${obj})`);
}
console.log(looseJsonParse("{ a: 4 - 1, b: function () {}, c: new Date() }"));
```

The two code snippets above may seem to work the same way, but they do not; the first one using direct eval suffers from multiple problems.

* It is a great deal slower, due to more scope inspections. Notice `c: new Date()` in the evaluated string. In the indirect eval version, the object is being evaluated in the global scope, so it is safe for the interpreter to assume that `Date` refers to the global `Date()` constructor instead of a local variable called `Date`. However, in the code using direct eval, the interpreter cannot assume this. For example, in the following code, `Date` in the evaluated string doesn't refer to `window.Date()`.

```js
function looseJsonParse(obj) {
  function Date() {}
  return eval(`(${obj})`);
}
console.log(looseJsonParse(`{ a: 4 - 1, b: function () {}, c: new Date() }`));
```

Thus, in the `eval()` version of the code, the browser is forced to make the expensive lookup call to check to see if there are any local variables called `Date()`.
* If not using strict mode, `var` declarations within the `eval()` source becomes variables in the surrounding scope. This leads to hard-to-debug issues if the string is acquired from external input, especially if there's an existing variable with the same name.
* Direct eval can read and mutate bindings in the surrounding scope, which may lead to external input corrupting local data.
* When using direct `eval`, especially when the eval source cannot be proven to be in strict mode, the engine — and build tools — have to disable all optimizations related to inlining, because the `eval()` source can depend on any variable name in its surrounding scope.

However, using indirect `eval()` does not allow passing extra bindings other than existing global variables for the evaluated source to read. If you need to specify additional variables that the evaluated source should have access to, consider using the `Function()` constructor.

#### Using the Function() constructor

The `Function()` constructor is very similar to the indirect eval example above: it also evaluates the JavaScript source passed to it in the global scope without reading or mutating any local bindings, and therefore allows engines to do more optimizations than direct `eval()`.

The difference between `eval()` and `Function()` is that the source string passed to `Function()` is parsed as a function body, not as a script. There are a few nuances — for example, you can use `return` statements at the top level of a function body, but not in a script.

The `Function()` constructor is useful if you wish to create local bindings within your eval source, by passing the variables as parameter bindings.

```js
function Date(n) {
  return [
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
    "Sunday",
  ][n % 7 || 0];
}
function runCodeWithDateFunction(obj) {
  return Function("Date", `"use strict";return (${obj});`)(Date);
}
console.log(runCodeWithDateFunction("Date(5)")); // Saturday
```

Both `eval()` and `Function()` implicitly evaluate arbitrary code, and are forbidden in strict CSP settings. There are also additional safer (and faster!) alternatives to `eval()` or `Function()` for common use-cases.

#### Using bracket accessors

You should not use `eval()` to access properties dynamically. Consider the following example where the property of the object to be accessed is not known until the code is executed. This can be done with `eval()`:

```js
const obj = { a: 20, b: 30 };
const propName = getPropName(); // returns "a" or "b"

const result = eval(`obj.${propName}`);
```

However, `eval()` is not necessary here — in fact, it's more error-prone, because if `propName` is not a valid identifier, it leads to a syntax error. Moreover, if `getPropName` is not a function you control, this may lead to execution of arbitrary code. Instead, use the property accessors, which are much faster and safer:

```js
const obj = { a: 20, b: 30 };
const propName = getPropName(); // returns "a" or "b"
const result = obj[propName]; // obj["a"] is the same as obj.a
```

You can even use this method to access descendant properties. Using `eval()`, this would look like:

```js
const obj = { a: { b: { c: 0 } } };
const propPath = getPropPath(); // suppose it returns "a.b.c"

const result = eval(`obj.${propPath}`); // 0
```

Avoiding `eval()` here could be done by splitting the property path and looping through the different properties:

```js
function getDescendantProp(obj, desc) {
  const arr = desc.split(".");
  while (arr.length) {
    obj = obj[arr.shift()];
  }
  return obj;
}

const obj = { a: { b: { c: 0 } } };
const propPath = getPropPath(); // suppose it returns "a.b.c"
const result = getDescendantProp(obj, propPath); // 0
```

Setting a property that way works similarly:

```js
function setDescendantProp(obj, desc, value) {
  const arr = desc.split(".");
  while (arr.length > 1) {
    obj = obj[arr.shift()];
  }
  return (obj[arr[0]] = value);
}

const obj = { a: { b: { c: 0 } } };
const propPath = getPropPath(); // suppose it returns "a.b.c"
const result = setDescendantProp(obj, propPath, 1); // obj.a.b.c is now 1
```

However, beware that using bracket accessors with unconstrained input is not safe either — it may lead to object injection attacks.

#### Using callbacks

JavaScript has first-class functions, which means you can pass functions as arguments to other APIs, store them in variables and objects' properties, and so on. Many DOM APIs are designed with this in mind, so you can (and should) write:

```js
// Instead of setTimeout("…", 1000) use:
setTimeout(() => {
  // …
}, 1000);

// Instead of elt.setAttribute("onclick", "…") use:
elt.addEventListener("click", () => {
  // …
});
```

Closures are also helpful as a way to create parameterized functions without concatenating strings.

#### Using JSON

If the string you're calling `eval()` on contains data (for example, an array: `"[1, 2, 3]"`), as opposed to code, you should consider switching to JSON, which allows the string to use a subset of JavaScript syntax to represent data.

Note that since JSON syntax is limited compared to JavaScript syntax, many valid JavaScript literals will not parse as JSON. For example, trailing commas are not allowed in JSON, and property names (keys) in object literals must be enclosed in quotes. Be sure to use a JSON serializer to generate strings that will be later parsed as JSON.

Passing carefully constrained data instead of arbitrary code is a good idea in general. For example, an extension designed to scrape contents of web-pages could have the scraping rules defined in XPath instead of JavaScript code.

Examples
--------

### Using eval()

 In the following code, both of the statements containing `eval()` return 42.
 The first evaluates the string `"x + y + 1"`; the second evaluates the string
 `"42"`.

```js
const x = 2;
const y = 39;
const z = "42";
eval("x + y + 1"); // 42
eval(z); // 42
```

### eval() returns the completion value of statements

`eval()` returns the completion value of statements. For `if`, it would be the last expression or statement evaluated.

```js
const str = "if (a) { 1 + 1 } else { 1 + 2 }";
let a = true;
let b = eval(str);

console.log(`b is: ${b}`); // b is: 2

a = false;
b = eval(str);

console.log(`b is: ${b}`); // b is: 3
```

The following example uses `eval()` to evaluate the string `str`. This string consists of JavaScript statements that assign `z` a value of 42 if `x` is five, and assign 0 to `z` otherwise. When the second statement is executed, `eval()` will cause these statements to be performed, and it will also evaluate the set of statements and return the value that is assigned to `z`, because the completion value of an assignment is the assigned value.

```js
const x = 5;
const str = `if (x === 5) {
 console.log("z is 42");
 z = 42;
} else {
 z = 0;
}`;

console.log("z is ", eval(str)); // z is 42 z is 42
```

If you assign multiple values then the last value is returned.

```js
let x = 5;
const str = `if (x === 5) {
 console.log("z is 42");
 z = 42;
 x = 420;
} else {
 z = 0;
}`;

console.log("x is", eval(str)); // z is 42 x is 420
```

### eval() as a string defining function requires "(" and ")" as prefix and suffix

```js
// This is a function declaration
const fctStr1 = "function a() {}";
// This is a function expression
const fctStr2 = "(function b() {})";
const fct1 = eval(fctStr1); // return undefined, but `a` is available as a global function now
const fct2 = eval(fctStr2); // return the function `b`
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-eval-x |

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

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

See also
--------

* Property accessors
* WebExtensions: Using eval in content scripts