--- title: Variables chapter: Variables --- Variables are declared with the `var` keyword. JavaScript is _dynamically typed_ so every variable can hold a value of any data type. Variables can be declared _without an initial value_. Some example declarations: ```javascript var foo; var bar = 42; var foo, bar, baz; var foo = 42, bar = 'baz', z; ``` Variables that don't explicitly get assigned an initial value have the value `undefined`.
**ES2015** Since ES2015, `let` and `const` can be used in addition to `var`. We will learn how they differ from `var` later. For now, lets have a look how `const` differs from `var` or `let`: `const` can be assigned a value only _once_ (*const*ant). Reassigning a value will either throw an error (in strict mode, see below) or is silently ignored: ```js const foo = 42; foo = 21; // error or ignored ``` `const`s _must_ be initialized with a value: ```js const foo; // error foo = 42; ```
--- ## Variable names Valid characters for variable names include [a wide range of _unicode characters_](http://mathiasbynens.be/notes/javascript-identifiers). However, the name _must_ start with a letter, `_` or `$`. Not doing so will result in a syntax error. Examples: ```javascript var π = 3.141; var _foo = π; var 0_bar = '...'; // Syntax error ``` --- ## Variable access Trying to _read_ an _undeclared variable_ results in a runtime error: ```javascript var foo; console.log(bar); // ReferenceError: bar is not defined. ``` However, _writing_ to an undeclared variable is valid by default. It will create an _implicit global variable_ and should thus be avoided: ```javascript function foo() { bar = 42; } foo(); console.log(bar); // no error ```
If code runs in _[strict mode][]_, assigning to an undeclared variable throws an _error_.
### Strict mode [Strict mode][] is a mode of evaluating JavaScript that enforces stricter rules. It was introduced to "deprecate" certain patterns/behaviors that are considered bad or confusing. Strict mode can be enabled for a JavaScript or a function by putting ```js 'use strict'; ``` at the beginning of it.
[strict mode]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode --- title: Scope chapter: Scope --- Unlike other programming languages, JavaScript only has **function scope**, not block scope. In the following example, all variables are visible throughout the function: ```javascript function foo() { var bar = 42; // loop for (var i = 0; i < 10; i++) { var j = i; } console.log(bar); // 42 console.log(i); // 10 console.log(j); // 9 } ``` In other languages, like Java, the variables `i` or `j` would not be available where the above code tries to access them.
**ES2015** The big difference between `let`, `const`, and `var` is that `let` and `const` are _[block scoped][block scope]_. If we would use `let` instead of `var` in the above example, we would get the following result: ```javascript function foo() { let bar = 42; // or var or const, doesn't matter // loop for (let i = 0; i < 10; i++) { // i is scoped to the loop body block let j = i; // j is scoped to the loop body block } console.log(bar); // 42 console.log(i); // ReferenceError console.log(j); // ReferneceError } ``` --- toc: What is this? chapter: this style: | h1 { text-align: center } --- # What is `this`? [**`this`**][mdn] is a special "variable" which implicitly exists in every function. It can be thought of being similar to Java's `this` and Python's `self`, but it's much more flexible than that.
**Important**: The value of `this` is determined when the function is **called**, not when the function is _defined_.
Given the following function: ```javascript function foo() { console.log(this); } ``` these would be the values of `this` if called in those specific ways: ```javascript // "normal call": global object / window in browsers // undefined in strict mode foo(); // as object "method": to the object var obj = { method: foo }; obj.method(); // via .call / .apply: To the value passed as first argument foo.call(bar); ``` [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this --- title: JavaScript Basics toc: Title chapter: Intro layout: Center style: | .exerslide-slide .Center-wrapper { text-align: left; } .exerslide-slide h1 { color: #444; font-size: 400%; margin-bottom: 50px; text-align: center; } scale: content_width: 39 column_width: 0.6 --- A quick introduction to basic and important concepts of JavaScript Use the arrow keys (**←, →**) to navigate through the page. You should use Google Chrome and make yourself familiar with the [developer tools][], especially with the console. You will need it for the exercises. --- ## Contribute Found a problem with style or content? Or do you have suggestions for improving the content? Please [file an issue on GitHub][jsbasics-issues]. --- title: Booleans, numbers and strings --- The **Boolean** data type has two values, `true` and `false`. ```js var foo = true; var bar = false; ``` --- **Numbers** are [double precision floating point][float] numbers, following the [IEEE 754 standard][ieee754] This makes it very easy to work with them, since you don't have to differentiate between integer values and floating point values. There are various ways that numeric value can be expressed: ```javascript var x = 5; // "integer" var y = -4.2; // "float" var z = 5e3; // = 5 * 10^3 ``` An issue with floating point numbers is the loss of precision, which of course occurs in JavaScript as well: ```javascript 0.1 + 0.2; // 0.30000000000000004 ``` The maximum integer value that can be used without loss of precision is 253. ```javascript Math.pow(2, 53); // 9007199254740992 Math.pow(2, 53) + 1; // 9007199254740992 ``` --- **Strings** are sequences of unicode characters and can either be delimited with a **single** or **double** quotation mark. Unlike in other languages, such as PHP, both are interpreted in the exact same way. Example: ```javascript var foo = 'bar'; var bar = 'baz'; ``` [float]: http://en.wikipedia.org/wiki/Double-precision_floating-point_format [ieee754]: http://en.wikipedia.org/wiki/IEEE_floating_point --- title: Demo layout_data: description: Run the code and have a look at the output. Is it what you expect? Try some other values / operators and look at the output (remember to open the console). --- var a = 10; var b = 5; var c = "1"; log(a + b); log(a + c); log(b + Number(c)); --- title: Constructor functions chapter: Constructors/Classes --- JavaScript doesn't have classes like class-based OOP languages have, but it has something similar: _constructor functions_. Constructor functions are functions which _construct objects_. Technically _every_ function can be used as a constructor function, it just has to be called with the [`new` operator][new]: ```javascript function Person(name) { this.name = name; } var felix = new Person('Felix'); console.log(felix.name); ``` Inside the constructor function, `this` refers to a new, empty object. The result of the whole `new` expression (`new Person(...)`) is that object. You can think about it as if the function would implicitly `return this;`. Calling a function with `new` has another effect: The prototype of the new object is the object referred to by the function's `prototype` property. Example: ```javascript function Person(name) { this.name = name; } Person.prototype.sayName = function () { return this.name; }; var felix = new Person('Felix'); console.log(felix.sayName()); ``` Given the example above, use `console.dir(felix);` to get a better understanding of the structure of the object (including it's prototype chain). [new]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new --- title: Exercise layout_data: description: | Create a local variable with name `foo` and value `42`. Use `log(foo)` to log the value of `foo`. Remember to open your browser's *developer tools* to view the log output. assertion: | assert( /var foo\s*=.+;?$/m.test(source), "It doesn't look like you have declared a variable (hint: var)." ); assert(output[0] === 42, "Don't forget to log the value"); --- // Create variable // log(foo); --- title: Hoisting --- This behavior becomes more understandable after we introduce **hoisting**. Before a JavaScript function is even executed, the engine finds all variable and function declarations and creates a binding for them in the functions scope. Thus, the example of the previous slide is equivalent to the following: ```javascript function foo() { var bar, i, j; bar = 42; // loop for (i = 0; i < 10; i++) { j = i; } console.log(bar); // 42 console.log(i); // 10 console.log(j); // 9 } ``` Note how all variable declarations are put at the top of the function. The _value_ will still be assigned only when the execution reaches the line of the assignment expression. One of the practical implications of the hoisting concept is _mutually recursive functions_. Consider the following example: ```javascript function isEven(n) { if (n == 0) { return true; } return isOdd(n - 1); } // Normally may call `isEven` even though it's mutually // dependent on the `isOdd` which is defined below. console.log(isEven(2)); // true function isOdd(n) { if (n == 0) { return false; } return isEven(n - 1); } ``` To get more details on hoisting see [this article][hoisting]. [hoisting]: http://dmitrysoshnikov.com/notes/note-4-two-words-about-hoisting/ --- toc: this - an example style: | h1 { text-align: center } --- # `this` - an example ```javascript function say() { console.log('My name is ' + this.name); } var felix = { name: 'Felix', sayName: say }; var sarah = { name: 'Sarah', sayName: say }; felix.sayName(); // My name is Felix sarah.sayName(); // My name is Sarah say.call({ name: 'Anonymous' }); // My name is Anonymous say(); // My names is undefined ``` In this example we define a single function that uses `this` internally. The function is then assigned to different objects as property. The output the function produces depends on which object the function is called (_how_ it is called). --- title: What this presentation is not about layout: Center style: | .exerslide-slide .Center-wrapper { text-align: left; } .exerslide-slide h1 { text-align: center; } --- JavaScript is predominantly run in browsers to make websites interactive. In order to do that, the browser provides access to other technologies, such as [CSS][] and the [DOM][]. This presentation is exclusively about JavaScript, the _language_, not the environment in which the JavaScript code runs! --- title: Exercise layout_data: description: Create three variables `x`, `y`, `z`, where `x` contains a string value, `y` a number and `z` a boolean value. Log the values with `log`. assertion: | assert( output.some(function(x) { return typeof x === 'string' }), 'Your log must contain a string.' ); assert( output.some(function(x) { return typeof x === 'number' }), 'Your log must contain a number.' ); assert( output.some(function(x) { return typeof x === 'boolean' }), 'Your log must contain a boolean.' ); --- // Hint: You can pass multiple arguments to log: // log(a, b) --- toc: "ES6's class declarations" --- # Syntactic sugar: ES6's `class` declarations Setting up more complex constructor functions with their prototypes can be cumbersome. For that reason ES2015 [introduced a new syntax][classes]. With the syntax, the example from the previous slide would look like ```javascript class Person { constructor(name) { this.name = name; } sayName() { return name; } } var felix = new Person('Felix'); ```
I want to be very clear that this is mostly just _syntactic sugar_. While there are some differences between `class` declarations and constructor functions + prototype, the underlying paradigm (prototypes) does not change.
[classes]: http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes --- title: Comparison operators --- As already established at the beginning, JavaScript is _dynamically typed_. It also performs _type conversion_, if a specific data type is expected and not provided. For example in `a * b`, the values of `a` and `b` will be converted to numbers first. Even though there are [well defined rules][conversion rules] for converting one data type into another, these rules can be quite surprising. [conversion rules]: http://www.ecma-international.org/ecma-262/5.1/#sec-9 What does this have to do with comparison? JavaScript has two kind of comparison operators: - **Loose comparison** (`a == b`, `a != b`) - **Strict comparison** (`a === b`, `a !== b`) The difference is that _loose_ comparison will _convert both values_ to the same data type if they are of different data types. _Strict_ comparison immediately returns `false` if both values _don't have the same type_. Examples: ```javascript '42' == 42; // true (('42' === (42)[ // false // Objects are compared by reference (1, 2) ]) == [1, 2][(1, 2)]) === // false [1, 2]; // false ``` The following tool visualizes the steps of the _[abstract equality comparison](http://www.ecma-international.org/ecma-262/7.0/#sec-abstract-equality-comparison)_ algorithm, which is used for loose comparison. You can select some predefined examples and see which steps are performed during the comparison. The results will probably surprise you. You can also provide your own values. ```react comparison [ ["[1,2]", "'1,2'"], ["[0]", "false"], ["'\\n'", "false"], ["'0XA19'", "2585"] ] ``` Also have a look at [this table][comparison table] to get a quick overview of the differences between `==` and `===`. The above examples hopefully showed you that loose comparison isn't that "simple" and it's not always clear what ends up being compared in the end. For that reason you should follow this advice:
**You should _always_ use strict comparison**, unless you explicitly want to make use of the type conversion (i.e. you know what you are doing). If you write an API, make it clear which data type it expects (e.g. through comments).
[comparison table]: https://dorey.github.io/JavaScript-Equality-Table/ --- title: ES5, ES2015 and beyond layout: Center style: | .exerslide-slide .Center-wrapper { text-align: left; } .exerslide-slide h1 { text-align: center; } --- This tutorial primarily focuses on JavaScript following the [ECMAScript 5][es5] (ES5) specification. [ES2015][] (also known as ES6) was released in 2015 and brings many new features to the language, including new syntax constructs. While this tutorial won't go into detail about new features in ES2015 and newer versions, it will point differences to/alternatives for certain ES5 features if they exist. --- title: Demo layout_data: description: Which value does this code log and why? Think about the answer *before* you run the code. --- var bar = 42; function foo() { log(bar); var bar = 21; log(bar); } foo(); --- title: Exercise layout_data: description: Which value does the code log and why? How can it be changed to log the value of `obj.foo`? assertion: | assert(output[0] === 42, 'The code should only log 42'); assert(/log\s*\(\s*this\.foo\s*\)/.test(source), "Looks like you tried to be clever. Don't modify log(this.foo)."); --- var obj = { foo: 42, bar: function () { log(this.foo); } }; var foo = obj.bar; foo(); --- title: Closures --- [Wikipedia describes closures as][closures]: > In programming languages, a closure (also lexical closure or function closure) > is a function or reference to a function together with a referencing environment > — a table storing a reference to each of the non-local variables (also called > free variables or upvalues) of that function. According to this definition, **every** function in JavaScript is a closure, because [every function has an (internal) reference to the environment][functions] it was created in. The simplest example is: ```javascript var foo = 42; function bar() { console.log(foo); } ``` Here the function `bar` has access to `foo`, which is defined outside of it.
**Important**: The value of a free variable is determined when the function is **executed**, not when the function is _defined_. Read the previous sentence three times to make sure you really understand what it implies.
[closures]: http://en.wikipedia.org/wiki/Closure_%28computer_programming%29 [functions]: http://www.ecma-international.org/ecma-262/5.1/#sec-13 --- title: Exercise layout_data: description: Run the code and have a look at the output. Is it what you expect? What are reasons for this output? Modify the code, so that it prints the result you would expect. assertion: | var values = [" ", "0", 0]; var c = 1; for (var i = 0, l = values.length; i < l; i++) { for (var j = i; j < l; j++) { var expectedResult = values[i] === values[j]; assert( expectedResult === output[c], 'Comparing ' + JSON.stringify(values[i]) + ' and ' + JSON.stringify(values[j]) + ' should yield ' + expectedResult.toString() + ' not ' + output[c] ); c += 2; } } --- var values = [" ", "0", 0]; for (var i = 0, l = values.length; i < l; i++) { for (var j = i; j < l; j++) { log( JSON.stringify(values[i]) + ' == ' + JSON.stringify(values[j]) + ': ', values[i] == values[j] ); } } --- title: null and undefined --- JavaScript has two data types to express the **absence of a value**, null and undefined. **null** has the only value `null` and **undefined** has the only value `undefined`. The difference between those two is subtle and is best explained by how to use them: - `undefined` is the value JavaScript itself uses to indicate the absence of a value. - `null` is the value the engineer should use to indicate the absence of a value. Examples: ```javascript var foo; // no value is assigned, foo has the value undefined var bar = null; // bar is explicitly set to null console.log(foo); // logs "undefined" console.log(bar); // logs "null" ``` There are other native occurrence of `undefined` which we will mention later.
**Remember:** A variable that doesn't exist cannot be accessed at all (it will throw a reference error). Instead of saying "the variable is undefined" we rather say "the variable is not _declared_" to avoid confusion. ```js var foo; console.log(foo); // logs `undefined` console.log(bar); // reference error ```
--- title: Demo layout_data: description: Which value does this code log and why? Think about the solution *before* you run the code. --- var foo = 42; function bar() { log(foo); } foo = 21; bar(); --- title: Exercise layout_data: description: Which values does this code log and why? Modify the code so that it logs the values as "expected". assertion: assert( output.every(function(x, i) { return x === i; }), 'The code should output the loop variable of each iteration, i.e. 0, 1, 2' ); --- var functionArray = []; for (var i = 0; i < 3; i++) { functionArray[i] = function() { log(i); }; } for (var j = 0; j < 3; j++) { functionArray[j](); } --- title: Exercise layout_data: description: Log the values `null` and `undefined`. assertion: | assert( output.some(function(x) { return x === null }), 'Your log must contain null.' ); assert( output.some(function(x) { return x === void 0; }), 'Your log must contain undefined.' ); assert( source.indexOf('undefined') === -1, 'Try to log undefined without writing it in the source code.' ); --- --- title: Property access --- Properties of objects can be accessed in two ways: - **Dot notation** (`obj.prop`) - **Bracket notation** (`obj["prop"]`) You should always prefer dot notation, unless you _have_ to use bracket notation. This could be if the property name is not a valid identifier or if it comes from a variable. You can use any _expression_ inside the brackets. Examples: ```javascript obj['test-field']; // test-field is not a valid identifier var field = 'test'; obj[field]; obj['example' + i]; ``` Because you can only use dot notation if the property name is a valid identifier name, array objects can only be accessed via bracket notation, `arr[0]`, not dot notation, `a.0`. --- You can **assign to properties** by putting the member expression on the left hand side of an assignment expression: ```javascript obj.prop = value; ``` --- If you have nested objects/arrays, you simply use a valid property accessor repeatedly: ```javascript var obj = { foo: { bar: [42, 21] } }; console.log(obj.foo.bar[0]); // which is evaluated as ((obj.foo).bar)[0] ``` --- Accessing a non existing property does not throw an error, it returns `undefined`: ```javascript var obj = {}; console.log(obj.foo); ``` --- title: Objects --- Everything else besides primitive data type values is an _object_. Objects are _key-value_ stores, more specifically _stringkey-value_ stores. The "keys" of an object are called _properties_. The syntax to create a plain object is `{key: value, ...}`, which is called an object literal. For example: ```javascript var obj = { foo: 'bar', baz: 42 }; ``` Note that the above example doesn't use _quotation marks_ around the property names. In an object literal, quotation marks can be be omitted if the property name would also be a _valid variable name_. If not, they need to be quoted. _Number literals_ are valid an object literal as well. Here are some more examples of valid and invalid property names in object literals: ```js var obj = { foo: 0, // valid, could be variable name 'bar': 0, // string literals are always valid 123: 0, // number literals are always valid 1.5: 0, // ^ foo-bar: 0, // invalid, would not be a valid variable name 'foo-bar': 0, // string literals are alwaus valid }; ```
**Important:** No matter which value or syntax you use for a property name, the value will always be converted to a **string**.
**ES2015** ES2015 adds two extensions to object values and object literals: - _Symbols_ are can be used as property names. They are not converted to strings. - Object literals can contain _[computed property names][computed properties]_: ```js var foo = 42; var obj = { [foo]: 0 }; // creates {42: 0} ```
## References Just like in Java and other object-oriented programming languages, objects are represented as _references_. That means if a variable has an object as a value, it really has a reference to that object. ```js var user = {name: 'Tom'}: ``` :::ascii ``` ┌──────────────┐ ┌─────┬──────────┐ │ Object#123 │ │user │ ref:123 ◆┼──────▶├──────┬───────┤ └─────┴──────────┘ │ name │ "Tom" │ └──────┴───────┘ ``` ::: Assigning the value to another variable makes both variables point to the same object: ```js var owner = user; ``` :::ascii ``` ┌─────┬──────────┐ ┌──────────────┐ │user │ ref:123 ◆┼──┐ │ Object#123 │ ├─────┼──────────┤ ├───▶├──────┬───────┤ │owner│ ref:123 ◆┼──┘ │ name │ "Tom" │ └─────┴──────────┘ └──────┴───────┘ ``` ::: Assigning to `user.name` will therefore also "change" `owner.name`: ```js user.name = 'Joe'; console.log(user.name, owner.name); // Joe, Joe ``` :::ascii ``` ┌─────┬──────────┐ ┌──────────────┐ │user │ ref:123 ◆┼──┐ │ Object#123 │ ├─────┼──────────┤ ├───▶├──────┬───────┤ │owner│ ref:123 ◆┼──┘ │ name │ "Joe" │ └─────┴──────────┘ └──────┴───────┘ ``` ::: But assigning a new value to either `user` or `owner` will result in only that variable referring to the new value. The other variable will still refer to the same value. ```js owner = { name: 'Kim' }; ``` :::ascii ``` ┌──────────────┐ │ Object#123 │ ┌───▶├──────┬───────┤ ┌─────┬──────────┐ │ │ name │ "Joe" │ │user │ ref:123 ◆┼──┘ └──────┴───────┘ ├─────┼──────────┤ │owner│ ref:456 ◆┼──┐ ┌──────────────┐ └─────┴──────────┘ │ │ Object#456 │ └───▶├──────┬───────┤ │ name │ "Kim" │ └──────┴───────┘ ``` ::: --- The JavaScript standard defines a couple of [built-in objects][] with additional properties and special internal behavior, must notably _arrays_ and _functions_, which are explained in the next slides. [built-in objects]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects --- title: Exercise layout_data: description: Log the two properties of the object using dot and bracket notation. assertion: assert( source.indexOf('obj.foo') > -1, 'Access property foo with dot notation' ); assert( /obj\[(42|'42'|"42")\]/.test(source), 'How exactly did you want to access property 42?' ); --- var obj = {foo: 'bar', 42: 'answer'}; --- title: Prototypes (1) --- You may have heard that JavaScript is a _"[prototype-based language][prototype]"_, unlike other languages, such as Java, which are _"[class-based languages][class]"_. ## What exactly is a prototype? In short: A prototype is just another object. If an object `A` has this special connection to object `B`, then we say that "`B` is the prototype of `A`". In addition to having "external" properties that can be accessed from code, objects also have _internal/private_ properties/state. These cannot be accessed from code and their concrete implementation depends on the JavaScript engine. Every object has an _internal_ property `[[Prototype]]` (internal properties are usually denoted with `[[...]]` around the name). This property points to another object. :::ascii ``` ┌───────────────────────┐ ┌────────────────────────┐ │ A │ │ B │ ├───────────────┬───────┤ ├───────────────┬────────┤ │ name │ "Tom" │ ┌──▶│ toString │ │ ├───────────────┼───────┤ │ ├───────────────┼────────┤ │ [[Prototype]] │ ◆───┼───┘ │ [[Prototype]] │ null │ └───────────────┴───────┘ └───────────────┴────────┘ ``` ::: Multiple objects can have the same prototype. :::ascii ``` ┌───────────────────────┐ ┌────────────────────────┐ │ A │ │ B │ ├───────────────┬───────┤ ├───────────────┬────────┤ │ name │ "Tom" │ ┌──▶│ toString │ │ ├───────────────┼───────┤ │ ├───────────────┼────────┤ │ [[Prototype]] │ ◆───┼───┘ │ [[Prototype]] │ null │ └───────────────┴───────┘ └───────────────┴────────┘ ▲ ┌───────────────────────┐ │ │ C │ │ ├───────────────┬───────┤ │ │ time │ "day" │ │ ├───────────────┼───────┤ │ │ [[Prototype]] │ ◆───┼────────────────────┘ └───────────────┴───────┘ ``` ::: Since a prototype is an object, it might itself have a prototype, which may have a prototype, and so forth. :::ascii ``` ┌───────────────────┐ │ A │ ├───────────────┬───┤ │ [[Prototype]] │ ◆─┼────┐ └───────────────┴───┘ │ ▼ ┌───────────────────┐ │ B │ ├───────────────┬───┤ │ [[Prototype]] │ ◆─┼────┐ └───────────────┴───┘ │ ▼ ┌───────────────────┐ │ C │ ├───────────────┬───┤ │ [[Prototype]] │ ◆─│─ ─ ─ ▷ └───────────────┴───┘ ``` ::: This is called the _prototype chain_. Almost all objects have the same object at the end of the prototype chain, which doesn't have a prototype itself. An object created using literal notation will have the object `Object.prototype` as its prototype. You can verify this using the following commands: ```js var testObject = {}; Object.getPrototypeOf(testObject) === Object.prototype; // true ``` :::ascii ``` ┌────────────────────────┐ ┌───────────────────┐ │ Object.prototype │ │ testObject │ ├───────────────┬────────┤ ├───────────────┬───┤ │ toString │ │ │ [[Prototype]] │ ◆─┼──────▶├───────────────┼────────┤ └───────────────┴───┘ │ hasOwnProperty│ │ ├───────────────┼────────┤ │ [[Prototype]] │ null │ └───────────────┴────────┘ ``` ::: In order to create an object with an object other than `Object.prototype` as prototype, one can use [`Object.create`][object.create]: ```js var a = {}; var b = Object.create(a); Object.getPrototypeOf(b) === a; // true ``` [prototype]: https://en.wikipedia.org/wiki/Prototype-based_programming [class]: https://en.wikipedia.org/wiki/Class-based_programming [object.create]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create --- title: Prototypes (2) --- Now we know what prototypes are, but not what they _do_ or which problem they solve. ## What does a prototype do? Prototypes come in play when we are accessing the property of an object.
Whenver an object property is accessed, the object and its prototype chain are traversed until the property is found. If the end of the prototype chain is reached without finding the property, `undefined` is returned.
Consider the following structure: :::ascii ``` ┌───────────────────────┐ │ a │ ├───────────────┬───────┤ │ name │ "Tom" │ ├───────────────┼───────┤ │ [[Prototype]] │ ◆───┼───┐ └───────────────┴───────┘ │ ▼ ┌───────────────────────┐ │ b │ ├───────────────┬───────┤ │ name │ "Joe" │ ├───────────────┼───────┤ │ age │ 42 │ ├───────────────┼───────┤ │ [[Prototype]] │ ◆───┼───┐ └───────────────┴───────┘ │ ▼ ┌───────────────────────┐ │ c │ ├───────────────┬───────┤ │ height │ 180 │ ├───────────────┼───────┤ │ [[Prototype]] │ null │ └───────────────┴───────┘ ``` ::: These are the results for accessing different properties on A: ```js a.name; // Tom `a` itself has this property, it shadows `b.name` a.age; // 42 `a`'s prototype has this property a.height; // 180 `a`'s prototype's prototype has this property a.eyeColor; // undefined this property doesn't exist ``` --- This is also the reason why we can access `.toString()` on almost every object: It is defined in `Object.prototype`, which sits at the end of every prototype chain. ```js var user = { name: 'Tom' }; user.toString(); // "[object Object]" ```
**Note**: _Assignments_ to properties will (almost) always create or update a property on object itself, even if a property with the same name already exists in the prototype chain. The property in the prototype chain is then _shadowed_, similar to variable shadowing in scopes.
--- title: 'Built-in objects: Arrays and functions' --- ## Arrays Arrays are objects, which treat properties with numeric keys (i.e. `0`, `1`, `2`, ...) in a special way. For all purposes, they behave like arrays in other languages. JavaScript has a special syntax for creating arrays, `[value, value, ...]`: ```javascript var arr = [1, 2]; ``` If you run `console.dir([1, 2])` in your browser's console, you can inspect the structure of the array object in more detail. Unlike "plain" objects, array objects have `Array.prototype` as prototype, which provides all the array methods, such as `.push`, `.map`, etc. :::ascii ``` ┌──────────┐ [[Prototype]] ┌──────────────────┐ │ obj {} │───────────────────────────▶│ Object.prototype │ └──────────┘ └──────────────────┘ ▲ │ [[Prototype]] │ ┌──────────┐ [[Prototype]] ┌─────────────────┐ │ │ arr [] │───────────────▶│ Array.prototype │───┘ └──────────┘ └─────────────────┘ ``` ::: --- ## Functions Functions are the only kind of objects that are _callable_, and JavaScript also has a special syntax for defining them: ```javascript function foo() { console.log("I'm a function"); } ``` There are other ways to create functions, which will be explained later.
The most important implication of functions being objects is that "work" just like any other value. Functions can be _passed to_ functions and _returned from_ functions, allowing to creation of **higher-order functions**.
Similar to arrays, function objects also have a dedicated prototype, `Function.prototype`: :::ascii ``` ┌──────────┐ [[Prototype]] ┌──────────────────┐ │ obj {} │───────────────────────────────▶│ Object.prototype │ └──────────┘ └──────────────────┘ ▲ ▲ │ │ [[Prototype]] │ ┌──────────┐ [[Prototype]] ┌─────────────────┐ │ │ │ arr [] │───────────────▶│ Array.prototype │─┘ │ └──────────┘ └─────────────────┘ [[Prototype]] │ │ ┌──────────────────┐ [[Prototype]] ┌──────────────────┐ │ │func function(){} │───────────────▶│Function.prototype│──┘ └──────────────────┘ └──────────────────┘ ``` ::: --- title: Control structures --- JavaScript provides the same control structures known from other C-like languages: - `if (...) { ... } else if (...) { ... } else { ... }` - `while (...) { ... }` and `do { ... } while (...)` - `for (...; ...; ...) { ... }` - `switch (...) { case ...: ... }` Additionally, JavaScript provides the `for...in` loop to iterate over properties of objects: ```javascript for (var prop in obj) { console.log(prop, obj[prop]); } ``` `prop` is a variable containing the property _name_. You can use bracket notation to access the property values.
**ES2015** ES2015 introduces [`for/of`][forof] statements for iterating over _[iterables][]_: ```js var arr = [1, 2, 3]; for (var v of arr) { console.log(v); } // 1 // 2 // 3 ```
--- title: Demo layout_data: description: Run this code and look at the output. Do you notice anything unexpected? If yes, why do you think this is the case? --- var obj = {foo: 0, bar: 1, 42: 2}; for (var prop in obj) { log('property: ' + prop, 'value: ' + obj[prop]); } --- title: Exercise layout_data: description: | Log two value: an object which has a property `foo` and a value `"bar"`, and an array with the values `1`, `2` and `42`. assertion: | assert( output.some(function(x) { return JSON.stringify(x) === JSON.stringify({foo: 'bar'}); }), 'Your log must contain an object with property "foo" and value "bar". Hint: `{key: value}`.' ); assert( output.some(function(x) { return JSON.stringify(x) === JSON.stringify([1, 2, 42]); }), 'Your log must contain an array with values 1, 2 and 42. Hint: `[value, ...]`.' ); --- --- title: Resources --- - [MDN JavaScript Guide][mdn], [Eloquent JavaScript][eloquent] — basic JavaScript introduction. - [You don't know JS][ydkjs] — another JavaScript introduction, more focus on advanced concepts and technical details - [ECMAScript 5 specification][ecma] — only if you _really_ like JavaScript. - [ECMAScript 2015 specification][es2015] - [quirksmode.org - JavaScript][quirksmode] — basic introduction and excellent explanation of event handling. - [Learning Advanced JavaScript][lajs] — "strange" JavaScript concepts explored. - [jsFiddle][] — an online "editor" to quickly prototype JavaScript examples (with HTML, CSS and a selection of JS libraries). - [Learn how to **debug** JavaScript][debug] — knowing how to debug a program written in a specific language is as as important as knowing the language itself. [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide [eloquent]: http://eloquentjavascript.net/ [ydkjs]: https://github.com/getify/You-Dont-Know-JS [quirksmode]: http://quirksmode.org/js/contents.html [lajs]: http://ejohn.org/apps/learn/ [ecma]: http://www.ecma-international.org/ecma-262/5.1/ [jsfiddle]: http://jsfiddle.net/ [debug]: https://developers.google.com/chrome-developer-tools/docs/javascript-debugging --- title: Function definitions --- There are two syntactic constructs to create functions: function **declaration** and function **expressions**. **Function declarations** start with the `function` keyword followed by a **name**, the parameter list and the function body: ```javascript function foo(a, b, c) { // do something } ``` **Function expressions** have the same structure, but their name is optional: ```javascript var foo = function (a, b, c) { // do something }; ```
Note: Since functions are objects, they can be treated like any other value. They can be assigned to variables, passed to other functions and returned from functions. The code above is just an assignment expression with a function as value.
All function objects created either way behave exactly the same. Whether the parser treats a function definition as declaration or expression depends on where the definition is placed. If it is an expression context, it is interpreted as an expression, otherwise as a declaration. That's why ```javascript function () { } ``` generates an error (function declaration without name), but ```javascript (function () {}); ``` does not, because the grouping operator (`(...)`) can only contain expressions. --- title: Function Calls --- Like other C-like languages, functions are called by putting `()` after the function reference: ```javascript myFunction(); ``` Unlike other languages, functions can be called with any number of arguments, no matter how many formal parameters they have: ```javascript function myFunction(foo, bar) { console.log(foo, bar); } myFunction(); // undefined undefined myFunction(1); // 1 undefined myFunction(1, 2); // 1 2 myFunction(1, 2, 3); // 1 2 ``` Each function has access to the special [`arguments`][arguments] variable, which is an _array-like_ value. This allows you to access all the arguments passed to a function, even if there are more than formal parameters: ```javascript function myFunction(foo, bar) { console.log(foo, bar, arguments); } myFunction(); // undefined undefined [] myFunction(1); // 1 undefined [1] myFunction(1, 2); // 1 2 [1, 2] myFunction(1, 2, 3); // 1 2 [1, 2, 3] ``` [arguments]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments title: Insert item inside an Array tip-number: 00 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel tip-tldr: Inserting an item into an existing array is a daily common task. You can add elements to the end of an array using push, to the beginning using unshift, or to the middle using splice. tip-writer-support: https://www.coinbase.com/loverajoel - /en/insert-item-inside-an-array/ # Inserting an item into an existing array Inserting an item into an existing array is a daily common task. You can add elements to the end of an array using push, to the beginning using unshift, or to the middle using splice. Those are known methods, but it doesn't mean there isn't a more performant way. Here we go: ## Adding an element at the end Adding an element at the end of the array is easy with push(), but it can be done in different ways. ```javascript var arr = [1, 2, 3, 4, 5]; var arr2 = []; arr.push(6); arr[arr.length] = 6; arr2 = arr.concat([6]); ``` Both first methods modify the original array. Don't believe me? Check the [jsperf](http://jsperf.com/push-item-inside-an-array) ### Performance on mobile : #### Android (v4.2.2) 1. _arr.push(6);_ and _arr[arr.length] = 6;_ have the same performance // 3 319 694 ops/sec 2. _arr2 = arr.concat([6]);_ 50.61 % slower than the other two methods #### Chrome Mobile (v33.0.0) 1. _arr[arr.length] = 6;_ // 6 125 975 ops/sec 2. _arr.push(6);_ 66.74 % slower 3. _arr2 = arr.concat([6]);_ 87.63 % slower #### Safari Mobile (v9) 1. _arr[arr.length] = 6;_ // 7 452 898 ops/sec 2. _arr.push(6);_ 40.19 % slower 3. _arr2 = arr.concat([6]);_ 49.78 % slower ```javascript Final victor 1. arr[arr.length] = 6; // with an average of 5 632 856 ops/sec 2. arr.push(6); // 35.64 % slower 3. arr2 = arr.concat([6]); // 62.67 % slower ``` ### Performance on desktop #### Chrome (v48.0.2564) 1. _arr[arr.length] = 6;_ // 21 602 722 ops/sec 2. _arr.push(6);_ 61.94 % slower 3. _arr2 = arr.concat([6]);_ 87.45 % slower #### Firefox (v44) 1. _arr.push(6);_ // 56 032 805 ops/sec 2. _arr[arr.length] = 6;_ 0.52 % slower 3. _arr2 = arr.concat([6]);_ 87.36 % slower #### IE (v11) 1. _arr[arr.length] = 6;_ // 67 197 046 ops/sec 2. _arr.push(6);_ 39.61 % slower 3. _arr2 = arr.concat([6]);_ 93.41 % slower #### Opera (v35.0.2066.68) 1. _arr[arr.length] = 6;_ // 30 775 071 ops/sec 2. _arr.push(6);_ 71.60 % slower 3. _arr2 = arr.concat([6]);_ 83.70 % slower #### Safari (v9.0.3) 1. _arr.push(6);_ // 42 670 978 ops/sec 2. _arr[arr.length] = 6;_ 0.80 % slower 3. _arr2 = arr.concat([6]);_ 76.07 % slower ```javascript Final victor 1. arr[arr.length] = 6; // with an average of 42 345 449 ops/sec 2. arr.push(6); // 34.66 % slower 3. arr2 = arr.concat([6]); // 85.79 % slower ``` ## Add an element at the beginning Now if we are trying to add an item to the beginning of the array: ```javascript var arr = [1, 2, 3, 4, 5]; arr.unshift(0); [0].concat(arr); ``` Here is a little more detail: unshift edits the original array; concat returns a new array. [jsperf](http://jsperf.com/unshift-item-inside-an-array) ### Performance on mobile : #### Android (v4.2.2) 1. _[0].concat(arr);_ // 1 808 717 ops/sec 2. _arr.unshift(0);_ 97.85 % slower #### Chrome Mobile (v33.0.0) 1. _[0].concat(arr);_ // 1 269 498 ops/sec 2. _arr.unshift(0);_ 99.86 % slower #### Safari Mobile (v9) 1. _arr.unshift(0);_ // 3 250 184 ops/sec 2. _[0].concat(arr);_ 33.67 % slower ```javascript Final victor 1. [0].concat(arr); // with an average of 4 972 622 ops/sec 2. arr.unshift(0); // 64.70 % slower ``` ### Performance on desktop #### Chrome (v48.0.2564) 1. _[0].concat(arr);_ // 2 656 685 ops/sec 2. _arr.unshift(0);_ 96.77 % slower #### Firefox (v44) 1. _[0].concat(arr);_ // 8 039 759 ops/sec 2. _arr.unshift(0);_ 99.72 % slower #### IE (v11) 1. _[0].concat(arr);_ // 3 604 226 ops/sec 2. _arr.unshift(0);_ 98.31 % slower #### Opera (v35.0.2066.68) 1. _[0].concat(arr);_ // 4 102 128 ops/sec 2. _arr.unshift(0);_ 97.44 % slower #### Safari (v9.0.3) 1. _arr.unshift(0);_ // 12 356 477 ops/sec 2. _[0].concat(arr);_ 15.17 % slower ```javascript Final victor 1. [0].concat(arr); // with an average of 6 032 573 ops/sec 2. arr.unshift(0); // 78.65 % slower ``` ## Add an element in the middle Adding items in the middle of an array is easy with splice, and it's the most performant way to do it. ```javascript var items = ['one', 'two', 'three', 'four']; items.splice(items.length / 2, 0, 'hello'); ``` I tried to run these tests in various Browsers and OS and the results were similar. I hope these tips will be useful for you and encourage to perform your own tests! title: Improve Nested Conditionals tip-number: 03 tip-username: AlbertoFuente tip-username-profile: https://github.com/AlbertoFuente tip-tldr: How can we improve and make a more efficient nested `if` statement in javascript? - /en/improve-nested-conditionals/ How can we improve and make a more efficient nested `if` statement in javascript? ```javascript if (color) { if (color === 'black') { printBlackBackground(); } else if (color === 'red') { printRedBackground(); } else if (color === 'blue') { printBlueBackground(); } else if (color === 'green') { printGreenBackground(); } else { printYellowBackground(); } } ``` One way to improve the nested `if` statement would be using the `switch` statement. Although it is less verbose and is more ordered, it's not recommended to use it because it's so difficult to debug errors. Here's [why](https://toddmotto.com/deprecating-the-switch-statement-for-object-literals). ```javascript switch (color) { case 'black': printBlackBackground(); break; case 'red': printRedBackground(); break; case 'blue': printBlueBackground(); break; case 'green': printGreenBackground(); break; default: printYellowBackground(); } ``` But what if we have a conditional with several checks in each statement? In this case, if we want it less verbose and more ordered, we can use the conditional `switch`. If we pass `true` as a parameter to the `switch` statement, it allows us to put a conditional in each case. ```javascript switch (true) { case typeof color === 'string' && color === 'black': printBlackBackground(); break; case typeof color === 'string' && color === 'red': printRedBackground(); break; case typeof color === 'string' && color === 'blue': printBlueBackground(); break; case typeof color === 'string' && color === 'green': printGreenBackground(); break; case typeof color === 'string' && color === 'yellow': printYellowBackground(); break; } ``` If refactoring is an option, we can try to simplify the functions themselves. For example instead of having a function for each background color we could have an function that takes the color as an argument. ```javascript function printBackground(color) { if (!color || typeof color !== 'string') { return; // Invalid color, return immediately } } ``` But if refactoring is not an option, we must always avoid having several checks in every condition and avoid using `switch` as much as possible. We also must take into account that the most efficient way to do this is through an `object`. ```javascript var colorObj = { black: printBlackBackground, red: printRedBackground, blue: printBlueBackground, green: printGreenBackground, yellow: printYellowBackground }; if (color in colorObj) { colorObj[color](); } ``` Here you can find more information about [this](http://www.nicoespeon.com/en/2015/01/oop-revisited-switch-in-js/). title: Sorting strings with accented characters tip-number: 04 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel tip-tldr: Javascript has a native method **sort** that allows sorting arrays. Doing a simple `array.sort()` will treat each array entry as a string and sort it alphabetically. But when you try order an array of non ASCII characters you will obtain a strange result. tip-writer-support: https://www.coinbase.com/loverajoel - /en/sorting-strings-with-accented-characters/ Javascript has a native method **[sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)** that allows sorting arrays. Doing a simple `array.sort()` will treat each array entry as a string and sort it alphabetically. Also you can provide your [own custom sorting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Parameters) function. ```javascript ['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort(); // ["Buenos Aires", "Mumbai", "New York", "Shanghai"] ``` But when you try order an array of non ASCII characters like this `['é', 'a', 'ú', 'c']`, you will obtain a strange result `['c', 'e', 'á', 'ú']`. That happens because sort works only with the English language. See the next example: ```javascript // Spanish ['único', 'árbol', 'cosas', 'fútbol'].sort(); // ["cosas", "fútbol", "árbol", "único"] // bad order // German ['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(); // ["Wann", "Woche", "wäre", "wöchentlich"] // bad order ``` Fortunately, there are two ways to overcome this behavior [localeCompare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) and [Intl.Collator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator) provided by ECMAScript Internationalization API. > Both methods have their own custom parameters in order to configure it to work adequately. ### Using `localeCompare()` ```javascript ['único', 'árbol', 'cosas', 'fútbol'].sort(function (a, b) { return a.localeCompare(b); }); // ["árbol", "cosas", "fútbol", "único"] ['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(function (a, b) { return a.localeCompare(b); }); // ["Wann", "wäre", "Woche", "wöchentlich"] ``` ### Using `Intl.Collator()` ```javascript ['único', 'árbol', 'cosas', 'fútbol'].sort(Intl.Collator().compare); // ["árbol", "cosas", "fútbol", "único"] ['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(Intl.Collator().compare); // ["Wann", "wäre", "Woche", "wöchentlich"] ``` - For each method you can customize the location. - According to [Firefox](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare#Performance) Intl.Collator is faster when comparing large numbers of strings. So when you are working with arrays of strings in a language other than English, remember to use this method to avoid unexpected sorting. title: Differences between `undefined` and `null` tip-number: 05 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel tip-tldr: Understanding the differences between `undefined` and `null`. tip-writer-support: https://www.coinbase.com/loverajoel - /en/differences-between-undefined-and-null/ - `undefined` means a variable has not been declared, or has been declared but has not yet been assigned a value - `null` is an assignment value that means "no value" - Javascript sets unassigned variables with a default value of `undefined` - Javascript never sets a value to `null`. It is used by programmers to indicate that a `var` has no value. - `undefined` is not valid in JSON while `null` is - `undefined` typeof is `undefined` - `null` typeof is an `object`. [Why?](http://www.2ality.com/2013/10/typeof-null.html) - Both are primitives - Both are [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) (`Boolean(undefined) // false`, `Boolean(null) // false`) - You can know if a variable is [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined) ```javascript typeof variable === 'undefined'; ``` ```` - You can check if a variable is [null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null) ```javascript variable === null ```` - The **equality** operator considers them equal, but the **identity** doesn't ```javascript null == undefined; // true null === undefined; // false ``` ``` ``` title: Writing a single method for arrays and a single element tip-number: 06 tip-username: mattfxyz tip-username-profile: https://twitter.com/mattfxyz tip-tldr: Rather than writing separate methods to handle an array and a single element parameter, write your functions so they can handle both. This is similar to how some of jQuery's functions work (`css` will modify everything matched by the selector). - /en/writing-a-single-method-for-arrays-and-a-single-element/ Rather than writing separate methods to handle an array and a single element parameter, write your functions so they can handle both. This is similar to how some of jQuery's functions work (`css` will modify everything matched by the selector). You just have to concat everything into an array first. `Array.concat` will accept an array or a single element. ```javascript function printUpperCase(words) { var elements = [].concat(words || []); for (var i = 0; i < elements.length; i++) { console.log(elements[i].toUpperCase()); } } ``` `printUpperCase` is now ready to accept a single node or an array of nodes as its parameter. It also avoids the potential `TypeError` that would be thrown if no parameter was passed. ```javascript printUpperCase('cactus'); // => CACTUS printUpperCase(['cactus', 'bear', 'potato']); // => CACTUS // BEAR // POTATO ``` title: use strict and get lazy tip-number: 07 tip-username: nainslie tip-username-profile: https://twitter.com/nat5an tip-tldr: Strict-mode JavaScript makes it easier for the developer to write "secure" JavaScript. - /en/use-strict-and-get-lazy/ Strict-mode JavaScript makes it easier for the developer to write "secure" JavaScript. By default, JavaScript allows the programmer to be pretty careless, for example, by not requiring us to declare our variables with "var" when we first introduce them. While this may seem like a convenience to the unseasoned developer, it's also the source of many errors when a variable name is misspelled or accidentally referred to out of its scope. Programmers like to make the computer do the boring stuff for us, and automatically check our work for mistakes. That's what the JavaScript "use strict" directive allows us to do, by turning our mistakes into JavaScript errors. We add this directive either by adding it at the top of a js file: ```javascript // Whole-script strict mode syntax 'use strict'; var v = "Hi! I'm a strict mode script!"; ``` or inside a function: ```javascript function f() { // Function-level strict mode syntax 'use strict'; function nested() { return 'And so am I!'; } return "Hi! I'm a strict mode function! " + nested(); } function f2() { return "I'm not strict."; } ``` By including this directive in a JavaScript file or function, we will direct the JavaScript engine to execute in strict mode which disables a bunch of behaviors that are usually undesirable in larger JavaScript projects. Among other things, strict mode changes the following behaviors: - Variables can only be introduced when they are preceded with "var" - Attempting to write to read-only properties generates a noisy error - You have to call constructors with the "new" keyword - "this" is not implicitly bound to the global object - Very limited use of eval() allowed - Protects you from using reserved words or future reserved words as variable names Strict mode is great for new projects, but can be challenging to introduce into older projects that don't already use it in most places. It also can be problematic if your build chain concatenates all your js files into one big file, as this may cause all files to execute in strict mode. It is not a statement, but a literal expression, ignored by earlier versions of JavaScript. Strict mode is supported in: - Internet Explorer from version 10. - Firefox from version 4. - Chrome from version 13. - Safari from version 5.1. - Opera from version 12. [See MDN for a fuller description of strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode). title: Converting a Node List to an Array tip-number: 08 tip-username: Tevko tip-username-profile: https://twitter.com/tevko tip-tldr: Here's a quick, safe, and reusable way to convert a node list into an array of DOM elements. - /en/converting-a-node-list-to-an-array/ The `querySelectorAll` method returns an array-like object called a node list. These data structures are referred to as "Array-like", because they appear as an array, but can not be used with array methods like `map` and `forEach`. Here's a quick, safe, and reusable way to convert a node list into an array of DOM elements: ```javascript const nodelist = document.querySelectorAll('div'); const nodelistToArray = Array.apply(null, nodelist); //later on .. nodelistToArray.forEach(...); nodelistToArray.map(...); nodelistToArray.slice(...); //etc... ``` The `apply` method is used to pass an array of arguments to a function with a given `this` value. [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) states that `apply` will take an array-like object, which is exactly what `querySelectorAll` returns. Since we don't need to specify a value for `this` in the context of the function, we pass in `null` or `0`. The result is an actual array of DOM elements which contains all of the available array methods. Alternatively you can use `Array.prototype.slice` combined with `Function.prototype.call` or `Function.prototype.apply` passing the array-like object as the value of `this`: ```javascript const nodelist = document.querySelectorAll('div'); const nodelistToArray = Array.prototype.slice.call(nodelist); // or equivalently Array.prototype.slice.apply(nodelist); //later on .. nodelistToArray.forEach(...); nodelistToArray.map(...); nodelistToArray.slice(...); //etc... ``` Or if you are using ES2015 you can use the [spread operator `...`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) ```js const nodelist = [...document.querySelectorAll('div')]; // returns a real array //later on .. nodelist.forEach(...); nodelist.map(...); nodelist.slice(...); //etc... ``` title: Template Strings tip-number: 09 tip-username: JakeRawr tip-username-profile: https://github.com/JakeRawr tip-tldr: As of ES6, JS now has template strings as an alternative to the classic end quotes strings. - /en/template-strings/ As of ES6, JS now has template strings as an alternative to the classic end quotes strings. Ex: Normal string ```javascript var firstName = 'Jake'; var lastName = 'Rawr'; console.log('My name is ' + firstName + ' ' + lastName); // My name is Jake Rawr ``` Template String ```javascript var firstName = 'Jake'; var lastName = 'Rawr'; console.log(`My name is ${firstName} ${lastName}`); // My name is Jake Rawr ``` You can do multi-line strings without `\n`, perform simple logic (ie 2+3) or even use the [ternary operator](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) inside `${}` in template strings. ```javascript var val1 = 1, val2 = 2; console.log(`${val1} is ${val1 < val2 ? 'less than' : 'greater than'} ${val2}`); // 1 is less than 2 ``` You are also able to modify the output of template strings using a function; they are called [tagged template strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings#Tagged_template_strings) for example usages of tagged template strings. You may also want to [read](https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2) to understand template strings more. title: Check if a property is in a Object tip-number: 10 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: These are ways to check if a property is present in an object. tip-writer-support: https://www.coinbase.com/loverajoel - /en/check-if-a-property-is-in-a-object/ When you have to check if a property is present in an [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects), you probably are doing something like this: ```javascript var myObject = { name: '@tips_js' }; if (myObject.name) { ... } ``` That's ok, but you have to know that there are two native ways for this kind of thing, the [`in` operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in) and [`Object.hasOwnProperty`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty). Every object descended from `Object`, has both ways available. ### See the big Difference ```javascript var myObject = { name: '@tips_js' }; myObject.hasOwnProperty('name'); // true 'name' in myObject; // true myObject.hasOwnProperty('valueOf'); // false, valueOf is inherited from the prototype chain 'valueOf' in myObject; // true ``` Both differ in the depth at which they check the properties. In other words, `hasOwnProperty` will only return true if key is available on that object directly. However, the `in` operator doesn't discriminate between properties created on an object and properties inherited from the prototype chain. Here's another example: ```javascript var myFunc = function () { this.name = '@tips_js'; }; myFunc.prototype.age = '10 days'; var user = new myFunc(); user.hasOwnProperty('name'); // true user.hasOwnProperty('age'); // false, because age is from the prototype chain ``` Check the [live examples here](https://jsbin.com/tecoqa/edit?js,console)! I also recommend reading [this discussion](https://github.com/loverajoel/jstips/issues/62) about common mistakes made when checking a property's existence in objects. title: Hoisting tip-number: 11 tip-username: squizzleflip tip-username-profile: https://twitter.com/squizzleflip tip-tldr: Understanding hoisting will help you organize your function scope. Understanding [hoisting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting) will help you organize your function scope. Just remember, variable declarations and function definitions are hoisted to the top. Variable definitions are not, even if you declare and define a variable on the same line. Also, a variable **declaration** lets the system know that the variable exists while **definition** assigns it a value. ```javascript function doTheThing() { // ReferenceError: notDeclared is not defined console.log(notDeclared); // Outputs: undefined console.log(definedLater); var definedLater; definedLater = 'I am defined!'; // Outputs: 'I am defined!' console.log(definedLater); // Outputs: undefined console.log(definedSimulateneously); var definedSimulateneously = 'I am defined!'; // Outputs: 'I am defined!' console.log(definedSimulateneously); // Outputs: 'I did it!' doSomethingElse(); function doSomethingElse() { console.log('I did it!'); } // TypeError: undefined is not a function functionVar(); var functionVar = function () { console.log('I did it!'); }; } ``` To make things easier to read, declare all of your variables at the top of your function scope so it is clear which scope the variables are coming from. Define your variables before you need to use them. Define your functions at the bottom of your scope to keep them out of your way. title: Pseudomandatory parameters in ES6 functions tip-number: 12 tip-username: Avraam Mavridis tip-username-profile: https://github.com/AvraamMavridis tip-tldr: In many programming languages the parameters of a function are by default mandatory and the developer has to explicitly define that a parameter is optional. - /en/pseudomandatory-parameters-in-es6-functions/ In many programming languages the parameters of a function are by default mandatory and the developer has to explicitly define that a parameter is optional. In Javascript, every parameter is optional, but we can enforce this behavior without messing with the actual body of a function, taking advantage of [**es6's default values for parameters**] (http://exploringjs.com/es6/ch_parameter-handling.html#sec_parameter-default-values) feature. ```javascript const _err = function (message) { throw new Error(message); }; const getSum = (a = _err('a is not defined'), b = _err('b is not defined')) => a + b; getSum(10); // throws Error, b is not defined getSum(undefined, 10); // throws Error, a is not defined ``` `_err` is a function that immediately throws an Error. If no value is passed for one of the parameters, the default value is going to be used, `_err` will be called and an Error will be thrown. You can see more examples for the **default parameters feature** on [Mozilla's Developer Network ](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/default_parameters) title: Tip to measure performance of a javascript block tip-number: 13 tip-username: manmadareddy tip-username-profile: https://twitter.com/manmadareddy tip-tldr: For quickly measuring performance of a javascript block, we can use the console functions like `console.time(label)` and `console.timeEnd(label)` - /en/tip-to-measure-performance-of-a-javascript-block/ For quickly measuring performance of a javascript block, we can use the console functions like [`console.time(label)`](https://developer.chrome.com/devtools/docs/console-api#consoletimelabel) and [`console.timeEnd(label)`](https://developer.chrome.com/devtools/docs/console-api#consoletimeendlabel) ```javascript console.time('Array initialize'); var arr = new Array(100), len = arr.length, i; for (i = 0; i < len; i++) { arr[i] = new Object(); } console.timeEnd('Array initialize'); // Outputs: Array initialize: 0.711ms ``` More info: [Console object](https://github.com/DeveloperToolsWG/console-object), [Javascript benchmarking](https://mathiasbynens.be/notes/javascript-benchmarking) Demo: [jsfiddle](https://jsfiddle.net/meottb62/) - [codepen](http://codepen.io/anon/pen/JGJPoa) (outputs in browser console) > Note: As [Mozilla](https://developer.mozilla.org/en-US/docs/Web/API/Console/time) suggested don't use this for production sites, use it for development purposes only. title: Fat Arrow Functions tip-number: 14 tip-username: pklinger tip-username-profile: https://github.com/pklinger/ tip-tldr: Introduced as a new feature in ES6, fat arrow functions may come as a handy tool to write more code in fewer lines - /en/fat-arrow-functions/ Introduced as a new feature in ES6, fat arrow functions may come as a handy tool to write more code in fewer lines. The name comes from its syntax, `=>`, which is a 'fat arrow', as compared to a thin arrow `->`. Some programmers might already know this type of function from different languages such as Haskell, as 'lambda expressions', or as 'anonymous functions'. It is called anonymous, as these arrow functions do not have a descriptive function name. ### What are the benefits? - Syntax: fewer LOC; no more typing `function` keyword over and over again - Semantics: capturing the keyword `this` from the surrounding context ### Simple syntax example Have a look at these two code snippets, which do the exact same job, and you will quickly understand what fat arrow functions do: ```javascript // general syntax for fat arrow functions param => expression // may also be written with parentheses // parentheses are required on multiple params (param1 [, param2]) => expression // using functions var arr = [5,3,2,9,1]; var arrFunc = arr.map(function(x) { return x * x; }); console.log(arr) // using fat arrow var arr = [5,3,2,9,1]; var arrFunc = arr.map((x) => x*x); console.log(arr) ``` As you can see, the fat arrow function in this case can save you time typing out the parentheses as well as the function and return keywords. I would advise you to always write parentheses around the parameter inputs, as the parentheses will be needed for multiple input parameters, such as in `(x,y) => x+y`. It is just a way to cope with forgetting them in different use cases. But the code above would also work like this: `x => x*x`. So far, these are only syntactical improvements, which lead to fewer LOC and better readability. ### Lexically binding `this` There is another good reason to use fat arrow functions. There is the issue with the context of `this`. With arrow functions, you don't need to worry about `.bind(this)` or setting `that = this` anymore, as fat arrow functions pick the context of `this` from the lexical surrounding. Have a look at the next [example] (https://jsfiddle.net/pklinger/rw94oc11/): ```javascript // globally defined this.i this.i = 100; var counterA = new CounterA(); var counterB = new CounterB(); var counterC = new CounterC(); var counterD = new CounterD(); // bad example function CounterA() { // CounterA's `this` instance (!! gets ignored here) this.i = 0; setInterval(function () { // `this` refers to global object, not to CounterA's `this` // therefore starts counting with 100, not with 0 (local this.i) this.i++; document.getElementById('counterA').innerHTML = this.i; }, 500); } // manually binding that = this function CounterB() { this.i = 0; var that = this; setInterval(function () { that.i++; document.getElementById('counterB').innerHTML = that.i; }, 500); } // using .bind(this) function CounterC() { this.i = 0; setInterval( function () { this.i++; document.getElementById('counterC').innerHTML = this.i; }.bind(this), 500 ); } // fat arrow function function CounterD() { this.i = 0; setInterval(() => { this.i++; document.getElementById('counterD').innerHTML = this.i; }, 500); } ``` Further information about fat arrow functions may be found at [MDN] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions). To see different syntax options visit [this site] (http://jsrocks.org/2014/10/arrow-functions-and-their-scope/). title: Even simpler way of using `indexOf` as a contains clause tip-number: 15 tip-username: jhogoforbroke tip-username-profile: https://twitter.com/jhogoforbroke tip-tldr: JavaScript by default does not have a contains method. And for checking existence of a substring in a string or an item in an array you may do this. - /en/even-simpler-way-of-using-indexof-as-a-contains-clause/ JavaScript by default does not have a contains method. And for checking existence of a substring in a string or an item in an array you may do this: ```javascript var someText = 'javascript rules'; if (someText.indexOf('javascript') !== -1) { } // or if (someText.indexOf('javascript') >= 0) { } ``` But let's look at these [Expressjs](https://github.com/strongloop/express) code snippets. [examples/mvc/lib/boot.js](https://github.com/strongloop/express/blob/2f8ac6726fa20ab5b4a05c112c886752868ac8ce/examples/mvc/lib/boot.js#L26) ```javascript for (var key in obj) { // "reserved" exports if (~['name', 'prefix', 'engine', 'before'].indexOf(key)) continue; ``` [lib/utils.js](https://github.com/strongloop/express/blob/2f8ac6726fa20ab5b4a05c112c886752868ac8ce/lib/utils.js#L93) ```javascript exports.normalizeType = function (type) { return ~type.indexOf('/') ? acceptParams(type) : { value: mime.lookup(type), params: {} }; }; ``` [examples/web-service/index.js](https://github.com/strongloop/express/blob/2f8ac6726fa20ab5b4a05c112c886752868ac8ce/examples/web-service/index.js#L35) ```javascript // key is invalid if (!~apiKeys.indexOf(key)) return next(error(401, 'invalid api key')); ``` The gotcha is the [bitwise operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) **~**, "Bitwise operators perform their operations on binary representations, but they return standard JavaScript numerical values." It transforms `-1` into `0`, and `0` evaluates to `false` in JavaScript: ```javascript var someText = 'text'; !!~someText.indexOf('tex'); // someText contains "tex" - true !~someText.indexOf('tex'); // someText NOT contains "tex" - false ~someText.indexOf('asd'); // someText doesn't contain "asd" - false ~someText.indexOf('ext'); // someText contains "ext" - true ``` ### String.prototype.includes() ES6 introduced the [includes() method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) and you can use it to determine whether or not a string includes another string: ```javascript 'something'.includes('thing'); // true ``` With ECMAScript 2016 (ES7) it is even possible to use these techniques with Arrays: ```javascript !!~[1, 2, 3].indexOf(1); // true [1, 2, 3].includes(1); // true ``` **Unfortunately, it is only supported in Chrome, Firefox, Safari 9 or above and Edge; not IE11 or lower.** **It's better used in controlled environments.** title: Passing arguments to callback functions tip-number: 16 tip-username: minhazav tip-username-profile: https://twitter.com/minhazav tip-tldr: By default you cannot pass arguments to a callback function, but you can take advantage of the closure scope in Javascript to pass arguments to callback functions. - /en/passing-arguments-to-callback-functions/ By default you cannot pass arguments to a callback function. For example: ```js function callback() { console.log('Hi human'); } document.getElementById('someelem').addEventListener('click', callback); ``` You can take advantage of the closure scope in Javascript to pass arguments to callback functions. Check this example: ```js function callback(a, b) { return function () { console.log('sum = ', a + b); }; } var x = 1, y = 2; document.getElementById('someelem').addEventListener('click', callback(x, y)); ``` ### What are closures? Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure 'remembers' the environment in which it was created. [Check MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) to learn more. So this way the arguments `x` and `y` are in scope of the callback function when it is called. Another method to do this is using the `bind` method. For example: ```js var alertText = function (text) { alert(text); }; document.getElementById('someelem').addEventListener('click', alertText.bind(this, 'hello')); ``` There is a very slight difference in performance of both methods, checkout [jsperf](http://jsperf.com/bind-vs-closure-23). title: Node.js - Run a module if it is not `required` tip-number: 17 tip-username: odsdq tip-username-profile: https://twitter.com/odsdq tip-tldr: In node, you can tell your program to do two different things depending on whether the code is run from `require('./something.js')` or `node something.js`. This is useful if you want to interact with one of your modules independently. - /en/nodejs-run-a-module-if-it-is-not-required/ In node, you can tell your program to do two different things depending on whether the code is run from `require('./something.js')` or `node something.js`. This is useful if you want to interact with one of your modules independently. ```js if (!module.parent) { // ran with `node something.js` app.listen(8088, function () { console.log('app listening on port 8088'); }); } else { // used with `require('/.something.js')` module.exports = app; } ``` See [the documentation for modules](https://nodejs.org/api/modules.html#modules_module_parent) for more info. title: Truncating the fast (but risky) way tip-number: 18 tip-username: pklinger tip-username-profile: https://github.com/pklinger tip-tldr: .`~~X` is usually a faster `Math.trunc(X)`, but can also make your code do nasty things. - /en/rounding-the-fast-way/ This tip is about performance...with a hidden price tag. Have you ever come across the [double tilde `~~` operator](http://stackoverflow.com/questions/5971645/what-is-the-double-tilde-operator-in-javascript)? It's also often called the "double bitwise NOT" operator. You can often use it as a faster substitute for `Math.trunc()`. Why is that? One bitwise shift `~` first truncates `input` to 32 bits, then transforms it into `-(input+1)`. The double bitwise shift therefore transforms the input into `-(-(input + 1)+1)` making it a great tool to round towards zero. For numeric input, it therefore mimics `Math.trunc()`. On failure, `0` is returned, which might come in handy sometimes instead of `Math.trunc()`, which returns `NaN` on failure. ```js // single ~ console.log(~1337); // -1338 // numeric input console.log(~~47.11); // -> 47 console.log(~~1.9999); // -> 1 console.log(~~3); // -> 3 ``` However, while `~~` is probably a better performer, experienced programmers often stick with `Math.trunc()` instead. To understand why, here's a clinical view on this operator. ### INDICATIONS ##### When every CPU cycle counts `~~` is probably faster than `Math.trunc()` across the board, though you should [test that assumption](https://jsperf.com/jsfvsbitnot/10) on whichever platforms matter to you. Also, you'd generally have to perform millions of such operations to have any visible impact at run time. ##### When code clarity is not a concern If you're trying to confuse others, or get maximum utility from your minifier/uglifier, this is a relatively cheap way to do it. ### CONTRAINDICATIONS ##### When your code needs to be maintained Code clarity is of great importance in the long term, whether you work in a team, contribute to public code repos, or fly solo. As [the oft-quoted saying](http://c2.com/cgi/wiki?CodeForTheMaintainer) goes: > Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live. For a solo programmer, that psychopath is inevitably "you in six months". ##### When you forget that `~~` always rounds to zero Newbie programmers may fixate on the cleverness of `~~`, forgetting the significance of "just drop the fractional portion of this number". This can easily lead to **fencepost errors** (a.k.a. "off-by-one") when transforming floats to array indices or related ordinal values, where a different kind of fractional rounding may actually be called for. (Lack of code clarity usually contributes to this problem.) For instance, if you're counting numbers on a "nearest integer" basis, you should use `Math.round()` instead of `~~`, but programmer laziness and the impact of **_10 whole characters saved per use_** on human fingers often triumph over cold logic, leading to incorrect results. In contrast, the very names of the `Math.xyz()` functions clearly communicate their effect, reducing the probability of accidental errors. ##### When dealing with large-magnitude numbers Because `~` first does a 32-bit conversion, `~~` results in bogus values around ±2.15 billion. If you don't properly range-check your input, a user could trigger unexpected behavior when the transformed value ends up being a great distance from the original: ```js a = 2147483647.123; // maximum positive 32-bit integer, plus a bit more console.log(~~a); // -> 2147483647 (ok) a += 10000; // -> 2147493647.123 (ok) console.log(~~a); // -> -2147483648 (huh?) ``` One particularly vulnerable area involves dealing with Unix epoch timestamps (measured in seconds from 1 Jan 1970 00:00:00 UTC). A quick way to get such values is: ```js epoch_int = ~~(+new Date() / 1000); // Date() epochs in milliseconds, so we scale accordingly ``` However, when dealing with timestamps after 19 Jan 2038 03:14:07 UTC (sometimes called the **Y2038 limit**), this breaks horribly: ```js // epoch timestamp for 1 Jan 2040 00:00:00.123 UTC epoch = +new Date('2040-01-01') / 1000 + 0.123; // -> 2208988800.123 // back to the future! epoch_int = ~~epoch; // -> -2085978496 console.log(new Date(epoch_int * 1000)); // -> Wed Nov 25 1903 17:31:44 UTC // that was fun, now let's get real epoch_flr = Math.floor(epoch); // -> 2208988800 console.log(new Date(epoch_flr * 1000)); // -> Sun Jan 01 2040 00:00:00 UTC ``` ##### When the original input wasn't sanitized Because `~~` transforms every non-number into `0`: ```js console.log(~~[]); // -> 0 console.log(~~NaN); // -> 0 console.log(~~null); // -> 0 ``` some programmers treat it as alternative to proper input validation. However, this can lead to strange logic bugs down the line, since you're no longer distinguishing between invalid inputs and actual `0` values. This is therefore _not_ a recommended practice. ##### When so many people think `~~X == Math.floor(X)` Most people who write about "double bitwise NOT" incorrectly equate it with `Math.floor()` for some reason. If you can't write about it accurately, odds are good you'll eventually misuse it. Others are more careful to mention `Math.floor()` for positive inputs and `Math.ceil()` for negative ones, but that forces you to stop and think about the values you're dealing with. This defeats the purpose of `~~` as a handy no-gotchas shortcut. ### DOSAGE Avoid where possible. Use sparingly otherwise. ### ADMINISTRATION 1. Apply cautiously. 2. Sanitize values before applying. 3. Carefully document relevant assumptions about the values being transformed. 4. Review code to deal with, at minimum: - logic bugs where invalid inputs are instead passed to other code modules as valid `0` values - range errors on transformed inputs - fencepost errors due to incorrect rounding direction title: Safe string concatenation tip-number: 19 tip-username: gogainda tip-username-profile: https://twitter.com/gogainda tip-tldr: Suppose you have a couple of variables with unknown types and you want to concatenate them in a string. To be sure that the arithmetical operation is not be applied during concatenation, use concat - /en/safe-string-concatenation/ Suppose you have a couple of variables with unknown types and you want to concatenate them in a string. To be sure that the arithmetical operation is not be applied during concatenation, use `concat`: ```javascript var one = 1; var two = 2; var three = '3'; var result = ''.concat(one, two, three); //"123" ``` This way of concatenting does exactly what you'd expect. In contrast, concatenation with pluses might lead to unexpected results: ```javascript var one = 1; var two = 2; var three = '3'; var result = one + two + three; //"33" instead of "123" ``` Speaking about performance, compared to the `join` [type](http://www.sitepoint.com/javascript-fast-string-concatenation/) of concatenation, the speed of `concat` is pretty much the same. You can read more about the `concat` function on MDN [page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat). title: Return objects to enable chaining of functions tip-number: 20 tip-username: WakeskaterX tip-username-profile: https://twitter.com/WakeStudio tip-tldr: When creating functions on an object in Object Oriented Javascript, returning the object in the function will enable you to chain functions together. - /en/return-objects-to-enable-chaining-of-functions/ When creating functions on an object in Object Oriented Javascript, returning the object in the function will enable you to chain functions together. ```js function Person(name) { this.name = name; this.sayName = function () { console.log('Hello my name is: ', this.name); return this; }; this.changeName = function (name) { this.name = name; return this; }; } var person = new Person('John'); person.sayName().changeName('Timmy').sayName(); ``` title: Shuffle an Array tip-number: 21 tip-username: 0xmtn tip-username-profile: https://github.com/0xmtn/ tip-tldr: Fisher-Yates Shuffling it's an algorithm to shuffle an array. - /en/shuffle-an-array/ This snippet here uses [Fisher-Yates Shuffling](https://www.wikiwand.com/en/Fisher%E2%80%93Yates_shuffle) Algorithm to shuffle a given array. ```javascript function shuffle(arr) { var i, j, temp; for (i = arr.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } return arr; } ``` An example: ```javascript var a = [1, 2, 3, 4, 5, 6, 7, 8]; var b = shuffle(a); console.log(b); // [2, 7, 8, 6, 5, 3, 1, 4] ``` title: Two ways to empty an array tip-number: 22 tip-username: microlv tip-username-profile: https://github.com/microlv tip-tldr: In JavaScript when you want to empty an array, there are a lot ways, but this is the most performant. - /en/two-ways-to-empty-an-array/ You define an array and want to empty its contents. Usually, you would do it like this: ```javascript // define Array var list = [1, 2, 3, 4]; function empty() { //empty your array list = []; } empty(); ``` But there is another way to empty an array that is more performant. You should use code like this: ```javascript var list = [1, 2, 3, 4]; function empty() { //empty your array list.length = 0; } empty(); ``` - `list = []` assigns a reference to a new array to a variable, while any other references are unaffected. which means that references to the contents of the previous array are still kept in memory, leading to memory leaks. - `list.length = 0` deletes everything in the array, which does hit other references. In other words, if you have two references to the same array (`a = [1,2,3]; a2 = a;`), and you delete the array's contents using `list.length = 0`, both references (a and a2) will now point to the same empty array. (So don't use this technique if you don't want a2 to hold an empty array!) Think about what this will output: ```js var foo = [1, 2, 3]; var bar = [1, 2, 3]; var foo2 = foo; var bar2 = bar; foo = []; bar.length = 0; console.log(foo, bar, foo2, bar2); // [] [] [1, 2, 3] [] ``` Stackoverflow more detail: [difference-between-array-length-0-and-array](http://stackoverflow.com/questions/4804235/difference-between-array-length-0-and-array) title: Converting to number fast way tip-number: 23 tip-username: sonnyt tip-username-profile: http://twitter.com/sonnyt tip-tldr: Converting strings to numbers is extremely common. The easiest and fastest way to achieve that would be using the + operator. - /en/converting-to-number-fast-way/ Converting strings to numbers is extremely common. The easiest and fastest ([jsPerf](https://jsperf.com/number-vs-parseint-vs-plus/29)) way to achieve that would be using the `+` (plus) operator. ```javascript var one = '1'; var numberOne = +one; // Number 1 ``` You can also use the `-` (minus) operator which type-converts the value into number but also negates it. ```javascript var one = '1'; var negativeNumberOne = -one; // Number -1 ``` title: Use === instead of == tip-number: 24 tip-username: bhaskarmelkani tip-username-profile: https://www.twitter.com/bhaskarmelkani tip-tldr: The `==` (or `!=`) operator performs an automatic type conversion if needed. The `===` (or `!==`) operator will not perform any conversion. It compares the value and the type, which could be considered faster ([jsPref](http://jsperf.com/strictcompare)) than `==`. - /en/use*===\_instead_of*==/ The `==` (or `!=`) operator performs an automatic type conversion if needed. The `===` (or `!==`) operator will not perform any conversion. It compares the value and the type, which could be considered faster ([jsPref](http://jsperf.com/strictcompare)) than `==`. ```js [10] == 10 // is true [10] === 10 // is false '10' == 10 // is true '10' === 10 // is false [] == 0 // is true [] === 0 // is false '' == false // is true but true == "a" is false '' === false // is false ``` title: Using immediately invoked function expression tip-number: 25 tip-username: rishantagarwal tip-username-profile: https://github.com/rishantagarwal tip-tldr: Called as "Iffy" ( IIFE - immediately invoked function expression) is an anonymous function expression that is immediately invoked and has some important uses in Javascript. - /en/Using-immediately-invoked-function-expression/ Called as "Iffy" ( IIFE - immediately invoked function expression) is an anonymous function expression that is immediately invoked and has some important uses in Javascript. ```javascript (function () { // Do something​ })(); ``` It is an anonymous function expression that is immediately invoked, and it has some particularly important uses in JavaScript. The pair of parenthesis surrounding the anonymous function turns the anonymous function into a function expression or variable expression. So instead of a simple anonymous function in the global scope, or wherever it was defined, we now have an unnamed function expression. Similarly, we can even create a named, immediately invoked function expression: ```javascript (someNamedFunction = function(msg) { console.log(msg || "Nothing for today !!") }) (); // Output --> Nothing for today !!​ ​ someNamedFunction("Javascript rocks !!"); // Output --> Javascript rocks !! someNamedFunction(); // Output --> Nothing for today !!​ ``` For more details, check the following URL's - 1. [Link 1](https://blog.mariusschulz.com/2016/01/13/disassembling-javascripts-iife-syntax) 2. [Link 2](http://javascriptissexy.com/12-simple-yet-powerful-javascript-tips/) Performance: [jsPerf](http://jsperf.com/iife-with-call) title: Filtering and Sorting a List of Strings tip-number: 26 tip-username: davegomez tip-username-profile: https://github.com/davegomez tip-tldr: You may have a big list of names you need to filter in order to remove duplicates and sort them alphabetically. c - /en/filtering-and-sorting-a-list-of-strings/ You may have a big list of names you need to filter in order to remove duplicates and sort them alphabetically. In our example we are going to use the list of **JavaScript reserved keywords** we can find across the different versions of the language, but as you can notice, there is a lot of duplicated keywords and they are not alphabetically organized. So this is a perfect list ([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)) of strings to test out this JavaScript tip. ```js var keywords = [ 'do', 'if', 'in', 'for', 'new', 'try', 'var', 'case', 'else', 'enum', 'null', 'this', 'true', 'void', 'with', 'break', 'catch', 'class', 'const', 'false', 'super', 'throw', 'while', 'delete', 'export', 'import', 'return', 'switch', 'typeof', 'default', 'extends', 'finally', 'continue', 'debugger', 'function', 'do', 'if', 'in', 'for', 'int', 'new', 'try', 'var', 'byte', 'case', 'char', 'else', 'enum', 'goto', 'long', 'null', 'this', 'true', 'void', 'with', 'break', 'catch', 'class', 'const', 'false', 'final', 'float', 'short', 'super', 'throw', 'while', 'delete', 'double', 'export', 'import', 'native', 'public', 'return', 'static', 'switch', 'throws', 'typeof', 'boolean', 'default', 'extends', 'finally', 'package', 'private', 'abstract', 'continue', 'debugger', 'function', 'volatile', 'interface', 'protected', 'transient', 'implements', 'instanceof', 'synchronized', 'do', 'if', 'in', 'for', 'let', 'new', 'try', 'var', 'case', 'else', 'enum', 'eval', 'null', 'this', 'true', 'void', 'with', 'break', 'catch', 'class', 'const', 'false', 'super', 'throw', 'while', 'yield', 'delete', 'export', 'import', 'public', 'return', 'static', 'switch', 'typeof', 'default', 'extends', 'finally', 'package', 'private', 'continue', 'debugger', 'function', 'arguments', 'interface', 'protected', 'implements', 'instanceof', 'do', 'if', 'in', 'for', 'let', 'new', 'try', 'var', 'case', 'else', 'enum', 'eval', 'null', 'this', 'true', 'void', 'with', 'await', 'break', 'catch', 'class', 'const', 'false', 'super', 'throw', 'while', 'yield', 'delete', 'export', 'import', 'public', 'return', 'static', 'switch', 'typeof', 'default', 'extends', 'finally', 'package', 'private', 'continue', 'debugger', 'function', 'arguments', 'interface', 'protected', 'implements', 'instanceof' ]; ``` Since we don't want to change our original list, we are going to use a high order function named [`filter`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), which will return a new filter array based in a predicate (_function_) we pass to it. The predicate will compare the index of the current keyword in the original list with its `index` in the new list and will push it to the new array only if the indexes match. Finally we are going to sort the filtered list using the [`sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) function which takes a comparison function as the only argument, returning a alphabetically sorted list. ```js var filteredAndSortedKeywords = keywords .filter(function (keyword, index) { return keywords.lastIndexOf(keyword) === index; }) .sort(function (a, b) { return a < b ? -1 : 1; }); ``` The **ES6** (ECMAScript 2015) version using [arrow functions](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions) looks a little simpler: ```js const filteredAndSortedKeywords = keywords.filter((keyword, index) => keywords.lastIndexOf(keyword) === index).sort((a, b) => (a < b ? -1 : 1)); ``` And this is the final filtered and sorted list of JavaScript reserved keywords: ```js console.log(filteredAndSortedKeywords); // ['abstract', 'arguments', 'await', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'double', 'else', 'enum', 'eval', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import', 'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native', 'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'short', 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws', 'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', 'with', 'yield'] ``` _Thanks to [@nikshulipa](https://github.com/nikshulipa), [@kirilloid](https://twitter.com/kirilloid), [@lesterzone](https://twitter.com/lesterzone), [@tracker1](https://twitter.com/tracker1), [@manuel_del_pozo](https://twitter.com/manuel_del_pozo) for all the comments and suggestions!_ title: Short circuit evaluation in JS. tip-number: 27 tip-username: bhaskarmelkani tip-username-profile: https://www.twitter.com/bhaskarmelkani tip-tldr: Short-circuit evaluation says, the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression, when the first argument of the AND `&&` function evaluates to false, the overall value must be false, and when the first argument of the OR `||` function evaluates to true, the overall value must be true. - /en/short-circuit-evaluation-in-js/ [Short-circuit evaluation](https://en.wikipedia.org/wiki/Short-circuit_evaluation) says, the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression: when the first argument of the AND (`&&`) function evaluates to false, the overall value must be false; and when the first argument of the OR (`||`) function evaluates to true, the overall value must be true. For the following `test` condition and `isTrue` and `isFalse` function. ```js var test = true; var isTrue = function () { console.log('Test is true.'); }; var isFalse = function () { console.log('Test is false.'); }; ``` Using logical AND - `&&`. ```js // A normal if statement. if (test) { isTrue(); // Test is true } // Above can be done using '&&' as - test && isTrue(); // Test is true ``` Using logical OR - `||`. ```js test = false; if (!test) { isFalse(); // Test is false. } test || isFalse(); // Test is false. ``` The logical OR could also be used to set a default value for function argument. ```js function theSameOldFoo(name) { name = name || 'Bar'; console.log("My best friend's name is " + name); } theSameOldFoo(); // My best friend's name is Bar theSameOldFoo('Bhaskar'); // My best friend's name is Bhaskar ``` The logical AND could be used to avoid exceptions when using properties of undefined. Example: ```js var dog = { bark: function () { console.log('Woof Woof'); } }; // Calling dog.bark(); dog.bark(); // Woof Woof. // But if dog is not defined, dog.bark() will raise an error "Cannot read property 'bark' of undefined." // To prevent this, we can use &&. dog && dog.bark(); // This will only call dog.bark(), if dog is defined. ``` title: Currying vs partial application tip-number: 28 tip-username: bhaskarmelkani tip-username-profile: https://www.twitter.com/bhaskarmelkani tip-tldr: Currying and partial application are two ways of transforming a function into another function with a generally smaller arity. - /en/curry-vs-partial-application/ **Currying** Currying takes a function f: X \* Y -> R and turns it into a function f': X -> (Y -> R) Instead of calling f with two arguments, we invoke f' with the first argument. The result is a function that we then call with the second argument to produce the result. Thus, if the uncurried f is invoked as f(3,5) then the curried f' is invoked as f(3)(5) For example: Uncurried add() ```javascript function add(x, y) { return x + y; } add(3, 5); // returns 8 ``` Curried add() ```javascript function addC(x) { return function (y) { return x + y; }; } addC(3)(5); // returns 8 ``` **The algorithm for currying.** Curry takes a binary function and returns a unary function that returns a unary function. curry: (X × Y → R) → (X → (Y → R)) Javascript Code: ```javascript function curry(f) { return function (x) { return function (y) { return f(x, y); }; }; } ``` **Partial application** Partial application takes a function f: X \* Y -> R and a fixed value for the first argument to produce a new function f`: Y -> R f' does the same as f, but only has to fill in the second parameter which is why its arity is one less than the arity of f. For example: Binding the first argument of function add to 5 produces the function plus5. ```javascript function plus5(y) { return 5 + y; } plus5(3); // returns 8 ``` **The algorithm of partial application.\*** partApply takes a binary function and a value and produces a unary function. partApply : ((X × Y → R) × X) → (Y → R) Javascript Code: ```javascript function partApply(f, x) { return function (y) { return f(x, y); }; } ``` title: Speed up recursive functions with memoization tip-number: 29 tip-username: hingsir tip-username-profile: https://github.com/hingsir tip-tldr: Fibonacci sequence is very familiar to everybody. we can write the following function in 20 seconds.it works, but not efficient. it did lots of duplicate computing works, we can cache its previously computed results to speed it up. - /en/speed-up-recursive-functions-with-memoization/ Fibonacci sequence is very familiar to everybody. We can write the following function in 20 seconds. ```js var fibonacci = function (n) { return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); }; ``` It works, but is not efficient. It did lots of duplicate computing works, we can cache its previously computed results to speed it up. ```js var fibonacci = (function () { var cache = [0, 1]; // cache the value at the n index return function (n) { if (cache[n] === undefined) { for (var i = cache.length; i <= n; ++i) { cache[i] = cache[i - 1] + cache[i - 2]; } } return cache[n]; }; })(); ``` Also, we can define a higher-order function that accepts a function as its argument and returns a memoized version of the function. ```js var memoize = function (func) { var cache = {}; return function () { var key = JSON.stringify(Array.prototype.slice.call(arguments)); return key in cache ? cache[key] : (cache[key] = func.apply(this, arguments)); }; }; fibonacci = memoize(fibonacci); ``` And this is an ES6 version of the memoize function. ```js var memoize = function (func) { const cache = {}; return (...args) => { const key = JSON.stringify(args); return key in cache ? cache[key] : (cache[key] = func(...args)); }; }; fibonacci = memoize(fibonacci); ``` we can use `memoize()` in many other situations - GCD(Greatest Common Divisor) ```js var gcd = memoize(function (a, b) { var t; if (a < b) (t = b), (b = a), (a = t); while (b != 0) (t = b), (b = a % b), (a = t); return a; }); gcd(27, 183); //=> 3 ``` - Factorial calculation ```js var factorial = memoize(function (n) { return n <= 1 ? 1 : n * factorial(n - 1); }); factorial(5); //=> 120 ``` Learn more about memoization: - [Memoization - Wikipedia](https://en.wikipedia.org/wiki/Memoization) - [Implementing Memoization in JavaScript](https://www.sitepoint.com/implementing-memoization-in-javascript/) title: Converting truthy/falsy values to boolean tip-number: 30 tip-username: hakhag tip-username-profile: https://github.com/hakhag tip-tldr: Logical operators are a core part of JavaScript, here you can see a a way you always get a true or false no matter what was given to it. - /en/converting-truthy-falsy-values-to-boolean/ You can convert a [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) or [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) value to true boolean with the `!!` operator. ```js !!''; // false !!0; // false !!null; // false !!undefined; // false !!NaN; // false !!'hello'; // true !!1; // true !!{}; // true !![]; // true ``` title: Avoid modifying or passing `arguments` into other functions — it kills optimization tip-number: 31 tip-username: berkana tip-username-profile: https://github.com/berkana tip-tldr: Within JavaScript functions, the variable name `arguments` lets you access all of the arguments passed to the function. `arguments` is an _array-like object_; `arguments` can be accessed using array notation, and it has the _length_ property, but it doesn't have many of the built-in methods that arrays have such as `filter` and `map` and `forEach`. Because of this, it is a fairly common practice to convert `arguments` into an array using the following snipet - /en/avoid-modifying-or-passing-arguments-into-other-functions-it-kills-optimization/ ###Background Within JavaScript functions, the variable name [`arguments`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments) lets you access all of the arguments passed to the function. `arguments` is an _array-like object_; `arguments` can be accessed using array notation, and it has the _length_ property, but it doesn't have many of the built-in methods that arrays have such as `filter` and `map` and `forEach`. Because of this, it is a fairly common practice to convert `arguments` into an array using the following: ```js var args = Array.prototype.slice.call(arguments); ``` This calls the `slice` method from the `Array` prototype, passing it `arguments`; the `slice` method returns a shallow copy of `arguments` as a new array object. A common shorthand for this is : ```js var args = [].slice.call(arguments); ``` In this case, instead of calling `slice` from the `Array` prototype, it is simply being called from an empty array literal. ###Optimization Unfortunately, passing `arguments` into any function call will cause the V8 JavaScript engine used in Chrome and Node to skip optimization on the function that does this, which can result in considerably slower performance. See this article on [optimization killers](https://github.com/petkaantonov/bluebird/wiki/Optimization-killers). Passing `arguments` to any other function is known as _leaking `arguments`_. Instead, if you want an array of the arguments that lets you use you need to resort to this: ```js var args = new Array(arguments.length); for (var i = 0; i < args.length; ++i) { args[i] = arguments[i]; } ``` Yes it is more verbose, but in production code, it is worth it for the performance optimization. title: Map() to the rescue; adding order to Object properties tip-number: 32 tip-username: loverajoel tip-username-profile: https://twitter.com/loverajoel tip-tldr: An Object it is an unordered collection of properties... that means that if you are trying to save ordered data inside an Object, you have to review it because properties order in objects are not guaranteed. tip-writer-support: https://www.coinbase.com/loverajoel - /en/map-to-the-rescue-adding-order-to-object-properties/ ## Object properties order > An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method. [ECMAScript](http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf) Take a look in action ```js var myObject = { z: 1, '@': 2, b: 3, 1: 4, 5: 5 }; console.log(myObject) // Object {1: 4, 5: 5, z: 1, @: 2, b: 3} for (item in myObject) {... // 1 // 5 // z // @ // b ``` Each browser have his own rules about the order in objects bebause technically, order is unspecified. ## How to solve this? ### Map Using a new ES6 feature called Map. A [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) object iterates its elements in insertion order — a `for...of` loop returns an array of [key, value] for each iteration. ```js var myObject = new Map(); myObject.set('z', 1); myObject.set('@', 2); myObject.set('b', 3); for (var [key, value] of myObject) { console.log(key, value); ... // z 1 // @ 2 // b 3 ``` ### Hack for old browsers Mozilla suggest: > So, if you want to simulate an ordered associative array in a cross-browser environment, you are forced to either use two separate arrays (one for the keys and the other for the values), or build an array of single-property objects, etc. ```js // Using two separate arrays var objectKeys = [z, @, b, 1, 5]; for (item in objectKeys) { myObject[item] ... // Build an array of single-property objects var myData = [{z: 1}, {'@': 2}, {b: 3}, {1: 4}, {5: 5}]; ``` title: Create array sequence `[0, 1, ..., N-1]` in one line tip-number: 33 tip-username: SarjuHansaliya tip-username-profile: https://github.com/SarjuHansaliya tip-tldr: Compact one-liners that generate ordinal sequence arrays - /en/create-range-0...n-easily-using-one-line/ Here are two compact code sequences to generate the `N`-element array `[0, 1, ..., N-1]`: ### Solution 1 (requires ES5) ```js Array.apply(null, { length: N }).map(Function.call, Number); ``` #### Brief explanation 1. `Array.apply(null, {length: N})` returns an `N`-element array filled with `undefined` (i.e. `A = [undefined, undefined, ...]`). 2. `A.map(Function.call, Number)` returns an `N`-element array, whose index `I` gets the result of `Function.call.call(Number, undefined, I, A)` 3. `Function.call.call(Number, undefined, I, A)` collapses into `Number(I)`, which is naturally `I`. 4. Result: `[0, 1, ..., N-1]`. For a more thorough explanation, go [here](https://github.com/gromgit/jstips-xe/blob/master/tips/33.md). ### Solution 2 (requires ES6) It uses `Array.from` [https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) ```js Array.from(new Array(N), (val, index) => index); ``` ### Solution 3 (requires ES6) ```js Array.from(Array(N).keys()); ``` #### Brief explanation 1. `A = new Array(N)` returns an array with `N` _holes_ (i.e. `A = [,,,...]`, but `A[x] = undefined` for `x` in `0...N-1`). 2. `F = (val,index)=>index` is simply `function F (val, index) { return index; }` 3. `Array.from(A, F)` returns an `N`-element array, whose index `I` gets the results of `F(A[I], I)`, which is simply `I`. 4. Result: `[0, 1, ..., N-1]`. ### One More Thing If you actually want the sequence [1, 2, ..., N], **Solution 1** becomes: ```js Array.apply(null, { length: N }).map(function (value, index) { return index + 1; }); ``` and **Solution 2**: ```js Array.from(new Array(N), (val, index) => index + 1); ``` title: Implementing asynchronous loop tip-number: 34 tip-username: madmantalking tip-username-profile: https://github.com/madmantalking tip-tldr: You may run into problems while implementing asynchronous loops. - /en/implementing-asynchronous-loops/ Let's try out writing an asynchronous function which prints the value of the loop index every second. ```js for (var i = 0; i < 5; i++) { setTimeout(function () { console.log(i); }, 1000 * (i + 1)); } ``` The output of the above programs turns out to be ```js > 5 > 5 > 5 > 5 > 5 ``` So this definitely doesn't work. **Reason** Each timeout refers to the original `i`, not a copy. So the for loop increments `i` until it gets to 5, then the timeouts run and use the current value of `i` (which is 5). Well , this problem seems easy. An immediate solution that strikes is to cache the loop index in a temporary variable. ```js for (var i = 0; i < 5; i++) { var temp = i; setTimeout(function () { console.log(temp); }, 1000 * (i + 1)); } ``` But again the output of the above programs turns out to be ```js > 4 > 4 > 4 > 4 > 4 ``` So , that doesn't work either , because blocks don't create a scope and variables initializers are hoisted to the top of the scope. In fact, the previous block is the same as: ```js var temp; for (var i = 0; i < 5; i++) { temp = i; setTimeout(function () { console.log(temp); }, 1000 * (i + 1)); } ``` **Solution** There are a few different ways to copy `i`. The most common way is creating a closure by declaring a function and passing `i` as an argument. Here we do this as a self-calling function. ```js for (var i = 0; i < 5; i++) { (function (num) { setTimeout(function () { console.log(num); }, 1000 * (i + 1)); })(i); } ``` In JavaScript, arguments are passed by value to a function. So primitive types like numbers, dates, and strings are basically copied. If you change them inside the function, it does not affect the outside scope. Objects are special: if the inside function changes a property, the change is reflected in all scopes. Another approach for this would be with using `let`. With ES6 the `let` keyword is useful since it's block scoped unlike `var` ```js for (let i = 0; i < 5; i++) { setTimeout(function () { console.log(i); }, 1000 * (i + 1)); } ``` title: Assignment Operators tip-number: 35 tip-username: hsleonis tip-username-profile: https://github.com/hsleonis tip-tldr: Assigning is very common. Sometimes typing becomes time consuming for us 'Lazy programmers'. So, we can use some tricks to help us and make our code cleaner and simpler. - /en/assignment-shorthands/ Assigning is very common. Sometimes typing becomes time consuming for us 'Lazy programmers'. So, we can use some tricks to help us and make our code cleaner and simpler. This is the similar use of ```javascript x += 23; // x = x + 23; y -= 15; // y = y - 15; z *= 10; // z = z * 10; k /= 7; // k = k / 7; p %= 3; // p = p % 3; d **= 2; // d = d ** 2; m >>= 2; // m = m >> 2; n <<= 2; // n = n << 2; n++; // n = n + 1; n--; n = n - 1; ``` ### `++` and `--` operators There is a special `++` operator. It's best to explain it with an example: ```javascript var a = 2; var b = a++; // Now a is 3 and b is 2 ``` The `a++` statement does this: 1. return the value of `a` 2. increment `a` by 1 But what if we wanted to increment the value first? It's simple: ```javascript var a = 2; var b = ++a; // Now both a and b are 3 ``` See? I put the operator _before_ the variable. The `--` operator is similar, except it decrements the value. ### If-else (Using ternary operator) This is what we write on regular basis. ```javascript var newValue; if (value > 10) newValue = 5; else newValue = 2; ``` We can user ternary operator to make it awesome: ```javascript var newValue = value > 10 ? 5 : 2; ``` ### Null, Undefined, Empty Checks ```javascript if (variable1 !== null || variable1 !== undefined || variable1 !== '') { var variable2 = variable1; } ``` Shorthand here: ```javascript var variable2 = variable1 || ''; ``` P.S.: If variable1 is a number, then first check if it is 0. ### Object Array Notation Instead of using: ```javascript var a = new Array(); a[0] = 'myString1'; a[1] = 'myString2'; ``` Use this: ```javascript var a = ['myString1', 'myString2']; ``` ### Associative array Instead of using: ```javascript var skillSet = new Array(); skillSet['Document language'] = 'HTML5'; skillSet['Styling language'] = 'CSS3'; ``` Use this: ```javascript var skillSet = { 'Document language': 'HTML5', 'Styling language': 'CSS3' }; ``` title: Observe DOM changes in extensions tip-number: 36 tip-username: beyondns tip-username-profile: https://github.com/beyondns tip-tldr: When you develop extensions to existent sites it's not so easy to play with DOM 'cause of modern dynamic javascript. - /en/observe-dom-changes/ [MutationObserver](https://developer.mozilla.org/en/docs/Web/API/MutationObserver) is a solution to listen DOM changes and do what you want to do with elements when they changed. In following example there is some emulation of dynamic content loading with help of timers, after first "target" element creation goes "subTarget". In extension code firstly rootObserver works till targetElement appearance then elementObserver starts. This cascading observing helps finally get moment when subTargetElement found. This useful to develop extensions to complex sites with dynamic content loading. ```js const observeConfig = { attributes: true, childList: true, characterData: true, subtree: true }; function initExtension(rootElement, targetSelector, subTargetSelector) { var rootObserver = new MutationObserver(function (mutations) { console.log('Inside root observer'); targetElement = rootElement.querySelector(targetSelector); if (targetElement) { rootObserver.disconnect(); var elementObserver = new MutationObserver(function (mutations) { console.log('Inside element observer'); subTargetElement = targetElement.querySelector(subTargetSelector); if (subTargetElement) { elementObserver.disconnect(); console.log('subTargetElement found!'); } }); elementObserver.observe(targetElement, observeConfig); } }); rootObserver.observe(rootElement, observeConfig); } (function () { initExtension(document.body, 'div.target', 'div.subtarget'); setTimeout(function () { del = document.createElement('div'); del.innerHTML = "
target
"; document.body.appendChild(del); }, 3000); setTimeout(function () { var el = document.body.querySelector('div.target'); if (el) { del = document.createElement('div'); del.innerHTML = "
subtarget
"; el.appendChild(del); } }, 5000); })(); ``` title: Deduplicate an Array tip-number: 37 tip-username: danillouz tip-username-profile: https://www.twitter.com/danillouz tip-tldr: How to remove duplicate elements, of different data types, from an Array. - /en/deduplicate-an-array/ # Primitives If an Array only contains primitive values, we can deduplicate it by only using the [`filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) and [`indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) methods. ```javascript var deduped = [1, 1, 'a', 'a'].filter(function (el, i, arr) { return arr.indexOf(el) === i; }); console.log(deduped); // [ 1, 'a' ] ``` ## ES2015 We can write this in a more compact way using an [arrow function](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions). ```javascript var deduped = [1, 1, 'a', 'a'].filter((el, i, arr) => arr.indexOf(el) === i); console.log(deduped); // [ 1, 'a' ] ``` But with the introduction of [Sets](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) and the [`from`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) method, we can achieve the same result in a more concise way. ```javascript var deduped = Array.from(new Set([1, 1, 'a', 'a'])); console.log(deduped); // [ 1, 'a' ] ``` # Objects We can't use the same approach when the elements are Objects, because Objects are stored by reference and primitives are stored by value. ```javascript 1 === 1 // true 'a' === 'a' // true { a: 1 } === { a: 1 } // false ``` Therefore we need to change our approach and use a hash table. ```javascript function dedup(arr) { var hashTable = {}; return arr.filter(function (el) { var key = JSON.stringify(el); var match = Boolean(hashTable[key]); return match ? false : (hashTable[key] = true); }); } var deduped = dedup([{ a: 1 }, { a: 1 }, [1, 2], [1, 2]]); console.log(deduped); // [ {a: 1}, [1, 2] ] ``` Because a hash table in javascript is simply an `Object`, the keys will always be of the type `String`. This means that normally we can't distinguish between strings and numbers of the same value, i.e. `1` and `'1'`. ```javascript var hashTable = {}; hashTable[1] = true; hashTable['1'] = true; console.log(hashTable); // { '1': true } ``` However, because we're using [`JSON.stringify`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify), keys that are of the type `String`, will be stored as an escaped string value, giving us unique keys in our `hashTable`. ```javascript var hashTable = {}; hashTable[JSON.stringify(1)] = true; hashTable[JSON.stringify('1')] = true; console.log(hashTable); // { '1': true, '\'1\'': true } ``` This means duplicate elements of the same value, but of a different type, will still be deduplicated using the same implementation. ```javascript var deduped = dedup([{ a: 1 }, { a: 1 }, [1, 2], [1, 2], 1, 1, '1', '1']); console.log(deduped); // [ {a: 1}, [1, 2], 1, '1' ] ``` # Resources ## Methods - [`filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) - [`indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) - [`from`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) - [`JSON.stringify`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) ## ES2015 - [arrow functions](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions) - [Sets](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) ## Stack overflow - [remove duplicates from array](http://stackoverflow.com/questions/9229645/remove-duplicates-from-javascript-array/9229821#9229821) title: Flattening multidimensional Arrays in JavaScript tip-number: 38 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: Three different solutions to merge multidimensional array into a single array. tip-writer-support: https://www.coinbase.com/loverajoel - /en/flattening-multidimensional-arrays-in-javascript/ These are the three known ways to merge multidimensional array into a single array. Given this array: ```js var myArray = [ [1, 2], [3, 4, 5], [6, 7, 8, 9] ]; ``` We wanna have this result: ```js [1, 2, 3, 4, 5, 6, 7, 8, 9]; ``` ### Solution 1: Using [`concat()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) and [`apply()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) ```js var myNewArray = [].concat.apply([], myArray); // [1, 2, 3, 4, 5, 6, 7, 8, 9] ``` ### Solution 2: Using [`reduce()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce#Flatten_an_array_of_arrays) ```js var myNewArray = myArray.reduce(function (prev, curr) { return prev.concat(curr); }); // [1, 2, 3, 4, 5, 6, 7, 8, 9] ``` ### Solution 3: ```js var myNewArray3 = []; for (var i = 0; i < myArray.length; ++i) { for (var j = 0; j < myArray[i].length; ++j) myNewArray3.push(myArray[i][j]); } console.log(myNewArray3); // [1, 2, 3, 4, 5, 6, 7, 8, 9] ``` ### Solution 4: Using [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) in ES6 ```js var myNewArray4 = [].concat(...myArray); console.log(myNewArray4); // [1, 2, 3, 4, 5, 6, 7, 8, 9] ``` ### Solution 5: Using [`flat()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) in ES10 ```js var myNewArray5 = myArray.flat(); console.log(myNewArray5); // [1, 2, 3, 4, 5, 6, 7, 8, 9] ``` Take a look [here](https://jsbin.com/janana/edit?js,console) these 4 algorithms in action. For infinitely nested array try Lodash [flattenDeep()](https://lodash.com/docs#flattenDeep). If you are curious about performance, [here](http://jsperf.com/flatten-an-array-loop-vs-reduce/6) a test for check how it works. title: Advanced Javascript Properties tip-number: 39 tip-username: mallowigi tip-username-profile: https://github.com/mallowigi tip-tldr: How to add private properties, getters and setters to objects. - /en/advanced-properties/ It is possible to configure object properties in Javascript for example to set properties to be pseudo-private or readonly. This feature is available since ECMAScript 5.1, therefore supported by all recent browsers. To do so, you need to use the method `defineProperty` of the `Object` prototype like so: ```js var a = {}; Object.defineProperty(a, 'readonly', { value: 15, writable: false }); a.readonly = 20; console.log(a.readonly); // 15 ``` The syntax is as follows: ```js Object.defineProperty(dest, propName, options); ``` or for multiple definitions: ```js Object.defineProperties(dest, { propA: optionsA, propB: optionsB //... }); ``` where options include the following attributes: - _value_: if the property is not a getter (see below), value is a mandatory attribute. `{a: 12}` === `Object.defineProperty(obj, 'a', {value: 12})` - _writable_: set the property as readonly. Note that if the property is a nested objects, its properties are still editable. - _enumerable_: set the property as hidden. That means that `for ... of` loops and `stringify` will not include the property in their result, but the property is still there. Note: That doesn't mean that the property is private! It can still be accessible from the outside, it just means that it won't be printed. - _configurable_: set the property as non modifiable, e.g. protected from deletion or redefinition. Again, if the property is a nested object, its properties are still configurable. So in order to create a private constant property, you can define it like so: ```js Object.defineProperty(obj, 'myPrivateProp', { value: val, enumerable: false, writable: false, configurable: false }); ``` Besides configuring properties, `defineProperty` allows us to define _dynamic properties_, thanks to the second parameter being a string. For instance, let's say that I want to create properties according to some external configuration: ```js var obj = { getTypeFromExternal(): true // illegal in ES5.1 } Object.defineProperty(obj, getTypeFromExternal(), {value: true}); // ok // For the example sake, ES6 introduced a new syntax: var obj = { [getTypeFromExternal()]: true } ``` But that's not all! Advanced properties allows us to create **getters** and **setters**, just like other OOP languages! In that case, one cannot use the `writable`, `enumerable` and `configurable` properties, but instead: ```js function Foobar () { var _foo; // true private property Object.defineProperty(obj, 'foo', { get: function () { return _foo; } set: function (value) { _foo = value } }); } var foobar = new Foobar(); foobar.foo; // 15 foobar.foo = 20; // _foo = 20 ``` Aside for the obvious advantage of encapsulation and advanced accessors, you will notice that we didn't "call" the getter, instead we just "get" the property without parentheses! This is awesome! For instance, let's imagine that we have an object with long nested properties, like so: ```js var obj = { a: { b: { c: [{ d: 10 }, { d: 20 }] } } }; ``` Now instead of doing `a.b.c[0].d` (where one of the properties can resolve to `undefined` and throw an error), we can instead create an alias: ```js Object.defineProperty(obj, 'firstD', { get: function () { return a && a.b && a.b.c && a.b.c[0] && a.b.c[0].d; } }); console.log(obj.firstD); // 10 ``` ### Note If you define a getter without a setter and still try to set a value, you will get an error! This is particularly important when using helper functions such as `$.extend` or `_.merge`. Be careful! ### Links - [defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) - [Defining properties in JavaScript](http://bdadam.com/blog/defining-properties-in-javascript.html) title: Using JSON.Stringify tip-number: 40 tip-username: vamshisuram tip-username-profile: https://github.com/vamshisuram tip-tldr: Create string from selected properties of JSON object. - /en/using-json-stringify/ Let's say there is an object with properties "prop1", "prop2", "prop3". We can pass **additional params** to **JSON.stringify** to selectively write properties of the object to string like: ```javascript var obj = { prop1: 'value1', prop2: 'value2', prop3: 'value3' }; var selectedProperties = ['prop1', 'prop2']; var str = JSON.stringify(obj, selectedProperties); // str // {"prop1":"value1","prop2":"value2"} ``` The **"str"** will contain only info on selected properties only. Instead of array we can pass a function also. ```javascript function selectedProperties(key, val) { // the first val will be the entire object, key is empty string if (!key) { return val; } if (key === 'prop1' || key === 'prop2') { return val; } return; } ``` The last optional param it takes is to modify the way it writes the object to string. ```javascript var str = JSON.stringify(obj, selectedProperties, '\t\t'); /* str output with double tabs in every line. { "prop1": "value1", "prop2": "value2" } */ ``` title: Array average and median tip-number: 41 tip-username: soyuka tip-username-profile: https://github.com/soyuka tip-tldr: Calculate the average and median from array values - /en/array-average-and-median/ The following examples will be based on the following array: ```javascript let values = [2, 56, 3, 41, 0, 4, 100, 23]; ``` To get the average, we have to sum up numbers and then divide by the number of values. Steps are: - get the array length - sum up values - get the average (`sum/length`) ```javascript let values = [2, 56, 3, 41, 0, 4, 100, 23]; let sum = values.reduce((previous, current) => (current += previous)); let avg = sum / values.length; // avg = 28 ``` Or: ```javascript let values = [2, 56, 3, 41, 0, 4, 100, 23]; let count = values.length; values = values.reduce((previous, current) => (current += previous)); values /= count; // avg = 28 ``` Now, to get the median steps are: - sort the array - get the arethmic mean of the middle values ```javascript let values = [2, 56, 3, 41, 0, 4, 100, 23]; values.sort((a, b) => a - b); let lowMiddle = Math.floor((values.length - 1) / 2); let highMiddle = Math.ceil((values.length - 1) / 2); let median = (values[lowMiddle] + values[highMiddle]) / 2; // median = 13,5 ``` With a bitwise operator: ```javascript let values = [2, 56, 3, 41, 0, 4, 100, 23]; values.sort((a, b) => a - b); let median = (values[(values.length - 1) >> 1] + values[values.length >> 1]) / 2; // median = 13,5 ``` title: Preventing Unapply Attacks tip-number: 42 tip-username: emars tip-username-profile: https://twitter.com/marseltov tip-tldr: Freeze the builtin prototypes. - /en/preventing-unapply-attacks/ By overriding the builtin prototypes, external code can cause code to break by rewriting code to expose and change bound arguments. This can be an issue that seriously breaks applications that works by using polyfill es5 methods. ```js // example bind polyfill function bind(fn) { var prev = Array.prototype.slice.call(arguments, 1); return function bound() { var curr = Array.prototype.slice.call(arguments, 0); var args = Array.prototype.concat.apply(prev, curr); return fn.apply(null, args); }; } // unapply-attack function unapplyAttack() { var concat = Array.prototype.concat; Array.prototype.concat = function replaceAll() { Array.prototype.concat = concat; // restore the correct version var curr = Array.prototype.slice.call(arguments, 0); var result = concat.apply([], curr); return result; }; } ``` The above function discards the `prev` array from the bind meaning that any `.concat` the first concat call following using the unapply attack will throw an error. By using [Object.freeze](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze), making an object immutable, you prevent any overriding of the builtin object prototypes. ```js (function freezePrototypes() { if (typeof Object.freeze !== 'function') { throw new Error('Missing Object.freeze'); } Object.freeze(Object.prototype); Object.freeze(Array.prototype); Object.freeze(Function.prototype); })(); ``` You can read more about unapply attacks [here](https://glebbahmutov.com/blog/unapply-attack/). Although this concept is called an 'unapply attack' due to some code being able to access closures that normally wouldn't be in scope, it is mostly wrong to consider this a security feature due to it not preventing an attacker with code execution from extending prototypes before the freezing happens and also still having the potential to read all scopes using various language features. ECMA modules would give realm based isolation which is much stronger than this solution however still doesn't fix the issues of third party scripts. title: Use destructuring in function parameters tip-number: 43 tip-username: dislick tip-username-profile: https://github.com/dislick tip-tldr: Did you know that you can use destructuring in function parameters? - /en/use-destructuring-in-function-parameters/ I am sure many of you are already familiar with the [ES6 Destructuring Assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment). Did you know that you can also use it in function parameters? ```js var sayHello = function ({ name, surname }) { console.log(`Hello ${name} ${surname}! How are you?`); }; sayHello({ name: 'John', surname: 'Smith' }); // -> Hello John Smith! How are you? ``` This is great for functions which accept an options object. For this use case, you can also add [default parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters) to fill in whatever values the caller leaves out, or if the caller forgets to pass one at all: ```js var sayHello2 = function ({ name = 'Anony', surname = 'Moose' } = {}) { console.log(`Hello ${name} ${surname}! How are you?`); }; ``` The `= {}` says that the default object to be destructured for this parameter is `{}`, in case the caller forgets to pass the parameter, or passes one of the wrong type (more on this below). ```js sayHello2(); // -> Hello Anony Moose! How are you? sayHello2({ name: 'Bull' }); // -> Hello Bull Moose! How are you? ``` ##### Argument Handling With plain destructuring assignment, if the the input parameter can't be matched with the function's specified object arguments, all the unmatched arguments are `undefined`, so you need to add code that handles this properly: ```js var sayHelloTimes = function ({ name, surname }, times) { console.log(`Hello ${name} ${surname}! I've seen you ${times} times before.`); }; sayHelloTimes({ name: 'Pam' }, 5678); // -> Hello Pam undefined! I've seen you 5678 times before. sayHelloTimes(5678); // -> Hello undefined undefined! I've seen you undefined times before. ``` Worse, if the parameter to be destructured is missing, an exception is thrown, probably bringing your app to a screeching halt: ```js sayHelloTimes(); // -> Uncaught TypeError: Cannot match against 'undefined' or 'null'... ``` It's conceptually similar to accessing a property of an undefined object, just with a different exception type. Destructuring assignment with default parameters hides all the above to a certain extent: ```js var sayHelloTimes2 = function ({ name = 'Anony', surname = 'Moose' } = {}, times) { console.log(`Hello ${name} ${surname}! I've seen you ${times} times before.`); }; sayHelloTimes2({ name: 'Pam' }, 5678); // -> Hello Pam Moose! I've seen you 5678 times before. sayHelloTimes2(5678); // -> Hello Anony Moose! I've seen you undefined times before. sayHelloTimes2(); // -> Hello Anony Moose! I've seen you undefined times before. ``` As for `= {}`, it covers the case of a missing _object_, for which individual property defaults won't help at all: ```js var sayHelloTimes2a = function ({ name = 'Anony', surname = 'Moose' }, times) { console.log(`Hello ${name} ${surname}! I've seen you ${times} times before.`); }; sayHelloTimes2a({ name: 'Pam' }, 5678); // -> Hello Pam Moose! I've seen you 5678 times before. sayHelloTimes2a(5678); // -> Hello Anony Moose! I've seen you undefined times before. sayHelloTimes2a(); // -> Uncaught TypeError: Cannot match against 'undefined' or 'null'. ``` ##### Availability Note that destructuring assignment may not yet be available by default, in the version of Node.js or browser that you're using. For Node.js, you can try using the `--harmony-destructuring` flag on startup to activate this feature. title: Know the passing mechanism tip-number: 44 tip-username: bmkmanoj tip-username-profile: https://github.com/bmkmanoj tip-tldr: JavaScript technically only passes by value for both primitives and object (or reference) types. In case of reference types the reference value itself is passed by value. - /en/know-the-passing-mechanism/ JavaScript is pass-by-value, technically. It is neither pass-by-value nor pass-by-reference, going by the truest sense of these terms. To understand this passing mechanism, take a look at the following two example code snippets and the explanations. ### Example 1 ```js var me = { // 1 partOf: 'A Team' }; function myTeam(me) { // 2 me = { // 3 belongsTo: 'A Group' }; } myTeam(me); console.log(me); // 4 : {'partOf' : 'A Team'} ``` In above example, when the `myTeam` gets invoked, JavaScript is _passing the reference to_ `me` _object as value, as it is an object_ and invocation itself creates two independent references to the same object, (though the name being same here i.e. `me`, is misleading and gives us an impression that it is the single reference) and hence, the reference variable themselves are independent. When we assigned a new object at #`3`, we are changing this reference value entirely within the `myTeam` function, and it will not have any impact on the original object outside this function scope, from where it was passed and the reference in the outside scope is going to retain the original object and hence the output from #`4`. ### Example 2 ```js var me = { // 1 partOf: 'A Team' }; function myGroup(me) { // 2 me.partOf = 'A Group'; // 3 } myGroup(me); console.log(me); // 4 : {'partOf' : 'A Group'} ``` In the case of `myGroup` invocation, we are passing the object `me`. But unlike the example 1 scenario, we are not assigning this `me` variable to any new object, effectively meaning the object reference value within the `myGroup` function scope still is the original object's reference value and when we are modifying the property within this scope, it is effectively modifying the original object's property. Hence, you get the output from #`4`. So does this later case not prove that javascript is pass-by-reference? No, it does not. Remember, _JavaScript passes the reference as value, in case of objects_. The confusion arises as we tend not to understand fully what pass by reference is. This is the exact reason, some prefer to call this as _call-by-sharing_. _Initially posted by the author on [js-by-examples](https://github.com/bmkmanoj/js-by-examples/blob/master/examples/js_pass_by_value_or_reference.md)_ title: Calculate the Max/Min value from an array tip-number: 45 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: Ways to use the built-in functions Math.max() and Math.min() with arrays of numbers tip-writer-support: https://www.coinbase.com/loverajoel - /en/calculate-the-max-min-value-from-an-array/ The built-in functions [Math.max()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) and [Math.min()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) find the maximum and minimum value of the arguments, respectively. ```js Math.max(1, 2, 3, 4); // 4 Math.min(1, 2, 3, 4); // 1 ``` These functions will not work as-is with arrays of numbers. However, there are some ways around this. [`Function.prototype.apply()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) allows you to call a function with a given `this` value and an _array_ of arguments. ```js var numbers = [1, 2, 3, 4]; Math.max.apply(null, numbers); // 4 Math.min.apply(null, numbers); // 1 ``` Passing the `numbers` array as the second argument of `apply()` results in the function being called with all values in the array as parameters. A simpler, ES2015 way of accomplishing this is with the new [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). ```js var numbers = [1, 2, 3, 4]; Math.max(...numbers); // 4 Math.min(...numbers); // 1 ``` This operator causes the values in the array to be expanded, or "spread", into the function's arguments. title: Detect document ready in pure JS tip-number: 46 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: The cross-browser way to check if the document has loaded in pure JavaScript tip-writer-support: https://www.coinbase.com/loverajoel - /en/detect-document-ready-in-pure-js/ The cross-browser way to check if the document has loaded in pure JavaScript is using [`readyState`](https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState). ```js if (document.readyState === 'complete') { // The page is fully loaded } ``` You can detect when the document is ready... ```js let stateCheck = setInterval(() => { if (document.readyState === 'complete') { clearInterval(stateCheck); // document ready } }, 100); ``` or with [onreadystatechange](https://developer.mozilla.org/en-US/docs/Web/Events/readystatechange)... ```js document.onreadystatechange = () => { if (document.readyState === 'complete') { // document ready } }; ``` Use `document.readyState === 'interactive'` to detect when the DOM is ready. title: Basics declarations tip-number: 47 tip-username: adaniloff tip-username-profile: https://github.com/adaniloff tip-tldr: Understand and work with declarations. - /en/basics-declarations/ Below, different ways to declare variables in JavaScript. Comments and console.log should be enough to explain what's happening here: ```js var y, x = (y = 1); //== var x; var y; x = y = 1 console.log('--> 1:', `x = ${x}, y = ${y}`); // Will print //--> 1: x = 1, y = 1 ``` First, we just set two variables. Nothing much here. ```js (() => { var x = (y = 2); // == var x; x = y = 2; console.log('2.0:', `x = ${x}, y = ${y}`); })(); console.log('--> 2.1:', `x = ${x}, y = ${y}`); // Will print //2.0: x = 2, y = 2 //--> 2.1: x = 1, y = 2 ``` As you can see, the code has only changed the global y, as we haven't declared the variable in the closure. ```js (() => { var x, y = 3; // == var x; var y = 3; console.log('3.0:', `x = ${x}, y = ${y}`); })(); console.log('--> 3.1:', `x = ${x}, y = ${y}`); // Will print //3.0: x = undefined, y = 3 //--> 3.1: x = 1, y = 2 ``` Now we declare both variables through var. Meaning they only live in the context of the closure. ```js (() => { var y, x = (y = 4); // == var x; var y; x = y = 4 console.log('4.0:', `x = ${x}, y = ${y}`); })(); console.log('--> 4.1:', `x = ${x}, y = ${y}`); // Will print //4.0: x = 4, y = 4 //--> 4.1: x = 1, y = 2 ``` Both variables have been declared using var and only after that we've set their values. As local > global, x and y are local in the closure, meaning the global x and y are untouched. ```js x = 5; // == x = 5 console.log('--> 5:', `x = ${x}, y = ${y}`); // Will print //--> 5: x = 5, y = 2 ``` This last line is explicit by itself. You can test this and see the result [thanks to babel](). More informations available on the [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var). Special thanks to @kurtextrem for his collaboration :)! title: How to `reduce()` arrays tip-number: 48 tip-username: darul75 tip-username-profile: https://twitter.com/darul75 tip-tldr: Some reminders about using `reduce()` - /en/reminders-about-reduce-function-usage/ As written in documentation the `reduce()` method applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value. ### Signature [reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) function accepts 2 parameters (M: mandatory, O: optional): - (M) a callback **reducer function** to be applied that deals with a pair of previous (result of previous computation) and next element until end of the list. - (O) an **initial value** to be used as the first argument to the first call of the callback. So let's see a common usage and later a more sophisticated one. ### Common usage (accumulation, concatenation) We are on Amazon website (prices in $) and our caddy is quite full, let's compute total. ```javascript // my current amazon caddy purchases var items = [{ price: 10 }, { price: 120 }, { price: 1000 }]; // our reducer function var reducer = function add(sumSoFar, item) { return sumSoFar + item.price; }; // do the job var total = items.reduce(reducer, 0); console.log(total); // 1130 ``` Optional reduce function parameter was primitive integer type 0 in that first case, but it could have been an Object, an Array...instead of a primitive type, but we will see that later. Now, cool I received a discount coupon of 20$. ```javascript var total = items.reduce(reducer, -20); console.log(total); // 1110 ``` ### Advanced usage (combination) This second usage example is inspired by Redux [combineReducers](http://redux.js.org/docs/api/combineReducers.html) function [source](https://github.com/reactjs/redux/blob/master/src/combineReducers.js#L93). Idea behind is to separate reducer function into separate individual functions and at the end compute a new _single big reducer function_. To illustrate this, let's create a single object literal with some reducers function able to compute total prices in different currency $, €... ```javascript var reducers = { totalInDollar: function (state, item) { // specific statements... return (state.dollars += item.price); }, totalInEuros: function (state, item) { return (state.euros += item.price * 0.897424392); }, totalInPounds: function (state, item) { return (state.pounds += item.price * 0.692688671); }, totalInYen: function (state, item) { return (state.yens += item.price * 113.852); } // more... }; ``` Then, we create a new swiss knife function - responsible for applying each partial reduce functions. - that will return a new callback reducer function ```javascript var combineTotalPriceReducers = function (reducers) { return function (state, item) { return Object.keys(reducers).reduce(function (nextState, key) { reducers[key](state, item); return state; }, {}); }; }; ``` Now let's see how using it. ```javascript var bigTotalPriceReducer = combineTotalPriceReducers(reducers); var initialState = { dollars: 0, euros: 0, yens: 0, pounds: 0 }; var totals = items.reduce(bigTotalPriceReducer, initialState); console.log(totals); /* Object {dollars: 1130, euros: 1015.11531904, yens: 127524.24, pounds: 785.81131152} */ ``` I hope this approach can give you another idea of using reduce() function for your own needs. Your reduce function could handle an history of each computation by instance as it is done in Ramdajs with [scan](http://ramdajs.com/docs/#scan) function [JSFiddle to play with](https://jsfiddle.net/darul75/81tgt0cd/) title: Easiest way to extract unix timestamp in JS tip-number: 49 tip-username: nmrony tip-username-profile: https://github.com/nmrony tip-tldr: In Javascript you can easily get the unix timestamp - /en/extract-unix-timestamp-easily/ We frequently need to calculate with unix timestamp. There are several ways to grab the timestamp. For current unix timestamp easiest and fastest way is ```js const dateTime = Date.now(); const timestamp = Math.floor(dateTime / 1000); ``` or ```js const dateTime = new Date().getTime(); const timestamp = Math.floor(dateTime / 1000); ``` To get unix timestamp of a specific date pass `YYYY-MM-DD` or `YYYY-MM-DDT00:00:00Z` as parameter of `Date` constructor. For example ```js const dateTime = new Date('2012-06-08').getTime(); const timestamp = Math.floor(dateTime / 1000); ``` You can just add a `+` sign also when declaring a `Date` object like below ```js const dateTime = +new Date(); const timestamp = Math.floor(dateTime / 1000); ``` or for specific date ```js const dateTime = +new Date('2012-06-08'); const timestamp = Math.floor(dateTime / 1000); ``` Under the hood the runtime calls `valueOf` method of the `Date` object. Then the unary `+` operator calls `toNumber()` with that returned value. For detailed explanation please check the following links - [Date.prototype.valueOf](http://es5.github.io/#x15.9.5.8) - [Unary + operator](http://es5.github.io/#x11.4.6) - [toNumber()](http://es5.github.io/#x9.3) - [Date Javascript MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) - [Date.parse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) title: Helpful Console Logging Tricks tip-number: 50 tip-username: zackhall tip-username-profile: https://twitter.com/zthall tip-tldr: Helpful logging techniques using coercion and conditonal breakpoints. - /en/helpful-console-log-hacks/ ## Using conditional breakpoints to log data If you wanted to log to the console a value each time a function is called, you can use conditional break points to do this. Open up your dev tools, find the function where you'd like to log data to the console and set a breakpoint with the following condition: ```js console.log(data.value) && false; ``` A conditional breakpoint pauses the page thread only if the condition for the breakpoint evaluates to true. So by using a condition like console.log('foo') && false it's guaranteed to evaluate to false since you're putting the literal false in the AND condition. So this will not pause the page thread when it's hit, but it will log data to the console. This can also be used to count how many times a function or callback is called. Here's how you can set a conditional breakpoint in [Edge](https://dev.windows.com/en-us/microsoft-edge/platform/documentation/f12-devtools-guide/debugger/#setting-and-managing-breakpoints 'Managing Breakpoints in Edge'), [Chrome](https://developer.chrome.com/devtools/docs/javascript-debugging#breakpoints 'Managing Breakpoints in Chrome'), [Firefox](https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Set_a_conditional_breakpoint 'Managing Breakpoints in Firefox') and [Safari](https://developer.apple.com/library/mac/documentation/AppleApplications/Conceptual/Safari_Developer_Guide/Debugger/Debugger.html 'Managing Breakpoints in Safari'). ## Printing a function variable to console Have you ever logged a function variable to the console and weren't able to just view the function's code? The quickest way to see the function's code is to coerce it to a string using concatenation with an empty string. ```js console.log(funcVariable + ''); ``` title: DOM event listening made easy tip-number: 51 tip-username: octopitus tip-username-profile: https://github.com/octopitus tip-tldr: An elegant and easy way to handle DOM events - /en/DOM-event-listening-made-easy/ Many of us are still doing these things: - `element.addEventListener('type', obj.method.bind(obj))` - `element.addEventListener('type', function (event) {})` - `element.addEventListener('type', (event) => {})` The above examples all create new anonymous event handlers that can't be removed when no longer needed. This may cause performance problems or unexpected logic bugs, when handlers that you no longer need still get accidentally triggered through unexpected user interactions or [event bubbling](http://www.javascripter.net/faq/eventbubbling.htm). Safer event-handling patterns include the following: Use a reference: ```js const handler = function () { console.log('Tada!'); }; element.addEventListener('click', handler); // Later on element.removeEventListener('click', handler); ``` Named function that removes itself: ```js element.addEventListener('click', function click(e) { if (someCondition) { return e.currentTarget.removeEventListener('click', click); } }); ``` A better approach: ```js function handleEvent(eventName, { onElement, withCallback, useCapture = false } = {}, thisArg) { const element = onElement || document.documentElement; function handler(event) { if (typeof withCallback === 'function') { withCallback.call(thisArg, event); } } handler.destroy = function () { return element.removeEventListener(eventName, handler, useCapture); }; element.addEventListener(eventName, handler, useCapture); return handler; } // Anytime you need const handleClick = handleEvent('click', { onElement: element, withCallback: (event) => { console.log('Tada!'); } }); // And anytime you want to remove it handleClick.destroy(); ``` title: Return Values with the 'new' Operator tip-number: 52 tip-username: Morklympious tip-username-profile: https://github.com/morklympious tip-tldr: Understand what gets returned when using new vs. not using new. - /en/return-values-with-the-new-operator/ You're going to run into some instances where you'll be using `new` to allocate new objects in JavaScript. It's going to blow your mind unless you read this tip to understand what's happening behind the scenes. The `new` operator in JavaScript is an operator that, under reasonable circumstances, returns a new instance of an object. Let's say we have a constructor function: ```js function Thing() { this.one = 1; this.two = 2; } var myThing = new Thing(); myThing.one; // 1 myThing.two; // 2 ``` **Note**: `this` refers to the new object created by `new`. Otherwise if `Thing()` is called without `new`, **no object is created**, and `this` is going to point to the global object, which is `window`. This means that: 1. You'll suddenly have two new global variables named `one` and `two`. 2. `myThing` is now undefined, since nothing is returned in `Thing()`. Now that you get that example, here's where things get a little bit wonky. Let's say I add something to the constructor function, a little SPICE: ```js function Thing() { this.one = 1; this.two = 2; return 5; } var myThing = new Thing(); ``` Now, what does myThing equal? Is it 5? is it an object? Is it my crippled sense of self-worth? The world may never know! Except the world does know: ```js myThing.one; // 1 myThing.two; // 2 ``` Interestingly enough, we never actually see the five that we supposedly 'returned' from our constructor. That's weird, isn't it? What are you doing function? WHERE'S THE FIVE? Let's try it with something else. Let's return a non-primitive type instead, something like an object. ```js function Thing() { this.one = 1; this.two = 2; return { three: 3, four: 4 }; } var myThing = new Thing(); ``` Let's check it out. A quick console.log reveals all: ```js console.log(myThing); /* Object {three: 3, four: 4} What happened to this.one and this.two!? They've been stomped, my friend. */ ``` **Here's where we learn:** When you invoke a function with the `new` keyword, you can set properties on it using the keyword `this` (but you probably already knew that). Returning a primitive value from a function you called with the `new` keyword will not return the value you specified, but instead will return the `this` instance of the function (the one you put properties on, like `this.one = 1;`). However, returning a non-primitive, like an `object`, `array`, or `function` will stomp on the `this` instance, and return that non-primitive instead, effectively ruining all the hard work you did assigning everything to `this`. title: Get File Extension tip-number: 53 tip-username: richzw tip-username-profile: https://github.com/richzw tip-tldr: How to get the file extension more efficiently? - /en/get-file-extension/ categories: - en - javascript --- ### Question: How to get the file extension? ```javascript var file1 = '50.xsl'; var file2 = '30.doc'; getFileExtension(file1); //returs xsl getFileExtension(file2); //returs doc function getFileExtension(filename) { /*TODO*/ } ``` ### Solution 1: Regular Expression ```js function getFileExtension1(filename) { return /[.]/.exec(filename) ? /[^.]+$/.exec(filename)[0] : undefined; } ``` ### Solution 2: String `split` method ```js function getFileExtension2(filename) { return filename.split('.').pop(); } ``` Those two solutions couldnot handle some edge cases, here is another more robust solution. ### Solution3: String `slice`, `lastIndexOf` methods ```js function getFileExtension3(filename) { return filename.slice(((filename.lastIndexOf('.') - 1) >>> 0) + 2); } console.log(getFileExtension3('')); // '' console.log(getFileExtension3('filename')); // '' console.log(getFileExtension3('filename.txt')); // 'txt' console.log(getFileExtension3('.hiddenfile')); // '' console.log(getFileExtension3('filename.with.many.dots.ext')); // 'ext' ``` _How does it works?_ - [String.lastIndexOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf) method returns the last occurrence of the specified value (`'.'` in this case). Returns `-1` if the value is not found. - The return values of `lastIndexOf` for parameter `'filename'` and `'.hiddenfile'` are `-1` and `0` respectively. [Zero-fill right shift operator (>>>)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#%3E%3E%3E_%28Zero-fill_right_shift%29) will transform `-1` to `4294967295` and `-2` to `4294967294`, here is one trick to insure the filename unchanged in those edge cases. - [String.prototype.slice()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) extracts file extension from the index that was calculated above. If the index is more than the length of the filename, the result is `""`. ### Comparison | Solution | Paramters | Results | | ----------------------------------------- | :-----------------------------------------------------------------------------------------: | :-------------------------------------------------------------------: | | Solution 1: Regular Expression | ''
'filename'
'filename.txt'
'.hiddenfile'
'filename.with.many.dots.ext' | undefined
undefined
'txt'
'hiddenfile'
'ext'
| | Solution 2: String `split` | ''
'filename'
'filename.txt'
'.hiddenfile'
'filename.with.many.dots.ext' | ''
'filename'
'txt'
'hiddenfile'
'ext'
| | Solution 3: String `slice`, `lastIndexOf` | ''
'filename'
'filename.txt'
'.hiddenfile'
'filename.with.many.dots.ext' | ''
''
'txt'
''
'ext'
| ### Live Demo and Performance [Here](https://jsbin.com/tipofu/edit?js,console) is the live demo of the above codes. [Here](http://jsperf.com/extract-file-extension) is the performance test of those 3 solutions. ### Source [How can I get file extensions with JavaScript](http://stackoverflow.com/questions/190852/how-can-i-get-file-extensions-with-javascript) title: How to use optional arguments in functions (with optional callback) tip-number: 54 tip-username: alphashuro tip-username-profile: https://github.com/alphashuro tip-tldr: You can make function arguments and callback optional - /en/use-optional-arguments/ categories: - en - javascript --- Example function where arguments 2 and 3 are optional ```javascript function example(err, optionalA, optionalB, callback) { // retrieve arguments as array var args = new Array(arguments.length); for (var i = 0; i < args.length; ++i) { args[i] = arguments[i]; } // first argument is the error object // shift() removes the first item from the // array and returns it err = args.shift(); // if last argument is a function then its the callback function. // pop() removes the last item in the array // and returns it if (typeof args[args.length - 1] === 'function') { callback = args.pop(); } // if args still holds items, these are // your optional items which you could // retrieve one by one like this: if (args.length > 0) optionalA = args.shift(); else optionalA = null; if (args.length > 0) optionalB = args.shift(); else optionalB = null; // continue as usual: check for errors if (err) { return callback && callback(err); } // for tutorial purposes, log the optional parameters console.log('optionalA:', optionalA); console.log('optionalB:', optionalB); console.log('callback:', callback); /* do your thing */ } // ES6 with shorter, more terse code function example(...args) { // first argument is the error object const err = args.shift(); // if last argument is a function then its the callback function const callback = typeof args[args.length - 1] === 'function' ? args.pop() : null; // if args still holds items, these are your optional items which you could retrieve one by one like this: const optionalA = args.length > 0 ? args.shift() : null; const optionalB = args.length > 0 ? args.shift() : null; // ... repeat for more items if (err && callback) return callback(err); /* do your thing */ } // invoke example function with and without optional arguments example(null, 'AA'); example(null, function (err) { /* do something */ }); example(null, 'AA', function (err) {}); example(null, 'AAAA', 'BBBB', function (err) {}); ``` ### How do you determine if optionalA or optionalB is intended? Design your function to require optionalA in order to accept optionalB title: Create an easy loop using an array tip-number: 55 tip-username: jamet-julien tip-username-profile: https://github.com/jamet-julien tip-tldr: Sometimes, we need to loop endlessly over an array of items, like a carousel of images or an audio playlist. Here's how to take an array and give it "looping powers” - /en/make-easy-loop-on-array/ categories: - en - javascript --- Sometimes, we need to loop endlessly over an array of items, like a carousel of images or an audio playlist. Here's how to take an array and give it "looping powers": ```js var aList = ['A', 'B', 'C', 'D', 'E']; function make_looper(arr) { arr.loop_idx = 0; // return current item arr.current = function () { if (this.loop_idx < 0) { // First verification this.loop_idx = this.length - 1; // update loop_idx } if (this.loop_idx >= this.length) { // second verification this.loop_idx = 0; // update loop_idx } return arr[this.loop_idx]; //return item }; // increment loop_idx AND return new current arr.next = function () { this.loop_idx++; return this.current(); }; // decrement loop_idx AND return new current arr.prev = function () { this.loop_idx--; return this.current(); }; } make_looper(aList); aList.current(); // -> A aList.next(); // -> B aList.next(); // -> C aList.next(); // -> D aList.next(); // -> E aList.next(); // -> A aList.pop(); // -> E aList.prev(); // -> D aList.prev(); // -> C aList.prev(); // -> B aList.prev(); // -> A aList.prev(); // -> D ``` Using the `%` ( Modulus ) operator is prettier.The modulus return division's rest ( ` 2 % 5 = 1` and ` 5 % 5 = 0`): ```js var aList = ['A', 'B', 'C', 'D', 'E']; function make_looper(arr) { arr.loop_idx = 0; // return current item arr.current = function () { this.loop_idx = this.loop_idx % this.length; // no verification !! return arr[this.loop_idx]; }; // increment loop_idx AND return new current arr.next = function () { this.loop_idx++; return this.current(); }; // decrement loop_idx AND return new current arr.prev = function () { this.loop_idx += this.length - 1; return this.current(); }; } make_looper(aList); aList.current(); // -> A aList.next(); // -> B aList.next(); // -> C aList.next(); // -> D aList.next(); // -> E aList.next(); // -> A aList.pop(); // -> E aList.prev(); // -> D aList.prev(); // -> C aList.prev(); // -> B aList.prev(); // -> A aList.prev(); // -> D ``` title: Copy to Clipboard tip-number: 56 tip-username: loverajoel tip-username-profile: https://twitter.com/loverajoel tip-tldr: This week I had to create a common "Copy to Clipboard" button, I've never created one before and I want to share how I made it. tip-writer-support: https://www.coinbase.com/loverajoel - /en/copy-to-clipboard/ categories: - en - javascript --- This is a simple tip, this week I had to create a common "Copy to Clipboard" button, I've never created one before and I want to share how I made it. It's easy, the bad thing is that we must add an `` with the text to be copied to the DOM. Then, we selected the content and execute the copy command with [execCommand](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand). `execCommand('copy')` will copy the actual selected content. Also, this command that now is [supported](http://caniuse.com/#search=execCommand) by all the latest version of browsers, allows us to execute another system commands like `copy`, `cut`, `paste`, and make changes like fonts color, size, and much more. ```js document.querySelector('#input').select(); document.execCommand('copy'); ``` ##### Playground title: Comma operator in JS tip-number: 57 tip-username: bhaskarmelkani tip-username-profile: https://www.twitter.com/bhaskarmelkani tip-tldr: When placed in an expression, it evaluates every expression from left to right and returns the last one. - /en/comma-operaton-in-js/ categories: - en - javascript --- Apart from being just a delimiter, the comma operator allows you to put multiple statements in a place where one statement is expected. Eg:- ```js for (var i = 0, j = 0; i < 5; i++, j++, j++) { console.log('i:' + i + ', j:' + j); } ``` Output:- ```js i:0, j:0 i:1, j:2 i:2, j:4 i:3, j:6 i:4, j:8 ``` When placed in an expression, it evaluates every expression from left to right and returns the right most expression. Eg:- ```js function a() { console.log('a'); return 'a'; } function b() { console.log('b'); return 'b'; } function c() { console.log('c'); return 'c'; } var x = (a(), b(), c()); console.log(x); // Outputs "c" ``` Output:- ```js 'a'; 'b'; 'c'; 'c'; ``` - Note: The comma(`,`) operator has the lowest priority of all javascript operators, so without the parenthesis the expression would become: `(x = a()), b(), c();`. ##### Playground title: Breaking or continuing loop in functional programming tip-number: 58 tip-username: vamshisuram tip-username-profile: https://github.com/vamshisuram tip-tldr: A common task for us is iterate over a list looking for a value or values, but we can't return from inside a loop so we will have to iterate the whole array, even if the item we search is the first in the list, in this tip we will see how to short circuit with `.some` and `.every`. - /en/break-continue-loop-functional/ categories: - en - javascript --- A common requirement of iteration is cancelation. Using `for` loops we can `break` to end iteration early. ```javascript const a = [0, 1, 2, 3, 4]; for (var i = 0; i < a.length; i++) { if (a[i] === 2) { break; // stop the loop } console.log(a[i]); } //> 0, 1 ``` Another common requirement is to close over our variables. A quick approach is to use `.forEach` but then we lack the ability to `break`. In this situation the closest we get is `continue` functionality through `return`. ```javascript [0, 1, 2, 3, 4].forEach(function (val, i) { if (val === 2) { // how do we stop? return true; } console.log(val); // your code }); //> 0, 1, 3, 4 ``` The `.some` is a method on Array prototype. It tests whether some element in the array passes the test implemented by the provided function. If any value is returning true, then it stops executing. Here is a [MDN link](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some) for more details. An example quoted from that link ```javascript const isBiggerThan10 = (numb) => numb > 10; [2, 5, 8, 1, 4].some(isBiggerThan10); // false [12, 5, 8, 1, 4].some(isBiggerThan10); // true ``` Using `.some` we get iteration functionally similar to `.forEach` but with the ability to `break` through `return` instead. ```javascript [0, 1, 2, 3, 4].some(function (val, i) { if (val === 2) { return true; } console.log(val); // your code }); //> 0, 1 ``` You keep returning `false` to make it `continue` to next item. When you return `true`, the loop will `break` and `a.some(..)` will `return` `true`. ```javascript // Array contains 2 const isTwoPresent = [0, 1, 2, 3, 4].some(function (val, i) { if (val === 2) { return true; // break } }); console.log(isTwoPresent); //> true ``` Also there is `.every`, which can be used. We have to return the opposite boolean compared to `.some`. ##### Playground title: ES6, var vs let tip-number: 59 tip-username: richzw tip-username-profile: https://github.com/richzw tip-tldr: In this tip, I will introduce the block-scope difference between keyword var and let. Should I replace var by let? let's take a look - /en/keyword-var-vs-let/ categories: - en - javascript --- ### Overview - The scope of a variable defined with `var` is function scope or declared outside any function, global. - The scope of a variable defined with `let` is block scope. ```js function varvslet() { console.log(i); // i is undefined due to hoisting // console.log(j); // ReferenceError: j is not defined for (var i = 0; i < 3; i++) { console.log(i); // 0, 1, 2 } console.log(i); // 3 // console.log(j); // ReferenceError: j is not defined for (let j = 0; j < 3; j++) { console.log(j); } console.log(i); // 3 // console.log(j); // ReferenceError: j is not defined } ``` ### Difference Details - Variable Hoisting `let` will not hoist to the entire scope of the block they appear in. By contrast, `var` could hoist as below. ```js { console.log(c); // undefined. Due to hoisting var c = 2; } { console.log(b); // ReferenceError: b is not defined let b = 3; } ``` - Closure in Loop `let` in the loop can re-binds it to each iteration of the loop, making sure to re-assign it the value from the end of the previous loop iteration, so it can be used to avoid issue with closures. ```js for (var i = 0; i < 5; ++i) { setTimeout(function () { console.log(i); // output '5' 5 times }, 100); } ``` After replacing `var` with `let` ```js // print 1, 2, 3, 4, 5 for (let i = 0; i < 5; ++i) { setTimeout(function () { console.log(i); // output 0, 1, 2, 3, 4 }, 100); } ``` ### Should I replace `var` with `let`? > NO, `let` is the new block scoping `var`. That statement emphasizes that `let` should replace `var` only when `var` was already signaling > block scoping stylistically. Otherwise, leave `var` alone. `let` improves scoping options in JS, not replaces. `var` is still a useful signal for variables that are used throughout the function. ### `let` compatibility - In server side, such as Node.js, you can safely use the `let` statement now. - In client side, through a transpiler (like [Traceur](https://github.com/google/traceur-compiler)), you can safely use the `let` statement. Otherwise, please consider the browser support [here](http://caniuse.com/#search=let) ### Playground ### More info - [Let keyword vs var keyword](http://stackoverflow.com/questions/762011/let-keyword-vs-var-keyword) - [For and against let](https://davidwalsh.name/for-and-against-let) - [Explanation of `let` and block scoping with for loops](http://stackoverflow.com/questions/30899612/explanation-of-let-and-block-scoping-with-for-loops/30900289#30900289). title: Three useful hacks tip-number: 60 tip-username: leandrosimoes tip-username-profile: https://github.com/leandrosimoes tip-tldr: Three very useful and syntax sugar hacks to speed up your development. - /en/three-useful-hacks/ categories: - en - javascript --- #### Getting array items from behind to front If you want to get the array items from behind to front, just do this: ```javascript var newArray = [1, 2, 3, 4]; console.log(newArray.slice(-1)); // [4] console.log(newArray.slice(-2)); // [3, 4] console.log(newArray.slice(-3)); // [2, 3, 4] console.log(newArray.slice(-4)); // [1, 2, 3, 4] ``` #### Short-circuits conditionals If you have to execute a function just if a condition is `true`, like this: ```javascript if (condition) { dosomething(); } ``` You can use a short-circuit just like this: ```javascript condition && dosomething(); ``` #### Set variable default values using "||" If you have to set a default value to variables, you can simple do this: ```javascript var a; console.log(a); //undefined a = a || 'default value'; console.log(a); //default value a = a || 'new value'; console.log(a); //default value ``` title: Binding objects to functions tip-number: 61 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel tip-tldr: Understanding how to use `Bind` method with objects and functions in JavaScript - /en/binding-objects-to-functions/ categories: - en - javascript --- More than often, we need to bind an object to a function's this object. JS uses the bind method when this is specified explicitly and we need to invoke desired method. ### Bind syntax ```js fun.bind(thisArg[, arg1[, arg2[, ...]]]) ``` ## Parameters **thisArg** `this` parameter value to be passed to target function while calling the `bound` function. **arg1, arg2, ...** Prepended arguments to be passed to the `bound` function while invoking the target function. **Return value** A copy of the given function along with the specified `this` value and initial arguments. ### Bind method in action in JS ```js const myCar = { brand: 'Ford', type: 'Sedan', color: 'Red' }; const getBrand = function () { console.log(this.brand); }; const getType = function () { console.log(this.type); }; const getColor = function () { console.log(this.color); }; getBrand(); // object not bind,undefined getBrand(myCar); // object not bind,undefined getType.bind(myCar)(); // Sedan let boundGetColor = getColor.bind(myCar); boundGetColor(); // Red ``` title: Working With Websocket Timeout tip-number: 63 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel tip-tldr: A trick to control the timeout categories: - en - javascript --- In case of established websocket connection, server or firewall could timeout and terminate the connection after a period of inactivity. To deal with this situation, we send periodic message to the server. To control the timeout we will add two functions in our code : one to make sure connection keep alive and another one to cancel the keep alive. Also we need a common `timerID` variable. Let's have a look on implementation- ```js var timerID = 0; function keepAlive() { var timeout = 20000; if (webSocket.readyState == webSocket.OPEN) { webSocket.send(''); } timerId = setTimeout(keepAlive, timeout); } function cancelKeepAlive() { if (timerId) { clearTimeout(timerId); } } ``` Now as we have both of our desired function for the task, we will place `keepAlive()` function at the end of `onOpen()` method of websocket connection and `cancelKeepAlive()` function at the end of `onClose()` method of websocket connection. Yes! We have perfectly implemented hack for websocket timeout problem. title: 3 Array Hacks tip-number: 64 tip-username: hassanhelfi tip-username-profile: https://twitter.com/hassanhelfi tip-tldr: Arrays are everywhere and with the new spread operators introduced in ECMAScript 6, you can do awesome things with them. In this post I will show you 3 useful tricks you can use when programming. categories: - en - javascript --- Arrays are everywhere in JavaScript and with the new [spread operators](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Spread_operator) introduced in ECMAScript 6, you can do awesome things with them. In this post I will show you 3 useful tricks you can use when programming. ### 1. Iterating through an empty array JavaScript arrays are sparse in nature in that there are a lot of holes in them. Try creating an array using the Array's constructor and you will see what I mean. ```javascript > const arr = new Array(4); [undefined, undefined, undefined, undefined] ``` You may find that iterating over a sparse array to apply a certain transformation is hard. ```javascript > const arr = new Array(4); > arr.map((elem, index) => index); [undefined, undefined, undefined, undefined] ``` To solve this, you can use `Array.apply` when creating the array. ```javascript > const arr = Array.apply(null, new Array(4)); > arr.map((elem, index) => index); [0, 1, 2, 3] ``` ### 2. Passing an empty parameter to a method If you want to call a method and ignore one of its parameters, then JavaScript will complain if you keep it empty. ```javascript > method('parameter1', , 'parameter3'); Uncaught SyntaxError: Unexpected token , ``` A workaround that people usually resort to is to pass either `null` or `undefined`. ```javascript > method('parameter1', null, 'parameter3') // or > method('parameter1', undefined, 'parameter3'); ``` I personally don't like using `null` since JavaScript treats it as an object and that's just weird. With the introduction of spread operators in ES6, there is a neater way of passing empty parameters to a method. As previously mentioned, arrays are sparse in nature and so passing empty values to it is totally okay. We'll use this to our advantage. ```javascript > method(...['parameter1', , 'parameter3']); // works! ``` ### 3. Unique array values I always wonder why the Array constructor does not have a designated method to facilitate the use of unique array values. Spread operators are here for the rescue. Use spread operators with the `Set` constructor to generate unique array values. ```javascript > const arr = [...new Set([1, 2, 3, 3])]; [1, 2, 3] ``` title: Tapping for quick debugging tip-number: 65 tip-username: loverajoel tip-username-profile: https://twitter.com/loverajoel tip-tldr: This little beastie here is tap. A really useful function for quick-debugging chains of function calls, anonymous functions and, actually, whatever you just want to print. tip-md-link: https://github.com/loverajoel/jstips/blob/master/_posts/en/javascript/2017-03-16-tapping-for-quick-debugging.md categories: - en - javascript --- This little beastie here is tap. A really useful function for quick-debugging chains of function calls, anonymous functions and, actually, whatever you just want to print. ```javascript function tap(x) { console.log(x); return x; } ``` Why would you use instead of good old `console.log`? Let me show you an example: ```javascript bank_totals_by_client(bank_info(1, banks), table) .filter((c) => c.balance > 25000) .sort((c1, c2) => (c1.balance <= c2.balance ? 1 : -1)) .map((c) => console.log(`${c.id} | ${c.tax_number} (${c.name}) => ${c.balance}`)); ``` Now, suppose you're getting nothing from this chain (possibly an error). Where is it failing? Maybe `bank_info` isn't returning anything, so we'll tap it: ```javascript bank_totals_by_client(tap(bank_info(1, banks)), table); ``` Depending on our particular implementation, it might print something or not. I'll assume the information that we got from our tapping was correct and therefore, bank_info isn't causing anything. We must then move on to the next chain, filter. ```javascript .filter(c => tap(c).balance > 25000) ``` Are we receiving any c's (clients actually)? If so, then bank_totals_by_client works alright. Maybe it's the condition within the filter? ```javascript .filter(c => tap(c.balance > 25000)) ``` Ah! Sweet, we see nothing but `false` printed, so there's no client with >25000, that's why the function was returning nothing. ## (Bonus) A more advanced tap. ```javascript function tap(x, fn = (x) => x) { console.log(fn(x)); return x; } ``` Now we're talking about a more advanced beast, what if we wanted to perform a certain operation _prior_ to tapping? i.e, we want to access a certain object property, perform a logical operation, etc. with our tapped object? Then we call old good tap with an extra argument, a function to be applied at the moment of tapping. ```javascript tap(3, (x) => x + 2) === 3; // prints 5, but expression evaluates to true, why :-)? ``` title: Recursion, iteration and tail calls in JS tip-number: 67 tip-username: loverajoel tip-username-profile: https://twitter.com/loverajoel tip-tldr: If you've been on the business for some time, you have, most likely, come across the definition of recursion, for which the factorial of a given number `n! = n * n - 1 * ... * 1` is a standard example... tip-md-link: https://github.com/loverajoel/jstips/blob/master/_posts/en/javascript/2017-03-29-recursion-iteration-and-tail-calls-in-js.md categories: - en - javascript --- If you've been on the business for some time, you have, most likely, come across the definition of recursion, for which the factorial of a given number `n! = n * (n - 1) * ... * 1` is a standard example. ```javascript function factorial(n) { if (n === 0) { return 1; } return n * factorial(n - 1); } ``` The example shown above is but the most naive implementation of the factorial function. For the sake of completeness, let's look at how this executes for `n = 6`: - factorial(6) - 6 \* factorial(5) - 5 \* factorial (4) - 4 \* factorial(3) - 3 \* factorial(2) - 2 \* factorial(1) - 1 \* factorial(0) - 1 - (resuming previous execution) 1 \* 1 = 1 - (resuming...) 2 \* 1 = 2 - (...) 3 \* 2 = 6 - ... 4 \* 6 = 24 - 5 \* 24 = 120 - 6 \* 120 = 720 - factorial(6) = 720 Now, we must be very cautious as to what's happening so we can understand what is to come next. When we invoke a function, several things happen at once. The location to which we must return to after calling the function is saved, along with the information of the current frame (i.e, the value of n). Then space is allocated for the new function and a new frame is born. This goes on and on, we keep stacking these frames and then we unwind that stack, replacing function calls with values returned by them. Another thing to notice is the shape of the process generated by our function. You might not be surprised if I call this shape _recursive_. We have, thus, a _recursive process_. Let's take a look at a second implementation of this function. ```javascript function factorial(n, res) { if (n === 0) { return res; } return factorial(n - 1, res * n); } ``` We can encapsulate functionality a bit further by defining an inner function. ```javascript function factorial(n) { function inner_factorial(n, res) { if (n === 0) { return res; } return inner_factorial(n - 1, res * n); } return inner_factorial(n, 1); } ``` Let's take a look at how this gets executed: - factorial(6) - inner anonymous function (iaf) gets called with (n = 6, res = 1) - iaf(5, 1 \* 6) - iaf(4, 6 \* 5) - iaf(3, 30 \* 4) - iaf(2, 120 \* 3) - iaf(1, 360 \* 2) - iaf(0, 720) - 720 - 720 - 720 - 720 - 720 - 720 - 720 - iaf (6, 1) = 720 - factorial(6) = 720 You might notice that we didn't need to perform any calculation after unwinding the stack. We just returned a value. But, according to our rules, we had to save the state as a stack frame, even if it weren't of any use later in the chain. Our rules, however, are not applied to every language out there. In fact, in Scheme it's mandatory for such chains to be optimized with tail call optimization. This ensures that our stack is not filled with unnecessary frames. Our previous calculation would look, thus, this way: - factorial(6) - iaf(6, 1) - iaf(5, 6) - iaf(4, 30) - iaf(3, 120) - iaf(2, 360) - iaf(1, 720) - iaf(0, 720) - 720 Which in turns, looks an awfully lot like ```javascript res = 1; n = 6; while (n > 1) { res = res * n; n--; } ``` This means, we actually have an _iterative process_, even if we're using recursion. How cool is that? The good news is, this is a feature in ES6. As long as your recursive call is in tail position and your function has strict mode, tail call optimization will kick in and save you from having a `maximum stack size exceeded` error. UPDATE Dec 1, 2017: The only major browser with tail call optimization is Safari.1 V8 has an implentation2 but has not shipped it yet3 for the reasons listed. 1: https://kangax.github.io/compat-table/es6/#test-proper_tail_calls_(tail_call_optimisation) 2: https://bugs.chromium.org/p/v8/issues/detail?id=4698 3: https://v8project.blogspot.com/2016/04/es6-es7-and-beyond.html title: Why you should use Object.is() in equality comparison tip-number: 68 tip-username: TarekAlQaddy tip-username-profile: https://github.com/TarekAlQaddy tip-tldr: A good solution for the looseness of equality comparisons in javascript categories: - en - javascript --- We all know that JavaScript is loosely typed and in some cases it fall behind specially when it comes to quality comparison with '==', comparing with '==' gives unexpected results due to whats called coercion or casting "converting one of the 2 operands to the other's type then compare". ```javascript 0 == ' '; //true (null == undefined[1]) == //true true; //true ``` So they provided us with the triple equal operator '===' which is more strict and does not coerce operands, However comparing with '===' is not the best solution you can get: ```javascript NaN === NaN; //false ``` The great news that in ES6 there is the new 'Object.is()' which is better and more precise it has the same features as '===' and moreover it behaves well in some special cases: ```javascript Object.is(0, ' '); //false Object.is(null, undefined); //false Object.is([1], true); //false Object.is(NaN, NaN); //true ``` Mozilla team doesn't think that Object.is is "stricter" than '===', they say that we should think of how this method deal with NaN, -0 and +0 but overall I think it is now a good practice in real applications. Now this table illustrates.. ![differences of operators in equality comparisons javascript](http://i.imgur.com/pCyqkLc.png) ## References: [Equality comparisons and sameness](http://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness) title: Picking and rejecting object properties tip-number: 70 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel tip-tldr: Sometimes we need to whitelist certain attributes from an object, say we've got an array representation of a database table and we need to `select` just a few fields for some function. categories: - en - javascript --- Sometimes we need to whitelist certain attributes from an object, say we've got an array representation of a database table and we need to `select` just a few fields for some function: ```javascript function pick(obj, keys) { return keys.map((k) => (k in obj ? { [k]: obj[k] } : {})).reduce((res, o) => Object.assign(res, o), {}); } const row = { 'accounts.id': 1, 'client.name': 'John Doe', 'bank.code': 'MDAKW213' }; const table = [row, { 'accounts.id': 3, 'client.name': 'Steve Doe', 'bank.code': 'STV12JB' }]; pick(row, ['client.name']); // Get client name table.map((row) => pick(row, ['client.name'])); // Get a list of client names ``` There's a bit of skulduggery going on in pick. First, we `map` a function over the keys that will return, each time, an object with only the attribute pointed by the current key (or an empty object if there's no such attribute in the object). Then, we `reduce` this collection of single-attribute objects by merging the objects. But what if we want to `reject` the attributes? Well, the function changes a bit ```javascript function reject(obj, keys) { return Object.keys(obj) .filter((k) => !keys.includes(k)) .map((k) => Object.assign({}, { [k]: obj[k] })) .reduce((res, o) => Object.assign(res, o), {}); } // or, reusing pick function reject(obj, keys) { const vkeys = Object.keys(obj).filter((k) => !keys.includes(k)); return pick(obj, vkeys); } reject({ a: 2, b: 3, c: 4 }, ['a', 'b']); // => {c: 4} ``` title: Protocols for the Brave tip-number: 73 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel tip-tldr: You might have heard about the old ways gaining hype recently, and we don't mean praying to the gods of the north. Today we're introducing a feature found in Clojure which allows you to define interfaces for your classes. categories: - en - javascript --- You might have heard about the old ways gaining hype recently, and we don't mean praying to the gods of the north. Functional programming is the rediscovered toy which is bringing some sanity to the world of mutable state and global bindings. Today we're introducing a feature found in Clojure which allows you to define interfaces for your classes. Let's look at one-off implementation: ```javascript const protocols = (...ps) => ps.reduce((c, p) => p(c), Object); const Mappable = (klass) => { return class extends klass { map() { throw 'Not implemented'; } }; }; const Foldable = (klass) => { return class extends klass { fold() { throw 'Not implemented'; } }; }; class NaturalNumbers extends protocols(Mappable, Foldable) { constructor() { super(); this.elements = [1, 2, 3, 4, 5, 6, 7, 8, 9]; } map(f) { return this.elements.map(f); } fold(f) { return this.elements.reduce(f, this.elements, 0); } } ``` Yes, we're building a chain of class inheritance up there with that reduce boy. It's pretty cool. We're doing it dynamically! You see, each protocol receives a base class (Object) and extends it somehow returning the new class. The idea is similar to that of interfaces. We supply method signatures for the protocol and make sure we provide implementations for it on our base classes. What's so cool about it? We get to write things like these: ```javascript const map = (f) => (o) => o.map(f); const fold = (f) => (o) => o.fold(f); const compose = (...fns) => fns.reduce((acc, f) => (x) => acc(f(x)), id); ``` Ok, maybe we could have written those two functions without the above fuzz but, now that we know `NaturalNumbers` are `Mappable`, we can call `map` on them and trust it will return the right result. Furthermore, with our third function, we can _compose_ any number of operations defined in protocols cleanly: ```javascript const plus1 = (x) => x + 1; const div5 = (x) => x / 5; const plus_then_div = compose(map(div5), map(plus1)); console.log(plus_then_div(new NaturalNumbers())); // => [ 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2 ] ``` More important, if we know that an object of ours is `Mappable`, we know `map` will work on it. Protocols gives us an idea of what we can do with an object and help us abstract common operations between data types, thus reducing the overhead of dealing with a hundred functions. What is easier? To have a hundred functions for every different object or ten functions that work on a hundred objects? title: Improving your Async functions with WebWorkers tip-number: 74 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel tip-tldr: JS runs in a single thread in the browser, this is the truth. In this tip I'll show you how to unleash the full power of asynchronous processing with Web Workers. categories: - en - javascript --- > JS shall have but one Thread (in the browser at least) > > -- Thus spoke the master programmer. JS runs in a single thread in the browser, this is the truth. Somewhere in its own universe, there exists a Queue which holds messages and functions associated with them. Every time an event (i.e, a user clicks a button) is registered, there's a runtime check to see whether there's any listener attached to that event. If there's one, it will enqueue the message. Otherwise, it will be lost forever. Now, our event loop processes one message at a time, meaning that if you do some CPU intensive operation (i.e, number crunching) this will indeed 'block' the one Thread, rendering our application useless. This is true even for `async` functions, which will be queued as soon as invoked and executed as soon as possible (immediately given the queue is empty). I/O such as requests to external resources are non-blocking though, so you can request a file as large as you want without fear. The associated callback, however, will show the same characteristics of an `async` function. Strategies for processing lots of data vary a lot. You could partition data and set timeouts for processing bits of it a time for example. But to unleash the full power of asynchronous processing, you should use Web Workers. To do so, you separate the processing part in a different file (possibly 'my_worker.js'), create a worker with `newWorker = new Worker('my_worker.js');` and offload the processing to it. ```javascript // my_worker.js const do_a_lot_of_processing = (data) => { .... } onmessage = (e) => { postMessage(do_a_lot_of_processing(e.data)); } // main.js const myWorker = new Worker('my_worker.js'); async function get_useful_data() { const raw_data = await request(some_url); myWorker.postmessage(raw_data); } const show_data => (e) { const data = e.data; ... } myWorker.onmessage(show_data); get_useful_data(); ``` Your mileage may vary of course, and there are many abstractions that can be built upon this model. title: Closures inside loops tip-number: 76 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel tip-tldr: Closure in a loop is an interesting topic and this is the tip to be a master of it categories: - en - javascript --- If you ever come across the likes of ```javascript var funcs = []; for (var i = 0; i < 3; i++) { funcs[i] = function () { console.log('i value is ' + i); }; } for (var k = 0; k < 3; k++) { funcs[k](); } ``` You will notice that the expected output of ``` i value is 0 i value is 1 i value is 2 ``` Doesn't match the actual output which will resemble ``` i value is 3 i value is 3 i value is 3 ``` This is because of how the capturing mechanism of closures work and how `i` is represented internally. To solve this situation you can do as follows: ```javascript for (var i = 0; i < 3; i++) { funcs[i] = (function (value) { console.log('i value is ' + i); })(i); } ``` Which effectively copies i by value by handing it to our closure or ```javascript for (let i = 0; i < 3; i++) { funcs[i] = function () { console.log('i value is ' + i); }; } ``` Where `let` scopes the variable to our `for` loop and produces a new value each iteration, thus `i` will be bound to different values on our closures as expected. title: Immutable structures and cloning tip-number: 78 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel tip-tldr: Object cloning is a tricky, full of edge-cases, endeavor. The reason is simple enough. Objects maintain internal state, and that is much abused. There are countless techniques, or better phrased, countless derivations of the same technique. categories: - en - javascript --- Object cloning is a tricky, full of edge-cases, endeavor. The reason is simple enough. Objects maintain internal state, and that is much abused. There are countless techniques, or better phrased, countless derivations of the same technique. Cloning an object is an indicator that your application is growing, and that you've got a complex object which you'd want to treat as an immutable value, i.e operate on it while maintaining a previous state. If the object is in your control, you're lucky. A bit of refactoring here and there might lead you to a point where you avoid the problem entirely by rethinking your object's structure and behavior. With the rediscovering of functional programming techniques, a myriad of debates have been held about immutable structures and how they offer exactly what you seek for. Mutable state is the root of all evil, some might argue. We encourage to reach **ImmutableJS** by Facebook which provides a nice set of immutable structures free for use. By rethinking your object's inner workings and separating state from behavior, making each function consume a state to produce a new one - much like the Haskell's **State** monad - you will reduce many nuisances. If the object is outside your control, you're partly out of luck. This can be circumvented by creating convoluted computations where you solve for yourself circular references and reach enlightenment. However, as you're using external objects anyways, and they must come, as their name says, from external sources, then you might be more comfortable handling the matter to yet another external library and focus on what matters the most, i.e, your application itself. One such library is [pvorb/clone](https://github.com/pvorb/clone), which has a very simple API. To clone an object you only have to ```javascript var clone = require('clone'); var a = { foo: { bar: 'baz' } }; var b = clone(a); a.foo.bar = 'foo'; console.log(a); // {foo: {bar: 'foo'}} console.log(b); // {foo: {bar: 'baz'}} ``` There are, of course, many more libraries that allow you to do the same such as [Ramda](http://ramdajs.com/docs/#clone), [lodash.clonedeep](https://www.npmjs.com/package/lodash.clonedeep) and [lodash.clone](https://www.npmjs.com/package/lodash.clone). As an end note, if you are serious about dealing with immutable structures, you might want to check **ClojureScript** or (for those that feel that Haskell's worth a shot) **PureScript**. We neither encourage, nor condemn, the use of self made cloning mechanisms. Only noting that considerable work has been done on the area and that you'd probably be better of reusing than reinventing the wheel. title: Looping over arrays tip-number: 79 tip-username: loverajoel tip-username-profile: https://github.com/loverajoel tip-tldr: There's a few methods for looping over arrays in Javascript. We'll start with the classical ones and move towards additions made to the standard. categories: - en - javascript --- # Looping over arrays There's a few methods for looping over arrays in Javascript. We'll start with the classical ones and move towards additions made to the standard. ## while ```javascript let index = 0; const array = [1, 2, 3, 4, 5, 6]; while (index < array.length) { console.log(array[index]); index++; } ``` ## for (classical) ```javascript const array = [1, 2, 3, 4, 5, 6]; for (let index = 0; index < array.length; index++) { console.log(array[index]); } ``` ## forEach ```javascript const array = [1, 2, 3, 4, 5, 6]; array.forEach(function (current_value, index, array) { console.log(`At index ${index} in array ${array} the value is ${current_value}`); }); // => undefined ``` ## map The last construct was useful, however, it doesn't return a new array which might be undesirable for your specific case. `map` solves this by applying a function over every element and then returning the new array. ```javascript const array = [1, 2, 3, 4, 5, 6]; const square = (x) => Math.pow(x, 2); const squares = array.map(square); console.log(`Original array: ${array}`); console.log(`Squared array: ${squares}`); ``` The full signature for `map` is `.map(current_value, index, array)`. ## reduce From MDN: > The reduce() method applies a function against an accumulator and each element > in the array (from left to right) to reduce it to a single value. ```javascript const array = [1, 2, 3, 4, 5, 6]; const sum = (x, y) => x + y; const array_sum = array.reduce(sum, 0); console.log(`The sum of array: ${array} is ${array_sum}`); ``` ## filter Filters elements on an array based on a boolean function. ```javascript const array = [1, 2, 3, 4, 5, 6]; const even = (x) => x % 2 === 0; const even_array = array.filter(even); console.log(`Even numbers in array ${array}: ${even_array}`); ``` ## every Got an array and want to test if a given condition is met in every element? ```javascript const array = [1, 2, 3, 4, 5, 6]; const under_seven = (x) => x < 7; if (array.every(under_seven)) { console.log('Every element in the array is less than 7'); } else { console.log('At least one element in the array was bigger than 7'); } ``` ## some Test if at least one element matches our boolean function. ```javascript const array = [1, 2, 3, 9, 5, 6, 4]; const over_seven = (x) => x > 7; if (array.some(over_seven)) { console.log('At least one element bigger than 7 was found'); } else { console.log('No element bigger than 7 was found'); } ``` title: Hash maps without side effects tip-number: 73 tip-username: bhaskarmelkani tip-username-profile: https://www.twitter.com/bhaskarmelkani tip-tldr: Create hash maps(without side effects) using `Object.create(null)`. categories: - en - javascript --- # Hash maps without side effects When you want to use javascript object as a hash map(purely for storing data), you might want to create it as follows. ```javascript const map = Object.create(null); ``` When creating a map using object literal(`const map = {}`), the map inherits properties from Object by default. It is equivalent to `Object.create(Object.prototype)`. But by doing `Object.create(null)`, we explicitly specify `null` as its prototype. So it have absolutely no properties, not even constructor, toString, hasOwnProperty, etc. so you're free to use those keys in your data structure if you need to. ## Rationale: ```javascript const dirtyMap = {}; const cleanMap = Object.create(null); dirtyMap.constructor // function Object() { [native code] } cleanMap.constructor // undefined // Iterating maps const key; for(key in dirtyMap){ if (dirtyMap.hasOwnProperty(key)) { // Check to avoid iterating over inherited properties. console.log(key + " -> " + dirtyMap[key]); } } for(key in cleanMap){ console.log(key + " -> " + cleanMap[key]); // No need to add extra checks, as the object will always be clean } ``` ## Notes: - Object.create() was introduced in ES5: [Compatibility](http://kangax.github.io/compat-table/es5/) - ES6 introduced some new structures: [Map](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map), [WeakMap](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap), [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) and [Weak Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet) title: Creating immutable objects in native JavaScript tip-number: 74 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: With the latest versions of JavaScript it's possible to create immutable objects. I'll walk you through how to do it in three different ways. categories: - en - javascript --- # Creating immutable objects in native JavaScript Javascript it's a flexible language, you can redefine anything. But when projects get complex we find problems with mutable data structures. With the latest versions of JavaScript this situation changed. Now it's possible to create immutable objects. I'll walk you through how to do it in three different ways. ### Wait, what means immutable? > Immutability in object means we don't want our objects to change in any ways once we create them i.e make them read-only type. Let's suppose we need to define a car [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) and use its properties to perform operations throughout our entire project. We can't allow modifying by mistake any data. ``` const myTesla = { maxSpeed: 250, batteryLife: 300, weight: 023 }; ``` ## [Object.preventExtensions()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions) This method prevents the addition of new properties to our existing object. `preventExtensions()` is a irreversible operation. We can never add extra properties to the object again. ``` Object.isExtensible(myTesla); // true Object.preventExtensions(myTesla); Object.isExtensible(myTesla); // false myTesla.color = 'blue'; console.log(myTesla.color) // undefined ``` ## [Object.seal()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal) It prevents additions or deletion of properties. `seal()` also prevents the modification of property descriptors. ``` Object.isSealed(myTesla); // false Object.seal(myTesla); Object.isSealed(myTesla); // true myTesla.color = 'blue'; console.log(myTesla.color); // undefined delete myTesla.batteryLife; // false console.log(myTesla.batteryLife); // 300 Object.defineProperty(myTesla, 'batteryLife'); // TypeError: Cannot redefine property: batteryLife ``` ## [Object.freeze()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) It does the same that `Object.seal()` plus it makes the properties non-writable. ``` Object.isFrozen(myTesla); // false Object.freeze(myTesla); Object.isFrozen(myTesla); // true myTesla.color = 'blue'; console.log(myTesla.color); // undefined delete myTesla.batteryLife; console.log(myTesla.batteryLife); // 300 Object.defineProperty(myTesla, 'batteryLife'); // TypeError: Cannot redefine property: batteryLife myTesla.batteryLife = 400; console.log(myTesla.batteryLife); // 300 ``` ## Extra Use `strict mode` if you want to throw an error when trying to modify an immutable object. title: What is Functional Inheritance? tip-number: 75 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: Functional inheritance is the process of inheriting features by applying an augmenting function to an object instance. categories: - en - javascript --- Functional inheritance is the process of inheriting features by applying an augmenting function to an object instance. The function supplies a closure scope which you can use to keep some data private. The augmenting function uses dynamic object extension to extend the object instance with new properties and methods. Functional mixins are composable factory functions that add properties and behaviors to objects like stations in an assembly line. ```javascript // Base object constructor function function Animal(data) { var that = {}; // Create an empty object that.name = data.name; // Add it a "name" property return that; // Return the object } // Create achild object, inheriting from the base Animal function Cat(data) { // Create the Animal object var that = Animal(data); // Extend base object that.sayHello = function () { return "Hello, I'm " + that.name; }; return that; } // Usage var myCat = Cat({ name: 'Rufi' }); console.log(myCat.sayHello()); // Output: "Hello, I'm Rufi" ``` title: What is a currying function? tip-number: 75 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: A currying function is a function that takes multiple arguments and turns it into a sequence of functions having only one argument at a time. categories: - en - javascript --- A currying function is a function that takes multiple arguments and turns it into a sequence of functions having only one argument at a time. In this way, an n-ary function becomes a unary function, and the last function returns the result of all the arguments together in a function. ```javascript // Normal definition function multiply(a, b, c) { return a * b * c; } console.log(multiply(1, 2, 3)); // Output: 6 // Simple curry function definition function multiply(a) { return (b) => { return (c) => { return a * b * c; }; }; } console.log(multiply(1)(2)(3)); // Output: 6 ``` ### Further readings: - [Currying in JavaScript](https://dev.to/suprabhasupi/currying-in-javascript-1k3l) - [Lodash curry](https://lodash.com/docs/#curry) - [JavaScript currying](http://zetcode.com/javascript/currying/) title: What is the Temporal Dead Zone? tip-number: 76 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: Temporal Dead Zone is a JavaScript behavior while using variables declared using `let` and `const` keywords. categories: - en - javascript --- Temporal Dead Zone is a JavaScript behavior while using variables declared using `let` and `const` keywords. Since the keywords are block-scoped, the variables declared these keywords could not be accessed before the declaration, and then you will have to witness where variables will be said to be `undefined`. ```javascript function myFunc() { console.log(greeting); var greeting = 'Hello World!'; } myFunc(); // Output: undefined function myFunc() { console.log(greeting); let greeting = 'Hello World!'; } myFunc(); // Output: ReferenceError: greeting is not defined function myFunc() { console.log(greeting); const greeting = 'Hello World!'; } myFunc(); // Output: ReferenceError: greeting is not defined ``` title: What is the difference between Target and currentTarget in the event context? tip-number: 77 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: target refers to the element that triggers an event. currentTarget to the element that the event listener is listening on. categories: - en - javascript --- `target` refers to the DOM element that triggers an event. Otherwise, `currentTarget` refers to the DOM element that the event listener is listening on. ```html
  • Walk your dog
``` ```js const list = document.querySelector('.todo-list'); list.addEventListener('click', (e) => { console.log(e.target); // Output:
  • Walk your dog
  • console.log(e.currentTarget); // Output:
      }); ``` title: What is a spread operator? tip-number: 78 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: The spread operator is a useful syntax for manipulating arrays and objects. categories: - en - javascript --- The spread operator in JavaScript is a useful syntax for adding elements to an array, combining arrays into one larger one, spreading an array inside the arguments of a function, and more. ```js // Concatenating arrays and objects let arr1 = [1, 2, 3]; let arr2 = [4, 5]; let newArray = [...arr1, ...arr2]; console.log(newArray); // Output: [ 1, 2, 3, 4, 5 ] // Copying array elements let arr = ['a', 'b', 'c']; let newArray = [...arr]; console.log(newArray); // Output: ["a", "b", "c"] // Expanding arrays let arr = ['a', 'b']; let newArray = [...arr, 'c', 'd']; console.log(newArray); // Output: ["a", "b", "c", "d"] // Merging objects const userBasic = { name: 'Jen', age: 22 }; const userMoreInfo = { country: 'Argentina', city: 'Córdoba' }; const user = { ...userBasic, ...userMoreInfo }; // Output: { name: "Jen", age: 22, country: "Argentina", city: "Córdoba" } ``` title: What is a void operator? tip-number: 79 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: The void operator returns an undefined value from an evaluated expression categories: - en - javascript --- The `void` operator returns an `undefined` value from an evaluated expression, or in other words; the `void` operator specifies an expression to be evaluated without returning a value. It is commonly used in client-side JavaScript, where the browser should not display the value. ```js function getYear() { return 2020; } console.log(getYear()); // Output: 2020 console.log(void getYear()); // Output: undefined // Useful use case button.onclick = () => void getYear(); ``` --- layout: post title: What is the promise executor? tip-number: 80 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: The method received as an argument for the promise. categories: - en - javascript --- All `Promise` instances accept a method as an argument called the executor. This executor takes two methods as arguments: resolve and reject. Within the executor, if resolve is called, the `Promise` instance becomes fulfilled. If an exception is thrown, reject is called instead, and the `Promise` instance becomes rejected. ```js const executor = (resolve, reject) => { setTimeout(() => resolve("I'm done"), 1000); }; new Promise(executor).then((result) => { console.log(result); // Output after 1000ms: I'm done }); ``` --- layout: post title: What is the JavaScript ternary operator? tip-number: 81 tip-username: loverajoel tip-username-profile: https://www.twitter.com/loverajoel tip-tldr: The ternary operator is a shortcut for the if statement. categories: - en - javascript --- The ternary operator is a shortcut for the `if` statement. It consists of three operands; a question mark, a condition, and an expression to execute if the condition is true, followed by a colon and another expression to execute if it's false. ```js let age = 26; // condition ? expression if true : expression if false let drink = age >= 21 ? 'Beer' : 'Juice'; console.log(drink); // "Beer" // Equivalent to: let drink; if (age >= 21) { drink = 'Beer'; } else { drink = 'Juice'; } console.log(drink); // "Beer" ``` # About the JavaScript reference The JavaScript reference serves as a repository of facts about the JavaScript language. The entire language is described here in detail. As you write JavaScript code, you'll refer to these pages often (thus the title "JavaScript reference"). If you're learning JavaScript, or need help understanding some of its capabilities or features, check out the [JavaScript guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide). The JavaScript language is intended to be used within some larger environment, be it a browser, server-side scripts, or similar. For the most part, this reference attempts to be environment-agnostic and does not target a web browser environment. ## Where to find JavaScript information JavaScript documentation of core language features (pure [ECMAScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Language_Resources), for the most part) includes the following: - The [JavaScript guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide) - The [JavaScript reference](index) If you are new to JavaScript, start with the [guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide). Once you have a firm grasp of the fundamentals, you can use the [reference](index) to get more details on individual objects and language constructs. ## Structure of the reference In the JavaScript reference you can find the following chapters: [Standard built-in objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects) This chapter documents all the JavaScript standard built-in objects, along with their methods and properties. [Statements and declarations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements) JavaScript applications consist of statements with an appropriate syntax. A single statement may span multiple lines. Multiple statements may occur on a single line if each statement is separated by a semicolon. This isn't a keyword, but a group of keywords. [Expressions and operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators) This chapter documents all the JavaScript language operators, expressions and keywords. Functions Chapter about JavaScript functions. [Classes](classes) Chapter about JavaScript classes introduced in ECMAScript 2015. [Errors](errors) Chapter about specific errors, exceptions and warnings thrown by JavaScript. [New in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_in_JavaScript) Chapter about JavaScript version history. ### More reference pages - [Deprecated and obsolete features](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features) - [Lexical grammar](lexical_grammar) - [Data types and data structures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/About # Math.abs() The `Math.abs()` function returns the absolute value of a number. That is, it returns `x` if `x` is positive or zero, and the negation of `x` if `x` is negative. ## Syntax Math.abs(x) ### Parameters `x` A number. ### Return value The absolute value of the given number. ## Description Because `abs()` is a static method of `Math`, you always use it as `Math.abs()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Behavior of Math.abs() Passing an empty object, an array with more than one member, a non-numeric string or [`undefined`](../undefined)/empty variable returns [`NaN`](../nan). Passing [`null`](../null), an empty string or an empty array returns 0. Math.abs('-1'); // 1 Math.abs(-2); // 2 Math.abs(null); // 0 Math.abs(''); // 0 Math.abs([]); // 0 Math.abs([2]); // 2 Math.abs([1,2]); // NaN Math.abs({}); // NaN Math.abs('string'); // NaN Math.abs(); // NaN ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Math.abs' in that specification.
      `abs` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`Math.ceil()`](ceil) - [`Math.floor()`](floor) - [`Math.round()`](round) - [`Math.sign()`](sign) - [`Math.trunc()`](trunc) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs # Math.acos() The `Math.acos()` function returns the arccosine (in radians) of a number, that is ∀*x* ∈ \[ − 1; 1\], `Math.acos` ` (``x``) ` = arccos (_x_) = the unique *y* ∈ \[0; *π*\] such that cos (_y_) = *x* ## Syntax Math.acos(x) ### Parameters `x` A number representing a cosine, where `x` is between `-1` and `1`. ### Return value The arccosine (angle in radians) of the given number if it's between `-1` and `1`; otherwise, [`NaN`](../nan). ## Description The `Math.acos()` method returns a numeric value between 0 and π radians for `x` between -1 and 1. If the value of `x` is outside this range, it returns [`NaN`](../nan). Because `acos()` is a static method of `Math`, you always use it as `Math.acos()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.acos() Math.acos(-2); // NaN Math.acos(-1); // 3.141592653589793 Math.acos(0); // 1.5707963267948966 Math.acos(0.5); // 1.0471975511965979 Math.acos(1); // 0 Math.acos(2); // NaN For values less than -1 or greater than 1, `Math.acos()` returns [`NaN`](../nan). ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.acos
      `acos` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`Math.asin()`](asin) - [`Math.atan()`](atan) - [`Math.atan2()`](atan2) - [`Math.cos()`](cos) - [`Math.sin()`](sin) - [`Math.tan()`](tan) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acos # Math.acosh() The `Math.acosh()` function returns the hyperbolic arc-cosine of a number, that is ∀*x* ≥ 1, `Math.acosh` ` (``x``) ` = arcosh (_x_) = the unique *y* ≥ 0 such that cosh (_y_) = *x* ## Syntax Math.acosh(x) ### Parameters `x` A number. ### Return value The hyperbolic arc-cosine of the given number. If the number is less than **1**, [`NaN`](../nan). ## Description Because `acosh()` is a static method of `Math`, you always use it as `Math.acosh()`, rather than as a method of a `Math` object you created (`Math` is no constructor). ## Examples ### Using Math.acosh() Math.acosh(-1); // NaN Math.acosh(0); // NaN Math.acosh(0.5); // NaN Math.acosh(1); // 0 Math.acosh(2); // 1.3169578969248166 For values less than 1 `Math.acosh()` returns [`NaN`](../nan). ## Polyfill For all *x* ≥ 1, we have $\\operatorname{arcosh}(x) = \\ln\\left( {x + \\sqrt{x^{2} - 1}} \\right)$ and so this can be emulated with the following function: Math.acosh = Math.acosh || function(x) { return Math.log(x + Math.sqrt(x * x - 1)); }; ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.acosh
      `acosh` 38 12 25 No 25 8 38 38 25 25 8 3.0 ## See also - [`Math.asinh()`](asinh) - [`Math.atanh()`](atanh) - [`Math.cosh()`](cosh) - [`Math.sinh()`](sinh) - [`Math.tanh()`](tanh) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh # Atomics.add() The static ` Atomics``.add() ` method adds a given value at a given position in the array and returns the old value at that position. This atomic operation guarantees that no other write happens until the modified value is written back. ## Syntax Atomics.add(typedArray, index, value) ### Parameters `typedArray` An integer typed array. One of [`Int8Array`](../int8array), [`Uint8Array`](../uint8array), [`Int16Array`](../int16array), [`Uint16Array`](../uint16array), [`Int32Array`](../int32array), [`Uint32Array`](../uint32array), [`BigInt64Array`](../bigint64array), or [`BigUint64Array`](../biguint64array). `index` The position in the `typedArray` to add a `value` to. `value` The number to add. ### Return value The old value at the given position (`typedArray[index]`). ### Exceptions - Throws a [`TypeError`](../typeerror), if `typedArray` is not one of the allowed integer types. - Throws a [`RangeError`](../rangeerror), if `index` is out of bounds in the `typedArray`. ## Examples ### Using add() const sab = new SharedArrayBuffer(1024); const ta = new Uint8Array(sab); Atomics.add(ta, 0, 12); // returns 0, the old value Atomics.load(ta, 0); // 12 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-atomics.add
      `add` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. ## See also - [`Atomics`](../atomics) - [`Atomics.sub()`](sub) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/add # Addition (+) The addition operator (`+`) produces the sum of numeric operands or string concatenation. ## Syntax Operator: x + y ## Examples ### Numeric addition // Number + Number -> addition 1 + 2 // 3 // Boolean + Number -> addition true + 1 // 2 // Boolean + Boolean -> addition false + false // 0 ### String concatenation // String + String -> concatenation 'foo' + 'bar' // "foobar" // Number + String -> concatenation 5 + 'foo' // "5foo" // String + Boolean -> concatenation 'foo' + false // "foofalse" ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Addition operator' in that specification.
      `Addition` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Subtraction operator](subtraction) - [Division operator](division) - [Multiplication operator](multiplication) - [Remainder operator](remainder) - [Exponentiation operator](exponentiation) - [Increment operator](increment) - [Decrement operator](decrement) - [Unary negation operator](unary_negation) - [Unary plus operator](unary_plus) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition # AggregateError The `AggregateError` object represents an error when several errors need to be wrapped in a single error. It is thrown when multiple errors need to be reported by an operation, for example by [`Promise.any()`](promise/any), when all promises passed to it reject. ## Constructor [`AggregateError()`](aggregateerror/aggregateerror) Creates a new `AggregateError` object. ## Instance properties [`AggregateError.prototype.message`](error/message) Error message, defaults to `""`. [`AggregateError.prototype.name`](error/name) Error name, defaults to `AggregateError`. ## Examples ### Catching an AggregateError Promise.any([ Promise.reject(new Error("some error")), ]).catch(e => { console.log(e instanceof AggregateError); // true console.log(e.message); // "All Promises rejected" console.log(e.name); // "AggregateError" console.log(e.errors); // [ Error: "some error" ] }); ### Creating an AggregateError try { throw new AggregateError([ new Error("some error"), ], 'Hello'); } catch (e) { console.log(e instanceof AggregateError); // true console.log(e.message); // "Hello" console.log(e.name); // "AggregateError" console.log(e.errors); // [ Error: "some error" ] } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-aggregate-error-objects
      `AggregateError` 85 85 79 No No 14 85 85 79 No 14 No `AggregateError` 85 85 79 No No 14 85 85 79 No 14 No ## See also - [`Error`](error) - [`Promise.any`](promise/any) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError # Promise.all() The `Promise.all()` method takes an iterable of promises as an input, and returns a single [`Promise`](../promise) that resolves to an array of the results of the input promises. This returned promise will resolve when all of the input's promises have resolved, or if the input iterable contains no promises. It rejects immediately upon any of the input promises rejecting or non-promises throwing an error, and will reject with this first rejection message / error. ## Syntax Promise.all(iterable); ### Parameters `iterable` An [iterable](../../iteration_protocols#the_iterable_protocol) object such as an [`Array`](../array). ### Return value - An **already resolved** [`Promise`](../promise) if the iterable passed is empty. - An **asynchronously resolved** [`Promise`](../promise) if the iterable passed contains no promises. Note, Google Chrome 58 returns an **already resolved** promise in this case. - A **pending** [`Promise`](../promise) in all other cases. This returned promise is then resolved/rejected **asynchronously** (as soon as the stack is empty) when all the promises in the given iterable have resolved, or if any of the promises reject. See the example about "Asynchronicity or synchronicity of Promise.all" below. Returned values will be in order of the Promises passed, regardless of completion order. ## Description This method can be useful for aggregating the results of multiple promises. It is typically used when there are multiple related asynchronous tasks that the overall code relies on to work successfully — all of whom we want to fulfill before the code execution continues. `Promise.all()` will reject immediately upon **any** of the input promises rejecting. In comparison, the promise returned by [`Promise.allSettled()`](allsettled) will wait for all input promises to complete, regardless of whether or not one rejects. Consequently, it will always return the final result of every promise and function from the input iterable. ### Fulfillment The returned promise is fulfilled with an array containing **all** the resolved values (including non-promise values) in the iterable passed as the argument. - If an empty iterable is passed, then the promise returned by this method is fulfilled synchronously. The resolved value is an empty array. - If a nonempty _iterable_ is passed, and **all** of the promises fulfill, or are not promises, then the promise returned by this method is fulfilled asynchronously. ### Rejection If any of the passed-in promises reject, `Promise.all` asynchronously rejects with the value of the promise that rejected, whether or not the other promises have resolved. ## Examples ### Using `Promise.all` `Promise.all` waits for all fulfillments (or the first rejection). var p1 = Promise.resolve(3); var p2 = 1337; var p3 = new Promise((resolve, reject) => { setTimeout(() => { resolve("foo"); }, 100); }); Promise.all([p1, p2, p3]).then(values => { console.log(values); // [3, 1337, "foo"] }); If the iterable contains non-promise values, they will be ignored, but still counted in the returned promise array value (if the promise is fulfilled): // this will be counted as if the iterable passed is empty, so it gets fulfilled var p = Promise.all([1,2,3]); // this will be counted as if the iterable passed contains only the resolved promise with value "444", so it gets fulfilled var p2 = Promise.all([1,2,3, Promise.resolve(444)]); // this will be counted as if the iterable passed contains only the rejected promise with value "555", so it gets rejected var p3 = Promise.all([1,2,3, Promise.reject(555)]); // using setTimeout we can execute code after the stack is empty setTimeout(function() { console.log(p); console.log(p2); console.log(p3); }); // logs // Promise { : "fulfilled", : Array[3] } // Promise { : "fulfilled", : Array[4] } // Promise { : "rejected", : 555 } ### Asynchronicity or synchronicity of `Promise.all` This following example demonstrates the asynchronicity (or synchronicity, if the iterable passed is empty) of `Promise.all`: // we are passing as argument an array of promises that are already resolved, // to trigger Promise.all as soon as possible var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)]; var p = Promise.all(resolvedPromisesArray); // immediately logging the value of p console.log(p); // using setTimeout we can execute code after the stack is empty setTimeout(function() { console.log('the stack is now empty'); console.log(p); }); // logs, in order: // Promise { : "pending" } // the stack is now empty // Promise { : "fulfilled", : Array[2] } The same thing happens if `Promise.all` rejects: var mixedPromisesArray = [Promise.resolve(33), Promise.reject(44)]; var p = Promise.all(mixedPromisesArray); console.log(p); setTimeout(function() { console.log('the stack is now empty'); console.log(p); }); // logs // Promise { : "pending" } // the stack is now empty // Promise { : "rejected", : 44 } But, `Promise.all` resolves synchronously **if and only if** the iterable passed is empty: var p = Promise.all([]); // will be immediately resolved var p2 = Promise.all([1337, "hi"]); // non-promise values will be ignored, but the evaluation will be done asynchronously console.log(p); console.log(p2) setTimeout(function() { console.log('the stack is now empty'); console.log(p2); }); // logs // Promise { : "fulfilled", : Array[0] } // Promise { : "pending" } // the stack is now empty // Promise { : "fulfilled", : Array[2] } ### `Promise.all` fail-fast behavior `Promise.all` is rejected if any of the elements are rejected. For example, if you pass in four promises that resolve after a timeout and one promise that rejects immediately, then `Promise.all` will reject immediately. var p1 = new Promise((resolve, reject) => { setTimeout(() => resolve('one'), 1000); }); var p2 = new Promise((resolve, reject) => { setTimeout(() => resolve('two'), 2000); }); var p3 = new Promise((resolve, reject) => { setTimeout(() => resolve('three'), 3000); }); var p4 = new Promise((resolve, reject) => { setTimeout(() => resolve('four'), 4000); }); var p5 = new Promise((resolve, reject) => { reject(new Error('reject')); }); // Using .catch: Promise.all([p1, p2, p3, p4, p5]) .then(values => { console.log(values); }) .catch(error => { console.error(error.message) }); //From console: //"reject" It is possible to change this behavior by handling possible rejections: var p1 = new Promise((resolve, reject) => { setTimeout(() => resolve('p1_delayed_resolution'), 1000); }); var p2 = new Promise((resolve, reject) => { reject(new Error('p2_immediate_rejection')); }); Promise.all([ p1.catch(error => { return error }), p2.catch(error => { return error }), ]).then(values => { console.log(values[0]) // "p1_delayed_resolution" console.error(values[1]) // "Error: p2_immediate_rejection" }) ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-promise.all
      `all` 32 12 29 No 19 8 4.4.3 32 29 19 8 2.0 ## See also - [`Promise`](../promise) - [`Promise.race()`](race) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all # Promise.allSettled() The `Promise.allSettled()` method returns a promise that resolves after all of the given promises have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise. It is typically used when you have multiple asynchronous tasks that are not dependent on one another to complete successfully, or you'd always like to know the result of each promise. In comparison, the Promise returned by [`Promise.all()`](all) may be more appropriate if the tasks are dependent on each other / if you'd like to immediately reject upon any of them rejecting. ## Syntax Promise.allSettled(iterable); ### Parameters `iterable` An [iterable](../../iteration_protocols) object, such as an [`Array`](../array), in which each member is a `Promise`. ### Return value A **pending** [`Promise`](../promise) that will be **asynchronously** fulfilled once every promise in the specified collection of promises has completed, either by successfully being fulfilled or by being rejected. At that time, the returned promise's handler is passed as input an array containing the outcome of each promise in the original set of promises. However, **if and only if** an empty iterable is passed as an argument, `Promise.allSettled()` returns a `Promise` object that has **already been resolved** as an empty array. For each outcome object, a `status` string is present. If the status is `fulfilled`, then a `value` is present. If the status is `rejected`, then a `reason` is present. The value (or reason) reflects what value each promise was fulfilled (or rejected) with. ## Examples ### Using Promise.allSettled Promise.allSettled([ Promise.resolve(33), new Promise(resolve => setTimeout(() => resolve(66), 0)), 99, Promise.reject(new Error('an error')) ]) .then(values => console.log(values)); // [ // {status: "fulfilled", value: 33}, // {status: "fulfilled", value: 66}, // {status: "fulfilled", value: 99}, // {status: "rejected", reason: Error: an error} // ] ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-promise.allsettled
      `allSettled` 76 79 71 No 63 13 76 76 79 54 13 12.0 ## See also - [Promises](https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Techniques/Promises) - [Using promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises) - [Graceful asynchronous programming with promises](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Promises) - [`Promise`](../promise) - [`Promise.all()`](all) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled # Warning: -file- is being assigned a //\# sourceMappingURL, but already has one The JavaScript warning "-file- is being assigned a //\# sourceMappingURL, but already has one." occurs when a source map has been specified more than once for a given JavaScript source. ## Message Warning: -file- is being assigned a //# sourceMappingURL, but already has one. ## Error type A warning. JavaScript execution won't be halted. ## What went wrong? A source map has been specified more than once for a given JavaScript source. JavaScript sources are often combined and minified to make delivering them from the server more efficient. With [source maps](https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/), the debugger can map the code being executed to the original source files. There are two ways to assign a source map, either by using a comment or by setting a header to the JavaScript file. ## Examples ### Setting source maps Setting a source map by using a comment in the file: //# sourceMappingURL=http://example.com/path/to/your/sourcemap.map Or, alternatively, you can set a header to your JavaScript file: X-SourceMap: /path/to/file.js.map ## See also - [How to use a source map – Firefox Tools documentation](https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map) - [Introduction to source maps – HTML5 rocks](https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Already_has_pragma # String.prototype.anchor() **Deprecated** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the [compatibility table](#browser_compatibility) at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time. The `anchor()` method creates a string beginning with an `` start tag, then some text, and then an `` end tag. **Warning:** Don't use this method. Use [DOM APIs](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) instead. Also, the HTML specification no longer allows the [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) element to have a `name` attribute, so this method doesn't even create valid markup. ## Syntax anchor(name) ### Parameters `name` A string representing a `name` value to put into the generated `` start tag. ### Return value A string beginning with an `` start tag, then the text str, and then an `` end tag. ## Description Don't use this method. Use [DOM APIs](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) instead. Also, the HTML specification no longer allows the [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) element to have a `name` attribute, so this method doesn't even create valid markup. ## Examples ### Using anchor() var myString = 'Table of Contents'; document.body.innerHTML = myString.anchor('contents_anchor'); will output the following HTML: Table of Contents ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-string.prototype.anchor
      `anchor` 1 12 1 Starting with version 17, the quotation mark (") is replaced by its HTML reference character (`"`) in strings supplied for the `name` parameter. No 3 1 1 18 4 10.1 1 1.0 ## See also - [`String.prototype.link()`](link) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/anchor # Atomics.and() The static ` Atomics``.and() ` method computes a bitwise AND with a given value at a given position in the array, and returns the old value at that position. This atomic operation guarantees that no other write happens until the modified value is written back. ## Syntax Atomics.and(typedArray, index, value) ### Parameters `typedArray` An integer typed array. One of [`Int8Array`](../int8array), [`Uint8Array`](../uint8array), [`Int16Array`](../int16array), [`Uint16Array`](../uint16array), [`Int32Array`](../int32array), [`Uint32Array`](../uint32array), [`BigInt64Array`](../bigint64array), or [`BigUint64Array`](../biguint64array). `index` The position in the `typedArray` to compute the bitwise AND. `value` The number to compute the bitwise AND with. ### Return value The old value at the given position (`typedArray[index]`). ### Exceptions - Throws a [`TypeError`](../typeerror), if `typedArray` is not one of the allowed integer types. - Throws a [`RangeError`](../rangeerror), if `index` is out of bounds in the `typedArray`. ## Description The bitwise AND operation only yields 1, if both `a` and `b` are 1. The truth table for the AND operation is:
      aba & b
      000
      010
      100
      111
      For example, a bitwise AND of `5 & 1` results in `0001` which is 1 in decimal. 5 0101 1 0001 ---- 1 0001 ## Examples ### Using and() const sab = new SharedArrayBuffer(1024); const ta = new Uint8Array(sab); ta[0] = 5; Atomics.and(ta, 0, 1); // returns 0, the old value Atomics.load(ta, 0); // 1 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-atomics.and
      `and` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. ## See also - [`Atomics`](../atomics) - [`Atomics.or()`](or) - [`Atomics.xor()`](xor) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/and # Promise.any() `Promise.any()` takes an iterable of [`Promise`](../promise) objects and, as soon as one of the promises in the iterable fulfills, returns a single promise that resolves with the value from that promise. If no promises in the iterable fulfill (if all of the given promises are rejected), then the returned promise is rejected with an [`AggregateError`](../aggregateerror), a new subclass of [`Error`](../error) that groups together individual errors. Essentially, this method is the opposite of [`Promise.all()`](all). ## Syntax Promise.any(iterable); ### Parameters `iterable` An [iterable](../../iteration_protocols#the_iterable_protocol) object, such as an [`Array`](../array). ### Return value - An **already rejected** [`Promise`](../promise) if the iterable passed is empty. - An **asynchronously resolved** [`Promise`](../promise) if the iterable passed contains no promises. - A **pending** [`Promise`](../promise) in all other cases. This returned promise is then resolved/rejected **asynchronously** (as soon as the stack is empty) when any of the promises in the given iterable resolve, or if all the promises have rejected. ## Description This method is useful for returning the first promise that fulfills. It short-circuits after a promise fulfills, so it does not wait for the other promises to complete once it finds one. Unlike [`Promise.all()`](all), which returns an _array_ of fulfillment values, we only get one fulfillment value (assuming at least one promise fulfills). This can be beneficial if we need only one promise to fulfill but we do not care which one does. Note another difference: This method rejects upon receiving an _empty iterable_, since, truthfully, the iterable contains no items that fulfill. Also, unlike [`Promise.race()`](race), which returns the first _settled_ value (either fulfillment or rejection), this method returns the first _fulfilled_ value. This method will ignore all rejected promises up until the first promise that fulfils. ### Fulfillment The returned promise is fulfilled with **the first** resolved value (or non-promise value) in the iterable passed as the argument, whether or not the other promises have rejected. - If a nonempty _iterable_ is passed, and **any** of the promises fulfill, or are not promises, then the promise returned by this method is fulfilled asynchronously. ### Rejection If all of the passed-in promises reject, `Promise.any` asynchronously rejects with an [`AggregateError`](../aggregateerror) object, which extends [`Error`](../error), and contains an `errors` property with an array of rejection values. - If an empty iterable is passed, then the promise returned by this method is rejected synchronously. The rejected reason is an `AggregateError` object whose `errors` property is an empty array. ## Examples ### First to fulfil `Promise.any()` resolves with the first promise to fulfil, even if a promise rejects first. This is in contrast to [`Promise.race()`](race), which resolves or rejects with the first promise to settle. const pErr = new Promise((resolve, reject) => { reject("Always fails"); }); const pSlow = new Promise((resolve, reject) => { setTimeout(resolve, 500, "Done eventually"); }); const pFast = new Promise((resolve, reject) => { setTimeout(resolve, 100, "Done quick"); }); Promise.any([pErr, pSlow, pFast]).then((value) => { console.log(value); // pFast fulfils first }) // expected output: "Done quick" ### Rejections with AggregateError `Promise.any()` rejects with an [`AggregateError`](../aggregateerror) if no promise fulfils. const pErr = new Promise((resolve, reject) => { reject('Always fails'); }); Promise.any([pErr]).catch((err) => { console.log(err); }) // expected output: "AggregateError: No Promise in Promise.any was resolved" ### Displaying the first image loaded In this example, we have a function that fetches an image and returns a blob. We use `Promise.any()` to fetch a couple of images and display the first one available (i.e. whose promise has resolved). function fetchAndDecode(url) { return fetch(url).then(response => { if(!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } else { return response.blob(); } }) } let coffee = fetchAndDecode('coffee.jpg'); let tea = fetchAndDecode('tea.jpg'); Promise.any([coffee, tea]).then(value => { let objectURL = URL.createObjectURL(value); let image = document.createElement('img'); image.src = objectURL; document.body.appendChild(image); }) .catch(e => { console.log(e.message); }); ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-promise.any
      `any` 85 85 79 No No 14 85 85 79 No 14 No ## See also - [`Promise`](../promise) - [`Promise.allSettled()`](allsettled) - [`Promise.all()`](all) - [`Promise.race()`](race) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any # Function.prototype.apply() The `apply()` method calls a function with a given `this` value, and `arguments` provided as an array (or an [array-like object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections#working_with_array-like_objects)). ## Syntax apply(thisArg) apply(thisArg, argsArray) ### Parameters `thisArg` The value of `this` provided for the call to `func`. Note that `this` may not be the actual value seen by the method: if the method is a function in [non-strict mode](../../strict_mode) code, [`null`](../null) and [`undefined`](../undefined) will be replaced with the global object, and primitive values will be boxed. This argument is required. `argsArray` Optional An array-like object, specifying the arguments with which `func` should be called, or [`null`](../null) or [`undefined`](../undefined) if no arguments should be provided to the function. Starting with ECMAScript 5 these arguments can be a generic array-like object instead of an array. See below for [browser compatibility](#browser_compatibility) information. ### Return value The result of calling the function with the specified `this` value and arguments. ## Description **Note:** While the syntax of this function is almost identical to that of [`call()`](call), the fundamental difference is that `call()` accepts an **argument list**, while `apply()` accepts a **single array of arguments**. **Note:** When the first argument is undefined or null a similar outcome can be achieved using the array [spread syntax](../../operators/spread_syntax). You can assign a different `this` object when calling an existing function. `this` refers to the current object (the calling object). With `apply`, you can write a method once, and then inherit it in another object, without having to rewrite the method for the new object. `apply` is very similar to [`call()`](call), except for the type of arguments it supports. You use an arguments array instead of a list of arguments (parameters). With `apply`, you can also use an array literal, for example, `func.apply(this, ['eat', 'bananas'])`, or an [`Array`](../array) object, for example, `func.apply(this, new Array('eat', 'bananas'))`. You can also use [`arguments`](../../functions/arguments) for the `argsArray` parameter. [`arguments`](../../functions/arguments) is a local variable of a function. It can be used for all unspecified arguments of the called object. Thus, you do not have to know the arguments of the called object when you use the `apply` method. You can use `arguments` to pass all the arguments to the called object. The called object is then responsible for handling the arguments. Since ECMAScript 5th Edition, you can also use any kind of object which is array-like. In practice, this means it's going to have a `length` property, and integer ("index") properties in the range `(0..length - 1)`. For example, you could use a [`NodeList`](https://developer.mozilla.org/en-US/docs/Web/API/NodeList), or a custom object like `{ 'length': 2, '0': 'eat', '1': 'bananas' }`. **Note:** Many older browsers—including Chrome <17 and Internet Explorer <9—don't accept array-like objects, and will throw an exception. ## Examples ### Using apply to append an array to another You can use `push` to append an element to an array. And, because `push` accepts a variable number of arguments, you can also push multiple elements at once. But, if you pass an array to `push`, it will actually add that array as a single element, instead of adding the elements individually. So you end up with an array inside an array. What if that is not what you want? `concat` does have the desired behavior in this case, but it does not append to the _existing_ array—it instead creates and returns a new array. But you wanted to append to the existing array... So what now? Write a loop? Surely not? `apply` to the rescue! const array = ['a', 'b']; const elements = [0, 1, 2]; array.push.apply(array, elements); console.info(array); // ["a", "b", 0, 1, 2] ### Using apply and built-in functions Clever usage of `apply` allows you to use built-in functions for some tasks that would probably have otherwise been written by looping over the array values. As an example, here are `Math.max`/`Math.min`, used to find out the maximum/minimum value in an array. // min/max number in an array const numbers = [5, 6, 2, 3, 7]; // using Math.min/Math.max apply let max = Math.max.apply(null, numbers); // This about equal to Math.max(numbers[0], ...) // or Math.max(5, 6, ...) let min = Math.min.apply(null, numbers); // vs. simple loop based algorithm max = -Infinity, min = +Infinity; for (let i = 0; i < numbers.length; i++) { if (numbers[i] > max) { max = numbers[i]; } if (numbers[i] < min) { min = numbers[i]; } } But beware: by using `apply` this way, you run the risk of exceeding the JavaScript engine's argument length limit. The consequences of applying a function with too many arguments (that is, more than tens of thousands of arguments) varies across engines. (The JavaScriptCore engine has hard-coded [argument limit of 65536](https://bugs.webkit.org/show_bug.cgi?id=80797). This is because the limit (and indeed, even the nature of any excessively-large-stack behavior) is unspecified. Some engines will throw an exception. More perniciously, others will arbitrarily limit the number of arguments actually passed to the applied function. To illustrate this latter case: if such an engine had a limit of four arguments (actual limits are of course significantly higher), it would be as if the arguments `5, 6, 2, 3` had been passed to `apply` in the examples above, rather than the full array. If your value array might grow into the tens of thousands, use a hybrid strategy: apply your function to chunks of the array at a time: function minOfArray(arr) { let min = Infinity; let QUANTUM = 32768; for (var i = 0, len = arr.length; i < len; i += QUANTUM) { var submin = Math.min.apply(null, arr.slice(i, Math.min(i+QUANTUM, len))); min = Math.min(submin, min); } return min; } let min = minOfArray([5, 6, 2, 3, 7]); ### Using apply to chain constructors You can use `apply` to chain [constructors](../../operators/new) for an object (similar to Java). In the following example we will create a global [`Function`](../function) method called `construct`, which will enable you to use an array-like object with a constructor instead of an arguments list. Function.prototype.construct = function(aArgs) { let oNew = Object.create(this.prototype); this.apply(oNew, aArgs); return oNew; }; Example usage: function MyConstructor() { for (let nProp = 0; nProp < arguments.length; nProp++) { this['property' + nProp] = arguments[nProp]; } } let myArray = [4, 'Hello world!', false]; let myInstance = MyConstructor.construct(myArray); console.log(myInstance.property1); // logs 'Hello world!' console.log(myInstance instanceof MyConstructor); // logs 'true' console.log(myInstance.constructor); // logs 'MyConstructor' **Note:** This non-native `Function.construct` method will not work with some native constructors; like [`Date`](../date), for example. In these cases you have to use the [`Function.prototype.bind`](bind) method. For example, imagine having an array like the following, to be used with [`Date`](../date) constructor: `[2012, 11, 4]`; in this case you have to write something like: `new (Function.prototype.bind.apply(Date, [null].concat([2012, 11, 4])))()`. This is not the best way to do things, and probably not to be used in any production environment. # The arguments object `arguments` is an `Array`-like object accessible inside [functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions) that contains the values of the arguments passed to that function. ## Description **Note:** If you're writing ES6 compatible code, then [rest parameters](rest_parameters) should be preferred. **Note:** "Array-like” means that `arguments` has a [`length`](arguments/length) property and properties indexed from zero, but it doesn't have [`Array`](../global_objects/array)'s built-in methods like [`forEach()`](../global_objects/array/foreach) or [`map()`](../global_objects/array/map). See [§Description](#description) for details. The `arguments` object is a local variable available within all non-[arrow](arrow_functions) functions. You can refer to a function's arguments inside that function by using its `arguments` object. It has entries for each argument the function was called with, with the first entry's index at `0`. For example, if a function is passed 3 arguments, you can access them as follows: arguments[0] // first argument arguments[1] // second argument arguments[2] // third argument Each argument can also be set or reassigned: arguments[1] = 'new value'; The `arguments` object is not an [`Array`](../global_objects/array). It is similar, but lacks all `Array` properties except [`length`](../global_objects/array/length). For example, it does not have the [`pop()`](../global_objects/array/pop) method. However, it can be converted to a real `Array`: var args = Array.prototype.slice.call(arguments); // Using an array literal is shorter than above but allocates an empty array var args = [].slice.call(arguments); As you can do with any Array-like object, you can use ES2015's [`Array.from()`](../global_objects/array/from) method or [spread syntax](../operators/spread_syntax) to convert `arguments` to a real Array: let args = Array.from(arguments); // or let args = [...arguments]; The `arguments` object is useful for functions called with more arguments than they are formally declared to accept. This technique is useful for functions that can be passed a variable number of arguments, such as [`Math.min()`](../global_objects/math/min). This example function accepts any number of string arguments and returns the longest one: function longestString() { var longest = ''; for (var i=0; i < arguments.length; i++) { if (arguments[i].length > longest.length) { longest = arguments[i]; } } return longest; } You can use [`arguments.length`](arguments/length) to count how many arguments the function was called with. If you instead want to count how many parameters a function is declared to accept, inspect that function's [`length`](../global_objects/function/length) property. ### Using typeof with arguments The [`typeof`](../operators/typeof) operator returns `'object'` when used with `arguments` console.log(typeof arguments); // 'object' The type of individual arguments can be determined by indexing `arguments`: console.log(typeof arguments[0]); // returns the type of the first argument ## Properties [`arguments.callee`](arguments/callee) Reference to the currently executing function that the arguments belong to. Forbidden in strict mode. [`arguments.length`](arguments/length) The number of arguments that were passed to the function. [`arguments[@@iterator]`](arguments/@@iterator) Returns a new [Array iterator](../global_objects/array/@@iterator) object that contains the values for each index in `arguments`. ## Examples ### Defining a function that concatenates several strings This example defines a function that concatenates several strings. The function's only formal argument is a string containing the characters that separate the items to concatenate. function myConcat(separator) { let args = Array.prototype.slice.call(arguments, 1); return args.join(separator); } You can pass as many arguments as you like to this function. It returns a string list using each argument in the list: // returns "red, orange, blue" myConcat(', ', 'red', 'orange', 'blue'); // returns "elephant; giraffe; lion; cheetah" myConcat('; ', 'elephant', 'giraffe', 'lion', 'cheetah'); // returns "sage. basil. oregano. pepper. parsley" myConcat('. ', 'sage', 'basil', 'oregano', 'pepper', 'parsley'); ### Defining a function that creates HTML lists This example defines a function that creates a string containing HTML for a list. The only formal argument for the function is a string that is "`u`" if the list is to be [unordered (bulleted)](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul), or "`o`" if the list is to be [ordered (numbered)](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol). The function is defined as follows: function list(type) { var html = '<' + type + 'l>
    • '; var args = Array.prototype.slice.call(arguments, 1); html += args.join('
    • '); html += '
    • '; // end list return html; } You can pass any number of arguments to this function, and it adds each argument as a list item to a list of the type indicated. For example: let listHTML = list('u', 'One', 'Two', 'Three'); /* listHTML is: "
      • One
      • Two
      • Three
      " */ ### Rest, default, and destructured parameters The `arguments` object can be used in conjunction with [rest](rest_parameters), [default](default_parameters), and [destructured](../operators/destructuring_assignment) parameters. function foo(...args) { return args; } foo(1, 2, 3); // [1, 2, 3] While the presence of rest, default, or destructured parameters does not alter [the behavior of the `arguments` object in strict mode code](../strict_mode#making_eval_and_arguments_simpler), there are subtle differences for non-strict code. In strict-mode code, the `arguments` object behaves the same whether or not a function is passed rest, default, or destructured parameters. That is, assigning new values to variables in the body of the function will not affect the `arguments` object. Nor will assigning new variables to the `arguments` object affect the value of variables. **Note:** You cannot write a `"use strict";` directive in the body of a function definition that accepts rest, default, or destructured parameters. Doing so will throw [a syntax error](../errors/strict_non_simple_params). Non-strict functions that are passed only simple parameters (that is, not rest, default, or restructured parameters) will sync the value of variables new values in the body of the function with the `arguments` object, and vice versa: function func(a) { arguments[0] = 99; // updating arguments[0] also updates a console.log(a); } func(10); // 99 And also: function func(a) { a = 99; // updating a also updates arguments[0] console.log(arguments[0]); } func(10); // 99 Conversely, non-strict functions that **are** passed rest, default, or destructured parameters **will not** sync new values assigned to argument variables in the function body with the `arguments` object. Instead, the `arguments` object in non-strict functions with complex parameters **will always** reflect the values passed to the function when the function was called (this is the same behavior as exhibited by all strict-mode functions, regardless of the type of variables they are passed): function func(a = 55) { arguments[0] = 99; // updating arguments[0] does not also update a console.log(a); } func(10); // 10 And also: function func(a = 55) { a = 99; // updating a does not also update arguments[0] console.log(arguments[0]); } func(10); // 10 And also: // An untracked default parameter function func(a = 55) { console.log(arguments[0]); } func(); // undefined ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-arguments-exotic-objects
      `arguments` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `callee` 1 12 1 6 4 1 1 18 4 10.1 1 1.0 `length` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `@@iterator` 52 12 46 No 39 9 52 52 46 41 9 6.0 ## See also - [`Function`](../global_objects/function) - [Rest parameters](rest_parameters) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments # Array The JavaScript `Array` class is a global object that is used in the construction of arrays; which are high-level, list-like objects. ## Description Arrays are list-like objects whose prototype has methods to perform traversal and mutation operations. Neither the length of a JavaScript array nor the types of its elements are fixed. Since an array's length can change at any time, and data can be stored at non-contiguous locations in the array, JavaScript arrays are not guaranteed to be dense; this depends on how the programmer chooses to use them. In general, these are convenient characteristics; but if these features are not desirable for your particular use, you might consider using typed arrays. Arrays cannot use strings as element indexes (as in an [associative array](https://en.wikipedia.org/wiki/Associative_array)) but must use integers. Setting or accessing via non-integers using [bracket notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#objects_and_properties) (or [dot notation](../operators/property_accessors)) will not set or retrieve an element from the array list itself, but will set or access a variable associated with that array's [object property collection](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#properties). The array's object properties and list of array elements are separate, and the array's [traversal and mutation operations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections#array_methods) cannot be applied to these named properties. ### Common operations **Create an Array** let fruits = ['Apple', 'Banana'] console.log(fruits.length) // 2 **Access an Array item using the index position** let first = fruits[0] // Apple let last = fruits[fruits.length - 1] // Banana **Loop over an Array** fruits.forEach(function(item, index, array) { console.log(item, index) }) // Apple 0 // Banana 1 **Add an item to the end of an Array** let newLength = fruits.push('Orange') // ["Apple", "Banana", "Orange"] **Remove an item from the end of an Array** let last = fruits.pop() // remove Orange (from the end) // ["Apple", "Banana"] **Remove an item from the beginning of an Array** let first = fruits.shift() // remove Apple from the front // ["Banana"] **Add an item to the beginning of an Array** let newLength = fruits.unshift('Strawberry') // add to the front // ["Strawberry", "Banana"] **Find the index of an item in the Array** fruits.push('Mango') // ["Strawberry", "Banana", "Mango"] let pos = fruits.indexOf('Banana') // 1 **Remove an item by index position** let removedItem = fruits.splice(pos, 1) // this is how to remove an item // ["Strawberry", "Mango"] **Remove items from an index position** let vegetables = ['Cabbage', 'Turnip', 'Radish', 'Carrot'] console.log(vegetables) // ["Cabbage", "Turnip", "Radish", "Carrot"] let pos = 1 let n = 2 let removedItems = vegetables.splice(pos, n) // this is how to remove items, n defines the number of items to be removed, // starting at the index position specified by pos and progressing toward the end of array. console.log(vegetables) // ["Cabbage", "Carrot"] (the original array is changed) console.log(removedItems) // ["Turnip", "Radish"] **Copy an Array** let shallowCopy = fruits.slice() // this is how to make a copy // ["Strawberry", "Mango"] ### Accessing array elements JavaScript arrays are zero-indexed. The first element of an array is at index `0`, and the last element is at the index value equal to the value of the array's [`length`](array/length) property minus `1`. Using an invalid index number returns `undefined`. let arr = ['this is the first element', 'this is the second element', 'this is the last element'] console.log(arr[0]) // logs 'this is the first element' console.log(arr[1]) // logs 'this is the second element' console.log(arr[arr.length - 1]) // logs 'this is the last element' Array elements are object properties in the same way that `toString` is a property (to be specific, however, `toString()` is a method). Nevertheless, trying to access an element of an array as follows throws a syntax error because the property name is not valid: console.log(arr.0) // a syntax error There is nothing special about JavaScript arrays and the properties that cause this. JavaScript properties that begin with a digit cannot be referenced with dot notation and must be accessed using bracket notation. For example, if you had an object with a property named `3d`, it can only be referenced using bracket notation. let years = [1950, 1960, 1970, 1980, 1990, 2000, 2010] console.log(years.0) // a syntax error console.log(years[0]) // works properly renderer.3d.setTexture(model, 'character.png') // a syntax error renderer['3d'].setTexture(model, 'character.png') // works properly In the `3d` example, `'3d'` _had_ to be quoted (because it begins with a digit). But it's also possible to quote the array indexes as well (e.g., `years['2']` instead of `years[2]`), although it's not necessary. The `2` in `years[2]` is coerced into a string by the JavaScript engine through an implicit `toString` conversion. As a result, `'2'` and `'02'` would refer to two different slots on the `years` object, and the following example could be `true`: console.log(years['2'] != years['02']) ### Relationship between length and numerical properties A JavaScript array's [`length`](array/length) property and numerical properties are connected. Several of the built-in array methods (e.g., [`join()`](array/join), [`slice()`](array/slice), [`indexOf()`](array/indexof), etc.) take into account the value of an array's [`length`](array/length) property when they're called. Other methods (e.g., [`push()`](array/push), [`splice()`](array/splice), etc.) also result in updates to an array's [`length`](array/length) property. const fruits = [] fruits.push('banana', 'apple', 'peach') console.log(fruits.length) // 3 When setting a property on a JavaScript array when the property is a valid array index and that index is outside the current bounds of the array, the engine will update the array's [`length`](array/length) property accordingly: fruits[5] = 'mango' console.log(fruits[5]) // 'mango' console.log(Object.keys(fruits)) // ['0', '1', '2', '5'] console.log(fruits.length) // 6 Increasing the [`length`](array/length). fruits.length = 10 console.log(fruits) // ['banana', 'apple', 'peach', empty x 2, 'mango', empty x 4] console.log(Object.keys(fruits)) // ['0', '1', '2', '5'] console.log(fruits.length) // 10 console.log(fruits[8]) // undefined Decreasing the [`length`](array/length) property does, however, delete elements. fruits.length = 2 console.log(Object.keys(fruits)) // ['0', '1'] console.log(fruits.length) // 2 This is explained further on the [`Array.length`](array/length) page. ### Creating an array using the result of a match The result of a match between a [`RegExp`](regexp) and a string can create a JavaScript array. This array has properties and elements which provide information about the match. Such an array is returned by [`RegExp.exec()`](regexp/exec), [`String.match()`](string/match), and [`String.replace()`](string/replace). To help explain these properties and elements, see this example and then refer to the table below: // Match one d followed by one or more b's followed by one d // Remember matched b's and the following d // Ignore case const myRe = /d(b+)(d)/i const myArray = myRe.exec('cdbBdbsbz') The properties and elements returned from this match are as follows:
      Property/ElementDescriptionExample
      input
      Read only
      The original string against which the regular expression was matched."cdbBdbsbz"
      index
      Read only
      The zero-based index of the match in the string.1
      [0]
      Read only
      The last matched characters."dbBd"
      [1], ...[n]
      Read only
      Elements that specify the parenthesized substring matches (if included) in the regular expression. The number of possible parenthesized substrings is unlimited.[1]: "bB" [2]: "d"
      ## Constructor [`Array()`](array/array) Creates a new `Array` object. ## Static properties [`get Array[@@species]`](array/@@species) The constructor function is used to create derived objects. ## Static methods [`Array.from()`](array/from) Creates a new `Array` instance from an array-like or iterable object. [`Array.isArray()`](array/isarray) Returns `true` if the argument is an array, or `false` otherwise. [`Array.of()`](array/of) Creates a new `Array` instance with a variable number of arguments, regardless of number or type of the arguments. ## Instance properties [`Array.prototype.length`](array/length) Reflects the number of elements in an array. [`Array.prototype[@@unscopables]`](array/@@unscopables) A symbol containing property names to exclude from a [`with`](../statements/with) binding scope. ## Instance methods [`Array.prototype.at()`](array/at) This is an experimental API that should not be used in production code. Returns the array item at the given index. Accepts negative integers, which count back from the last item. [`Array.prototype.concat()`](array/concat) Returns a new array that is this array joined with other array(s) and/or value(s). [`Array.prototype.copyWithin()`](array/copywithin) Copies a sequence of array elements within the array. [`Array.prototype.entries()`](array/entries) Returns a new `Array Iterator` object that contains the key/value pairs for each index in the array. [`Array.prototype.every()`](array/every) Returns `true` if every element in this array satisfies the testing function. [`Array.prototype.fill()`](array/fill) Fills all the elements of an array from a start index to an end index with a static value. [`Array.prototype.filter()`](array/filter) Returns a new array containing all elements of the calling array for which the provided filtering function returns `true`. [`Array.prototype.find()`](array/find) Returns the found `element` in the array, if some element in the array satisfies the testing function, or `undefined` if not found. [`Array.prototype.findIndex()`](array/findindex) Returns the found index in the array, if an element in the array satisfies the testing function, or `-1` if not found. [`Array.prototype.forEach()`](array/foreach) Calls a function for each element in the array. [`Array.prototype.includes()`](array/includes) Determines whether the array contains a value, returning `true` or `false` as appropriate. [`Array.prototype.indexOf()`](array/indexof) Returns the first (least) index of an element within the array equal to an element, or `-1` if none is found. [`Array.prototype.join()`](array/join) Joins all elements of an array into a string. [`Array.prototype.keys()`](array/keys) Returns a new `Array Iterator` that contains the keys for each index in the array. [`Array.prototype.lastIndexOf()`](array/lastindexof) Returns the last (greatest) index of an element within the array equal to an element, or `-1` if none is found. [`Array.prototype.map()`](array/map) Returns a new array containing the results of calling a function on every element in this array. [`Array.prototype.pop()`](array/pop) Removes the last element from an array and returns that element. [`Array.prototype.push()`](array/push) Adds one or more elements to the end of an array, and returns the new `length` of the array. [`Array.prototype.reduce()`](array/reduce) Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value. [`Array.prototype.reduceRight()`](array/reduceright) Apply a function against an accumulator> and each value of the array (from right-to-left) as to reduce it to a single value. [`Array.prototype.reverse()`](array/reverse) Reverses the order of the elements of an array _in place_. (First becomes the last, last becomes first.) [`Array.prototype.shift()`](array/shift) Removes the first element from an array and returns that element. [`Array.prototype.slice()`](array/slice) Extracts a section of the calling array and returns a new array. [`Array.prototype.some()`](array/some) Returns `true` if at least one element in this array satisfies the provided testing function. [`Array.prototype.sort()`](array/sort) Sorts the elements of an array in place and returns the array. [`Array.prototype.splice()`](array/splice) Adds and/or removes elements from an array. [`Array.prototype.toLocaleString()`](array/tolocalestring) Returns a localized string representing the array and its elements. Overrides the [`Object.prototype.toLocaleString()`](object/tolocalestring) method. [`Array.prototype.toString()`](array/tostring) Returns a string representing the array and its elements. Overrides the [`Object.prototype.toString()`](object/tostring) method. [`Array.prototype.unshift()`](array/unshift) Adds one or more elements to the front of an array, and returns the new `length` of the array. [`Array.prototype.values()`](array/values) Returns a new `Array Iterator` object that contains the values for each index in the array. [`Array.prototype[@@iterator]()`](array/@@iterator) Returns a new `Array Iterator` object that contains the values for each index in the array. ## Examples ### Creating an array The following example creates an array, `msgArray`, with a length of `0`, then assigns values to `msgArray[0]` and `msgArray[99]`, changing the `length` of the array to `100`. let msgArray = [] msgArray[0] = 'Hello' msgArray[99] = 'world' if (msgArray.length === 100) { console.log('The length is 100.') } ### Creating a two-dimensional array The following creates a chessboard as a two-dimensional array of strings. The first move is made by copying the `'p'` in `board[6][4]` to `board[4][4]`. The old position at `[6][4]` is made blank. let board = [ ['R','N','B','Q','K','B','N','R'], ['P','P','P','P','P','P','P','P'], [' ',' ',' ',' ',' ',' ',' ',' '], [' ',' ',' ',' ',' ',' ',' ',' '], [' ',' ',' ',' ',' ',' ',' ',' '], [' ',' ',' ',' ',' ',' ',' ',' '], ['p','p','p','p','p','p','p','p'], ['r','n','b','q','k','b','n','r'] ] console.log(board.join('\n') + '\n\n') // Move King's Pawn forward 2 board[4][4] = board[6][4] board[6][4] = ' ' console.log(board.join('\n')) Here is the output: R,N,B,Q,K,B,N,R P,P,P,P,P,P,P,P , , , , , , , , , , , , , , , , , , , , , , , , , , , , p,p,p,p,p,p,p,p r,n,b,q,k,b,n,r R,N,B,Q,K,B,N,R P,P,P,P,P,P,P,P , , , , , , , , , , , , , , , , , ,p, , , , , , , , , , p,p,p,p, ,p,p,p r,n,b,q,k,b,n,r ### Using an array to tabulate a set of values values = [] for (let x = 0; x < 10; x++){ values.push([ 2 ** x, 2 * x ** 2 ]) } console.table(values) Results in // The first column is the index 0 1 0 1 2 2 2 4 8 3 8 18 4 16 32 5 32 50 6 64 72 7 128 98 8 256 128 9 512 162 # TypeError: invalid Array.prototype.sort argument The JavaScript exception "invalid Array.prototype.sort argument" occurs when the argument of [`Array.prototype.sort()`](../global_objects/array/sort) isn't either [`undefined`](../global_objects/undefined) or a function which compares its operands. ## Message TypeError: argument is not a function object (Edge) TypeError: invalid Array.prototype.sort argument (Firefox) ## Error type [`TypeError`](../global_objects/typeerror) ## What went wrong? The argument of [`Array.prototype.sort()`](../global_objects/array/sort) is expected to be either [`undefined`](../global_objects/undefined) or a function which compares its operands. ## Examples ### Invalid cases [1, 3, 2].sort(5); // TypeError var cmp = { asc: (x, y) => x >= y, dsc: (x, y) => x <= y }; [1, 3, 2].sort(cmp[this.key] || 'asc'); // TypeError ### Valid cases [1, 3, 2].sort(); // [1, 2, 3] var cmp = { asc: (x, y) => x >= y, dsc: (x, y) => x <= y }; [1, 3, 2].sort(cmp[this.key || 'asc']); // [1, 2, 3] ## See also - [`Array.prototype.sort()`](../global_objects/array/sort) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Array_sort_argument # ArrayBuffer The `ArrayBuffer` object is used to represent a generic, fixed-length raw binary data buffer. It is an array of bytes, often referred to in other languages as a "byte array".You cannot directly manipulate the contents of an `ArrayBuffer`; instead, you create one of the [typed array objects](typedarray) or a [`DataView`](dataview) object which represents the buffer in a specific format, and use that to read and write the contents of the buffer. The `ArrayBuffer()` constructor creates a new `ArrayBuffer` of the given length in bytes. You can also get an array buffer from existing data, for example [from a Base64 string](https://developer.mozilla.org/en-US/docs/Glossary/Base64#appendix_to_solution_1_decode_a_base64_string_to_uint8array_or_arraybuffer) or [from a local file](https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsArrayBuffer). ## Constructor [`ArrayBuffer()`](arraybuffer/arraybuffer) Creates a new `ArrayBuffer` object. ## Static properties [`get ArrayBuffer[@@species]`](arraybuffer/@@species) The constructor function that is used to create derived objects. ## Static methods [`ArrayBuffer.isView(arg)`](arraybuffer/isview) Returns `true` if `arg` is one of the ArrayBuffer views, such as [typed array objects](typedarray) or a [`DataView`](dataview). Returns `false` otherwise. ## Instance properties [`ArrayBuffer.prototype.byteLength`](arraybuffer/bytelength) The read-only size, in bytes, of the `ArrayBuffer`. This is established when the array is constructed and cannot be changed. ## Instance methods [`ArrayBuffer.prototype.slice()`](arraybuffer/slice) Returns a new `ArrayBuffer` whose contents are a copy of this `ArrayBuffer`'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 an ArrayBuffer In this example, we create a 8-byte buffer with a [`Int32Array`](int32array) view referring to the buffer: const buffer = new ArrayBuffer(8); const view = new Int32Array(buffer); ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-arraybuffer-objects
      `ArrayBuffer` 7 12 4 10 11.6 5.1 4 18 4 12 4.2 1.0 `ArrayBuffer` 7 12 4 10 11.6 5.1 4 18 4 12 4.2 1.0 `byteLength` 7 12 4 10 11.6 5.1 4 18 4 12 4.2 1.0 `isView` 32 12 29 11 19 7 ≤37 32 29 19 7 2.0 `slice` 17 12 12 The non-standard `ArrayBuffer.slice()` method has been removed in Firefox 53 (but the standardized version `ArrayBuffer.prototype.slice()` is kept. 11 12.1 6 ≤37 18 14 The non-standard `ArrayBuffer.slice()` method has been removed in Firefox 53 (but the standardized version `ArrayBuffer.prototype.slice()` is kept. 12.1 6 1.0 `@@species` 51 13 48 No 38 10 51 51 48 41 10 5.0 ## See also - [JavaScript typed arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) - [`SharedArrayBuffer`](sharedarraybuffer) - [RangeError: invalid array length](../errors/invalid_array_length) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer # Arrow function expressions An **arrow function expression** is a compact alternative to a traditional [function expression](../operators/function), but is limited and can't be used in all situations. **Differences & Limitations:** - Does not have its own bindings to `this` or `super`, and should not be used as `methods`. - Does not have `arguments`, or `new.target` keywords. - Not suitable for `call`, `apply` and [`bind`](../global_objects/function/bind) methods, which generally rely on establishing a [scope](https://developer.mozilla.org/en-US/docs/Glossary/Scope). - Can not be used as [constructors](https://developer.mozilla.org/en-US/docs/Glossary/Constructor). - Can not use `yield`, within its body. ### Comparing traditional functions to arrow functions Let's decompose a "traditional function" down to the simplest "arrow function" step-by-step: NOTE: Each step along the way is a valid "arrow function" // Traditional Function function (a){ return a + 100; } // Arrow Function Break Down // 1. Remove the word "function" and place arrow between the argument and opening body bracket (a) => { return a + 100; } // 2. Remove the body brackets and word "return" -- the return is implied. (a) => a + 100; // 3. Remove the argument parentheses a => a + 100; **Note:** As shown above, the { brackets } and ( parentheses ) and "return" are optional, but may be required. For example, if you have **multiple arguments** or **no arguments**, you'll need to re-introduce parentheses around the arguments: // Traditional Function function (a, b){ return a + b + 100; } // Arrow Function (a, b) => a + b + 100; // Traditional Function (no arguments) let a = 4; let b = 2; function (){ return a + b + 100; } // Arrow Function (no arguments) let a = 4; let b = 2; () => a + b + 100; Likewise, if the body requires **additional lines** of processing, you'll need to re-introduce brackets **PLUS the "return"** (arrow functions do not magically guess what or when you want to "return"): // Traditional Function function (a, b){ let chuck = 42; return a + b + chuck; } // Arrow Function (a, b) => { let chuck = 42; return a + b + chuck; } And finally, for **named functions** we treat arrow expressions like variables // Traditional Function function bob (a){ return a + 100; } // Arrow Function let bob = a => a + 100; ## Syntax ### Basic syntax One param. With simple expression return is not needed: param => expression Multiple params require parentheses. With simple expression return is not needed: (param1, paramN) => expression Multiline statements require body brackets and return: param => { let a = 1; return a + param; } Multiple params require parentheses. Multiline statements require body brackets and return: (param1, paramN) => { let a = 1; return a + param1 + paramN; } ### Advanced syntax To return an object literal expression requires parentheses around expression: params => ({foo: "a"}) // returning the object {foo: "a"} [Rest parameters](rest_parameters) are supported: (a, b, ...r) => expression [Default parameters](default_parameters) are supported: (a=400, b=20, c) => expression [Destructuring](../operators/destructuring_assignment) within params supported: ([a, b] = [10, 20]) => a + b; // result is 30 ({ a, b } = { a: 10, b: 20 }) => a + b; // result is 30 ## Description ### Arrow functions used as methods As stated previously, arrow function expressions are best suited for non-method functions. Let's see what happens when we try to use them as methods: 'use strict'; var obj = { // does not create a new scope i: 10, b: () => console.log(this.i, this), c: function() { console.log(this.i, this); } } obj.b(); // prints undefined, Window {...} (or the global object) obj.c(); // prints 10, Object {...} Arrow functions do not have their own `this`. Another example involving [`Object.defineProperty()`](../global_objects/object/defineproperty): 'use strict'; var obj = { a: 10 }; Object.defineProperty(obj, 'b', { get: () => { console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...} (or the global object) return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined' } }); ### call, apply and bind The `call`, `apply` and [`bind`](../global_objects/function/bind) methods are **NOT suitable** for Arrow functions -- as they were designed to allow methods to execute within different scopes -- because **Arrow functions establish "this" based on the scope the Arrow function is defined within.** For example `call`, `apply` and [`bind`](../global_objects/function/bind) work as expected with Traditional functions, because we establish the scope for each of the methods: // ---------------------- // Traditional Example // ---------------------- // A simplistic object with its very own "this". var obj = { num: 100 } // Setting "num" on window to show how it is NOT used. window.num = 2020; // yikes! // A simple traditional function to operate on "this" var add = function (a, b, c) { return this.num + a + b + c; } // call var result = add.call(obj, 1, 2, 3) // establishing the scope as "obj" console.log(result) // result 106 // apply const arr = [1, 2, 3] var result = add.apply(obj, arr) // establishing the scope as "obj" console.log(result) // result 106 // bind var result = add.bind(obj) // establishing the scope as "obj" console.log(result(1, 2, 3)) // result 106 With Arrow functions, since our `add` function is essentially created on the `window` (global) scope, it will assume `this` is the window. // ---------------------- // Arrow Example // ---------------------- // A simplistic object with its very own "this". var obj = { num: 100 } // Setting "num" on window to show how it gets picked up. window.num = 2020; // yikes! // Arrow Function var add = (a, b, c) => this.num + a + b + c; // call console.log(add.call(obj, 1, 2, 3)) // result 2026 // apply const arr = [1, 2, 3] console.log(add.apply(obj, arr)) // result 2026 // bind const bound = add.bind(obj) console.log(bound(1, 2, 3)) // result 2026 Perhaps the greatest benefit of using Arrow functions is with DOM-level methods (setTimeout, setInterval, addEventListener) that usually required some kind of closure, call, apply or bind to ensure the function executed in the proper scope. **Traditional Example:** var obj = { count : 10, doSomethingLater : function (){ setTimeout(function(){ // the function executes on the window scope this.count++; console.log(this.count); }, 300); } } obj.doSomethingLater(); // console prints "NaN", because the property "count" is not in the window scope. **Arrow Example:** var obj = { count : 10, doSomethingLater : function(){ // of course, arrow functions are not suited for methods setTimeout( () => { // since the arrow function was created within the "obj", it assumes the object's "this" this.count++; console.log(this.count); }, 300); } } obj.doSomethingLater(); ### No binding of `arguments` Arrow functions do not have their own [`arguments` object](arguments). Thus, in this example, `arguments` is a reference to the arguments of the enclosing scope: var arguments = [1, 2, 3]; var arr = () => arguments[0]; arr(); // 1 function foo(n) { var f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0] is n return f(); } foo(3); // 3 + 3 = 6 In most cases, using [rest parameters](rest_parameters) is a good alternative to using an `arguments` object. function foo(n) { var f = (...args) => args[0] + n; return f(10); } foo(1); // 11 ### Use of the `new` operator Arrow functions cannot be used as constructors and will throw an error when used with `new`. var Foo = () => {}; var foo = new Foo(); // TypeError: Foo is not a constructor ### Use of `prototype` property Arrow functions do not have a `prototype` property. var Foo = () => {}; console.log(Foo.prototype); // undefined ### Use of the `yield` keyword The `yield` keyword may not be used in an arrow function's body (except when permitted within functions further nested within it). As a consequence, arrow functions cannot be used as generators. ### Function body Arrow functions can have either a "concise body" or the usual "block body". In a concise body, only an expression is specified, which becomes the implicit return value. In a block body, you must use an explicit `return` statement. var func = x => x * x; // concise body syntax, implied "return" var func = (x, y) => { return x + y; }; // with block body, explicit "return" needed ### Returning object literals Keep in mind that returning object literals using the concise body syntax `params => {object:literal}` will not work as expected. var func = () => { foo: 1 }; // Calling func() returns undefined! var func = () => { foo: function() {} }; // SyntaxError: function statement requires a name This is because the code inside braces ({}) is parsed as a sequence of statements (i.e. `foo` is treated like a label, not a key in an object literal). You must wrap the object literal in parentheses: var func = () => ({ foo: 1 }); ### Line breaks An arrow function cannot contain a line break between its parameters and its arrow. var func = (a, b, c) => 1; // SyntaxError: expected expression, got '=>' However, this can be amended by putting the line break after the arrow or using parentheses/braces as seen below to ensure that the code stays pretty and fluffy. You can also put line breaks between arguments. var func = (a, b, c) => 1; var func = (a, b, c) => ( 1 ); var func = (a, b, c) => { return 1 }; var func = ( a, b, c ) => 1; // no SyntaxError thrown ### Parsing order Although the arrow in an arrow function is not an operator, arrow functions have special parsing rules that interact differently with [operator precedence](../operators/operator_precedence) compared to regular functions. let callback; callback = callback || function() {}; // ok callback = callback || () => {}; // SyntaxError: invalid arrow-function arguments callback = callback || (() => {}); // ok ## Examples ### Basic usage // An empty arrow function returns undefined let empty = () => {}; (() => 'foobar')(); // Returns "foobar" // (this is an Immediately Invoked Function Expression) var simple = a => a > 15 ? 15 : a; simple(16); // 15 simple(10); // 10 let max = (a, b) => a > b ? a : b; // Easy array filtering, mapping, ... var arr = [5, 6, 13, 0, 1, 18, 23]; var sum = arr.reduce((a, b) => a + b); // 66 var even = arr.filter(v => v % 2 == 0); // [6, 0, 18] var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46] // More concise promise chains promise.then(a => { // ... }).then(b => { // ... }); // Parameterless arrow functions that are visually easier to parse setTimeout( () => { console.log('I happen sooner'); setTimeout( () => { // deeper code console.log('I happen later'); }, 1); }, 1); ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-arrow-function-definitions
      `Arrow_functions` 45 12 22 \["The initial implementation of arrow functions in Firefox made them automatically strict. This has been changed as of Firefox 24. The use of `'use strict';` is now required.", "Prior to Firefox 39, a line terminator (`\\n`) was incorrectly allowed after arrow function arguments. This has been fixed to conform to the ES2015 specification and code like `() \\n => {}` will now throw a `SyntaxError` in this and later versions."\] No 32 10 45 45 22 \["The initial implementation of arrow functions in Firefox made them automatically strict. This has been changed as of Firefox 24. The use of `'use strict';` is now required.", "Prior to Firefox 39, a line terminator (`\\n`) was incorrectly allowed after arrow function arguments. This has been fixed to conform to the ES2015 specification and code like `() \\n => {}` will now throw a `SyntaxError` in this and later versions."\] 32 10 5.0 `trailing_comma` 58 12 52 No 45 10 58 58 52 43 10 7.0 ## See also - ["ES6 In Depth: Arrow functions" on hacks.mozilla.org](https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions # Math.asin() The `Math.asin()` function returns the arcsine (in radians) of a number, that is $$\\forall x \\in \\lbrack{- 1};1\\rbrack,\\;\\mathtt{\\operatorname{Math.asin}(x)} = \\arcsin(x) = \\text{the\\ unique}\\; y \\in \\left\\lbrack {- \\frac{\\pi}{2};\\frac{\\pi}{2}} \\right\\rbrack\\,\\text{such\\ that}\\;\\sin(y) = x$$ ## Syntax Math.asin(x) ### Parameters `x` A number. ### Return value The arcsine (in radians) of the given number if it's between **-1** and **1**; otherwise, [`NaN`](../nan). ## Description The `Math.asin()` method returns a numeric value between $- \\frac{\\pi}{2}$ and $\\frac{\\pi}{2}$ radians for x between -1 and 1. If the value of x is outside this range, it returns [`NaN`](../nan). Because `asin()` is a static method of `Math`, you always use it as `Math.asin()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.asin() Math.asin(-2); // NaN Math.asin(-1); // -1.5707963267948966 (-pi/2) Math.asin(0); // 0 Math.asin(0.5); // 0.5235987755982989 Math.asin(1); // 1.5707963267948966 (pi/2) Math.asin(2); // NaN For values less than -1 or greater than 1, `Math.asin()` returns [`NaN`](../nan). ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.asin
      `asin` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`Math.acos()`](acos) - [`Math.atan()`](atan) - [`Math.atan2()`](atan2) - [`Math.cos()`](cos) - [`Math.sin()`](sin) - [`Math.tan()`](tan) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asin # Math.asinh() The `Math.asinh()` function returns the hyperbolic arcsine of a number, that is `Math.asinh` ` (``x``) ` = arsinh (_x_) = the unique *y* such that sinh (_y_) = *x* ## Syntax Math.asinh(x) ### Parameters `x` A number. ### Return value The hyperbolic arcsine of the given number. ## Description Because `asinh()` is a static method of `Math`, you always use it as `Math.asinh()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.asinh() Math.asinh(1); // 0.881373587019543 Math.asinh(0); // 0 ## Polyfill `Math.asinh` can be emulated with the following function: if (!Math.asinh) Math.asinh = function(x) { var absX = Math.abs(x), w if (absX < 3.725290298461914e-9) // |x| < 2^-28 return x if (absX > 268435456) // |x| > 2^28 w = Math.log(absX) + Math.LN2 else if (absX > 2) // 2^28 >= |x| > 2 w = Math.log(2 * absX + 1 / (Math.sqrt(x * x + 1) + absX)) else var t = x * x, w = Math.log1p(absX + t / (1 + Math.sqrt(1 + t))) return x > 0 ? w : -w } `Math.log1p` may also have to be polyfilled; see [Math.log1p](log1p) for details. ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.asinh
      `asinh` 38 12 25 No 25 8 38 38 25 25 8 3.0 ## See also - [`Math.acosh()`](acosh) - [`Math.atanh()`](atanh) - [`Math.cosh()`](cosh) - [`Math.sinh()`](sinh) - [`Math.tanh()`](tanh) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh # BigInt.asIntN() The `BigInt.asIntN` static method clamps a BigInt value to a signed integer value, and returns that value. ## Syntax BigInt.asIntN(bits, bigint); ### Parameters `bits` The amount of bits available for the integer size. `bigint` The BigInt value to clamp to fit into the supplied bits. ### Returns The value of `bigint` modulo 2`bits`, as a signed integer. ## Examples ### Staying in 64-bit ranges The `BigInt.asIntN()` method can be useful to stay in the range of 64-bit arithmetic. const max = 2n ** (64n - 1n) - 1n; BigInt.asIntN(64, max); // ↪ 9223372036854775807n BigInt.asIntN(64, max + 1n); // ↪ -9223372036854775808n // negative because of overflow ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-bigint.asintn
      `asIntN` 67 79 68 No 54 14 67 67 68 48 14 9.0 ## See also - [`BigInt`](../bigint) - [`BigInt.asUintN()`](asuintn) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN # Object.assign() The `Object.assign()` method copies all [enumerable](propertyisenumerable) [own properties](hasownproperty) from one or more _source objects_ to a _target object_. It returns the target object. ## Syntax Object.assign(target, ...sources) ### Parameters `target` The target object — what to apply the sources' properties to, which is returned after it is modified. `sources` The source object(s) — objects containing the properties you want to apply. ### Return value The target object. ## Description Properties in the target object are overwritten by properties in the sources if they have the same [key](keys). Later sources' properties overwrite earlier ones. The `Object.assign()` method only copies _enumerable_ and _own_ properties from a source object to a target object. It uses `[[Get]]` on the source and `[[Set]]` on the target, so it will invoke [getters](../../functions/get) and [setters](../../functions/set). Therefore it _assigns_ properties, versus copying or defining new properties. This may make it unsuitable for merging new properties into a prototype if the merge sources contain getters. For copying property definitions (including their enumerability) into prototypes, use [`Object.getOwnPropertyDescriptor()`](getownpropertydescriptor) and [`Object.defineProperty()`](defineproperty) instead. Both [`String`](../string) and [`Symbol`](../symbol) properties are copied. In case of an error, for example if a property is non-writable, a [`TypeError`](../typeerror) is raised, and the `target` object is changed if any properties are added before the error is raised. **Note:** `Object.assign()` does not throw on [`null`](../null) or [`undefined`](../undefined) sources. ## Polyfill This [polyfill](https://developer.mozilla.org/en-US/docs/Glossary/Polyfill) doesn't support symbol properties, since ES5 doesn't have symbols anyway: if (typeof Object.assign !== 'function') { // Must be writable: true, enumerable: false, configurable: true Object.defineProperty(Object, "assign", { value: function assign(target, varArgs) { // .length of function is 2 'use strict'; if (target === null || target === undefined) { throw new TypeError('Cannot convert undefined or null to object'); } var to = Object(target); for (var index = 1; index < arguments.length; index++) { var nextSource = arguments[index]; if (nextSource !== null && nextSource !== undefined) { for (var nextKey in nextSource) { // Avoid bugs when hasOwnProperty is shadowed if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; } } } } return to; }, writable: true, configurable: true }); } ## Examples ### Cloning an object const obj = { a: 1 }; const copy = Object.assign({}, obj); console.log(copy); // { a: 1 } ### Warning for Deep Clone For deep cloning, we need to use alternatives, because `Object.assign()` copies property values. If the source value is a reference to an object, it only copies the reference value. function test() { 'use strict'; let obj1 = { a: 0 , b: { c: 0}}; let obj2 = Object.assign({}, obj1); console.log(JSON.stringify(obj2)); // { "a": 0, "b": { "c": 0}} obj1.a = 1; console.log(JSON.stringify(obj1)); // { "a": 1, "b": { "c": 0}} console.log(JSON.stringify(obj2)); // { "a": 0, "b": { "c": 0}} obj2.a = 2; console.log(JSON.stringify(obj1)); // { "a": 1, "b": { "c": 0}} console.log(JSON.stringify(obj2)); // { "a": 2, "b": { "c": 0}} obj2.b.c = 3; console.log(JSON.stringify(obj1)); // { "a": 1, "b": { "c": 3}} console.log(JSON.stringify(obj2)); // { "a": 2, "b": { "c": 3}} // Deep Clone obj1 = { a: 0 , b: { c: 0}}; let obj3 = JSON.parse(JSON.stringify(obj1)); obj1.a = 4; obj1.b.c = 4; console.log(JSON.stringify(obj3)); // { "a": 0, "b": { "c": 0}} } test(); ### Merging objects const o1 = { a: 1 }; const o2 = { b: 2 }; const o3 = { c: 3 }; const obj = Object.assign(o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 } console.log(o1); // { a: 1, b: 2, c: 3 }, target object itself is changed. ### Merging objects with same properties const o1 = { a: 1, b: 1, c: 1 }; const o2 = { b: 2, c: 2 }; const o3 = { c: 3 }; const obj = Object.assign({}, o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 } The properties are overwritten by other objects that have the same properties later in the parameters order. ### Copying symbol-typed properties const o1 = { a: 1 }; const o2 = { [Symbol('foo')]: 2 }; const obj = Object.assign({}, o1, o2); console.log(obj); // { a : 1, [Symbol("foo")]: 2 } (cf. bug 1207182 on Firefox) Object.getOwnPropertySymbols(obj); // [Symbol(foo)] ### Properties on the prototype chain and non-enumerable properties cannot be copied const obj = Object.create({ foo: 1 }, { // foo is on obj's prototype chain. bar: { value: 2 // bar is a non-enumerable property. }, baz: { value: 3, enumerable: true // baz is an own enumerable property. } }); const copy = Object.assign({}, obj); console.log(copy); // { baz: 3 } ### Primitives will be wrapped to objects const v1 = 'abc'; const v2 = true; const v3 = 10; const v4 = Symbol('foo'); const obj = Object.assign({}, v1, null, v2, undefined, v3, v4); // Primitives will be wrapped, null and undefined will be ignored. // Note, only string wrappers can have own enumerable properties. console.log(obj); // { "0": "a", "1": "b", "2": "c" } ### Exceptions will interrupt the ongoing copying task const target = Object.defineProperty({}, 'foo', { value: 1, writable: false }); // target.foo is a read-only property Object.assign(target, { bar: 2 }, { foo2: 3, foo: 3, foo3: 3 }, { baz: 4 }); // TypeError: "foo" is read-only // The Exception is thrown when assigning target.foo console.log(target.bar); // 2, the first source was copied successfully. console.log(target.foo2); // 3, the first property of the second source was copied successfully. console.log(target.foo); // 1, exception is thrown here. console.log(target.foo3); // undefined, assign method has finished, foo3 will not be copied. console.log(target.baz); // undefined, the third source will not be copied either. ### Copying accessors const obj = { foo: 1, get bar() { return 2; } }; let copy = Object.assign({}, obj); console.log(copy); // { foo: 1, bar: 2 } // The value of copy.bar is obj.bar's getter's return value. // This is an assign function that copies full descriptors function completeAssign(target, ...sources) { sources.forEach(source => { let descriptors = Object.keys(source).reduce((descriptors, key) => { descriptors[key] = Object.getOwnPropertyDescriptor(source, key); return descriptors; }, {}); // By default, Object.assign copies enumerable Symbols, too Object.getOwnPropertySymbols(source).forEach(sym => { let descriptor = Object.getOwnPropertyDescriptor(source, sym); if (descriptor.enumerable) { descriptors[sym] = descriptor; } }); Object.defineProperties(target, descriptors); }); return target; } copy = completeAssign({}, obj); console.log(copy); // { foo:1, get bar() { return 2 } } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-object.assign
      `assign` 45 12 34 No 32 9 45 45 34 32 9 5.0 ## See also - [`Object.defineProperties()`](defineproperties) - [Enumerability and ownership of properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) - [Spread in object literals](../../operators/spread_syntax#spread_in_object_literals) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign # BigInt.asUintN() The `BigInt.asUintN` static method clamps a BigInt value to an unsigned integer value, and returns that value. ## Syntax BigInt.asUintN(bits, bigint); ### Parameters `bits` The amount of bits available for the integer size. `bigint` The BigInt value to clamp to fit into the supplied bits. ### Returns The value of `bigint` modulo 2`bits`, as an unsigned integer. ## Examples ### Staying in 64-bit ranges The `BigInt.asUintN()` method can be useful to stay in the range of 64-bit arithmetic. const max = 2n ** 64n - 1n; BigInt.asUintN(64, max); // ↪ 18446744073709551615n BigInt.asUintN(64, max + 1n); // ↪ 0n // zero because of overflow ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-bigint.asuintn
      `asUintN` 67 79 68 No 54 14 67 67 68 48 14 9.0 ## See also - [`BigInt`](../bigint) - [`BigInt.asIntN()`](asintn) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN # async function An async function is a function declared with the `async` keyword, and the `await` keyword is permitted within them. The `async` and `await` keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains. Async functions may also be defined [as expressions](../operators/async_function). ## Syntax async function name([param[, param[, ...param]]]) { statements } ### Parameters `name` The function's name. `param` The name of an argument to be passed to the function. `statements` The statements comprising the body of the function. The `await` mechanism may be used. ### Return value A [`Promise`](../global_objects/promise) which will be resolved with the value returned by the async function, or rejected with an exception thrown from, or uncaught within, the async function. ## Description Async functions can contain zero or more [`await`](../operators/await) expressions. Await expressions make promise-returning functions behave as though they're synchronous by suspending execution until the returned promise is fulfilled or rejected. The resolved value of the promise is treated as the return value of the await expression. Use of `async` and `await` enables the use of ordinary `try` / `catch` blocks around asynchronous code. **Note:** The `await` keyword is only valid inside async functions within regular JavaScript code. If you use it outside of an async function's body, you will get a [`SyntaxError`](../global_objects/syntaxerror). `await` can be used on its own with [JavaScript modules.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) **Note:** The purpose of `async`/`await` is to simplify the syntax necessary to consume promise-based APIs. The behavior of `async`/`await` is similar to combining [generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators) and promises. Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise. For example, the following: async function foo() { return 1 } ...is similar to: function foo() { return Promise.resolve(1) } **Checking equality with `Promise.resolve` vs `async` return** Even though the return value of an async function behaves as if it's wrapped in a `Promise.resolve`, they are not equivalent. An async function will return a different _reference_, whereas `Promise.resolve` returns the same reference if the given value is a promise. It can be a problem when you want to check the equality of a promise and a return value of an async function. const p = new Promise((res, rej) => { res(1); }) async function asyncReturn() { return p; } function basicReturn() { return Promise.resolve(p); } console.log(p === basicReturn()); // true console.log(p === asyncReturn()); // false The body of an async function can be thought of as being split by zero or more await expressions. Top-level code, up to and including the first await expression (if there is one), is run synchronously. In this way, an async function without an await expression will run synchronously. If there is an await expression inside the function body, however, the async function will always complete asynchronously. For example: async function foo() { await 1 } ...is equivalent to: function foo() { return Promise.resolve(1).then(() => undefined) } Code after each await expression can be thought of as existing in a `.then` callback. In this way a promise chain is progressively constructed with each reentrant step through the function. The return value forms the final link in the chain. In the following example, we successively await two promises. Progress moves through function `foo` in three stages. 1. The first line of the body of function `foo` is executed synchronously, with the await expression configured with the pending promise. Progress through `foo` is then suspended and control is yielded back to the function that called `foo`. 2. Some time later, when the first promise has either been fulfilled or rejected, control moves back into `foo`. The result of the first promise fulfillment (if it was not rejected) is returned from the await expression. Here `1` is assigned to `result1`. Progress continues, and the second await expression is evaluated. Again, progress through `foo` is suspended and control is yielded. 3. Some time later, when the second promise has either been fulfilled or rejected, control re-enters `foo`. The result of the second promise resolution is returned from the second await expression. Here `2` is assigned to `result2`. Control moves to the return expression (if any). The default return value of `undefined` is returned as the resolution value of the current promise. async function foo() { const result1 = await new Promise((resolve) => setTimeout(() => resolve('1'))) const result2 = await new Promise((resolve) => setTimeout(() => resolve('2'))) } foo() Note how the promise chain is not built-up in one go. Instead, the promise chain is constructed in stages as control is successively yielded from and returned to the async function. As a result, we must be mindful of error handling behavior when dealing with concurrent asynchronous operations. For example, in the following code an unhandled promise rejection error will be thrown, even if a `.catch` handler has been configured further along the promise chain. This is because `p2` will not be "wired into" the promise chain until control returns from `p1`. async function foo() { const p1 = new Promise((resolve) => setTimeout(() => resolve('1'), 1000)) const p2 = new Promise((_,reject) => setTimeout(() => reject('2'), 500)) const results = [await p1, await p2] // Do not do this! Use Promise.all or Promise.allSettled instead. } foo().catch(() => {}) // Attempt to swallow all errors... ## Examples ### Async functions and execution order function resolveAfter2Seconds() { console.log("starting slow promise") return new Promise(resolve => { setTimeout(function() { resolve("slow") console.log("slow promise is done") }, 2000) }) } function resolveAfter1Second() { console.log("starting fast promise") return new Promise(resolve => { setTimeout(function() { resolve("fast") console.log("fast promise is done") }, 1000) }) } async function sequentialStart() { console.log('==SEQUENTIAL START==') // 1. Execution gets here almost instantly const slow = await resolveAfter2Seconds() console.log(slow) // 2. this runs 2 seconds after 1. const fast = await resolveAfter1Second() console.log(fast) // 3. this runs 3 seconds after 1. } async function concurrentStart() { console.log('==CONCURRENT START with await=='); const slow = resolveAfter2Seconds() // starts timer immediately const fast = resolveAfter1Second() // starts timer immediately // 1. Execution gets here almost instantly console.log(await slow) // 2. this runs 2 seconds after 1. console.log(await fast) // 3. this runs 2 seconds after 1., immediately after 2., since fast is already resolved } function concurrentPromise() { console.log('==CONCURRENT START with Promise.all==') return Promise.all([resolveAfter2Seconds(), resolveAfter1Second()]).then((messages) => { console.log(messages[0]) // slow console.log(messages[1]) // fast }) } async function parallel() { console.log('==PARALLEL with await Promise.all==') // Start 2 "jobs" in parallel and wait for both of them to complete await Promise.all([ (async()=>console.log(await resolveAfter2Seconds()))(), (async()=>console.log(await resolveAfter1Second()))() ]) } sequentialStart() // after 2 seconds, logs "slow", then after 1 more second, "fast" // wait above to finish setTimeout(concurrentStart, 4000) // after 2 seconds, logs "slow" and then "fast" // wait again setTimeout(concurrentPromise, 7000) // same as concurrentStart // wait again setTimeout(parallel, 10000) // truly parallel: after 1 second, logs "fast", then after 1 more second, "slow" #### await and parallelism In `sequentialStart`, execution suspends 2 seconds for the first `await`, and then another second for the second `await`. The second timer is not created until the first has already fired, so the code finishes after 3 seconds. In `concurrentStart`, both timers are created and then `await`ed. The timers run concurrently, which means the code finishes in 2 rather than 3 seconds, i.e. the slowest timer. However, the `await` calls still run in series, which means the second `await` will wait for the first one to finish. In this case, the result of the fastest timer is processed after the slowest. If you wish to safely perform two or more jobs in parallel, you must await a call to `Promise.all`, or `Promise.allSettled`. **Warning:** The functions `concurrentStart` and `concurrentPromise` are not functionally equivalent. In `concurrentStart`, if promise `fast` rejects before promise `slow` is fulfilled, then an unhandled promise rejection error will be raised, regardless of whether the caller has configured a catch clause. In `concurrentPromise,` `Promise.all` wires up the promise chain in one go, meaning that the operation will fail-fast regardless of the order of rejection of the promises, and the error will always occur within the configured promise chain, enabling it to be caught in the normal way. ### Rewriting a Promise chain with an async function An API that returns a [`Promise`](../global_objects/promise) will result in a promise chain, and it splits the function into many parts. Consider the following code: function getProcessedData(url) { return downloadData(url) // returns a promise .catch(e => { return downloadFallbackData(url) // returns a promise }) .then(v => { return processDataInWorker(v) // returns a promise }) } it can be rewritten with a single async function as follows: async function getProcessedData(url) { let v try { v = await downloadData(url) } catch(e) { v = await downloadFallbackData(url) } return processDataInWorker(v) } In the above example, notice there is no `await` statement after the `return` keyword, although that would be valid too: The return value of an `async function` is implicitly wrapped in [`Promise.resolve`](../global_objects/promise/resolve) - if it's not already a promise itself (as in this example). **Note:** The implicit wrapping of return values in [`Promise.resolve`](../global_objects/promise/resolve) does not imply that `return await promiseValue` is functionally equivalent to `return promiseValue`. Consider the following rewrite of the above code. It returns `null` if `processDataInWorker` rejects with an error: async function getProcessedData(url) { let v try { v = await downloadData(url) } catch(e) { v = await downloadFallbackData(url) } try { return await processDataInWorker(v) // Note the `return await` vs. just `return` } catch (e) { return null } } Writing `return processDataInWorker(v)` would have caused the [`Promise`](../global_objects/promise) returned by the function to reject, instead of resolving to `null` if `processDataInWorker(v)` rejects. This highlights the subtle difference between `return foo;` and `return await foo;` — `return foo` immediately returns `foo` and never throws, even if `foo` is a Promise that rejects. `return await foo` will _wait_ for `foo` to resolve or reject if it's a Promise, and throws **before returning** if it rejects. ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-async-function-definitions
      `async_function` 55 15 52 No 42 10.1 55 55 52 42 10.3 6.0 ## See also - [`async function expression`](../operators/async_function) - [`AsyncFunction`](../global_objects/asyncfunction) object - [`await`](../operators/await) - ["Decorating Async Javascript Functions" on "innolitics.com"](https://innolitics.com/10x/javascript-decorators-for-promise-returning-functions/) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function # AsyncFunction The `AsyncFunction` creates a new [async function](../statements/async_function) object. In JavaScript, every asynchronous function is actually an `AsyncFunction` object. Note that `AsyncFunction` is _not_ a global object. It can be obtained with the following code: Object.getPrototypeOf(async function(){}).constructor ## Syntax new AsyncFunction(arg0, functionBody) new AsyncFunction(arg0, arg1, functionBody) new AsyncFunction(arg0, arg1, ...argN, functionBody) ### Parameters `arg1, arg2, ... argN` Names to be used by the function as formal argument names. Each must be a string that corresponds to a valid JavaScript identifier or a list of such strings separated with a comma; for example "`x`", "`theValue`", or "`a,b`". `functionBody` A string containing the JavaScript statements comprising the function definition. ## Description [`async function`](../statements/async_function) objects created with the `AsyncFunction` constructor are parsed when the function is created. This is less efficient than declaring an async function with an [`async function expression`](../statements/async_function) and calling it within your code, because such functions are parsed with the rest of the code. All arguments passed to the function are treated as the names of the identifiers of the parameters in the function to be created, in the order in which they are passed. **Note:** [async functions](../statements/async_function) created with the `AsyncFunction` constructor do not create closures to their creation contexts; they are always created in the global scope. When running them, they will only be able to access their own local variables and global ones, not the ones from the scope in which the `AsyncFunction` constructor was called. This is different from using [`eval`](eval) with code for an async function expression. Invoking the `AsyncFunction` constructor as a function (without using the `new` operator) has the same effect as invoking it as a constructor. ## Examples ### Creating an async function from an AsyncFunction() constructor function resolveAfter2Seconds(x) { return new Promise(resolve => { setTimeout(() => { resolve(x); }, 2000); }); } let AsyncFunction = Object.getPrototypeOf(async function(){}).constructor let a = new AsyncFunction('a', 'b', 'return await resolveAfter2Seconds(a) + await resolveAfter2Seconds(b);'); a(10, 20).then(v => { console.log(v); // prints 30 after 4 seconds }); ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-async-function-objects
      `AsyncFunction` 55 15 52 No 42 10.1 55 55 52 42 10.3 6.0 ## See also - [async function function](../statements/async_function) - [async function expression](../operators/async_function) - [`Function`](function) - [function statement](../statements/function) - [function expression](../operators/function) - [Functions and function scope](../functions) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction # Symbol.asyncIterator The `Symbol.asyncIterator` well-known symbol specifies the default AsyncIterator for an object. If this property is set on an object, it is an async iterable and can be used in a `for await...of` loop. ## Description The `Symbol.asyncIterator` symbol is a builtin symbol that is used to access an object's `@@asyncIterator` method. In order for an object to be async iterable, it must have a `Symbol.asyncIterator` key. Property attributes of `Symbol.asyncIterator` Writable no Enumerable no Configurable no ## Examples ### User-defined Async Iterables You can define your own async iterable by setting the `[Symbol.asyncIterator]` property on an object. const myAsyncIterable = { async* [Symbol.asyncIterator]() { yield "hello"; yield "async"; yield "iteration!"; } }; (async () => { for await (const x of myAsyncIterable) { console.log(x); // expected output: // "hello" // "async" // "iteration!" } })(); When creating an API, remember that async iterables are designed to represent something _iterable_ — like a stream of data or a list —, not to completely replace callbacks and events in most situations. ### Built-in Async Iterables There are currently no built-in JavaScript objects that have the `[Symbol.asyncIterator]` key set by default. However, WHATWG Streams are set to be the first built-in object to be async iterable, with `[Symbol.asyncIterator]` recently landing in the spec. ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-symbol.asynciterator
      `asyncIterator` 63 79 57 No 50 11.1 63 63 57 46 No 8.0 ## See also - [Iteration protocols](../../iteration_protocols) - [for await... of](../../statements/for-await...of) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator # Array.prototype.at() The `at()` method takes an integer value and returns the item at that index, allowing for positive and negative integers. Negative integers count back from the last item in the array. This is not to suggest there is anything wrong with using the square bracket notation. For example `array[0]` would return the first item. However instead of using [`array.length`](length) for latter items; e.g. `array[array.length-1]` for the last item, you can call `array.at(-1)`. [(See the examples below)](#examples) ## Syntax at(index) ### Parameters `index` The index (position) of the array element to be returned. Supports relative indexing from the end of the array when passed a negative index; i.e. if a negative number is used, the element returned will be found by counting back from the end of the array. ### Return value The element in the array matching the given index. Returns [`undefined`](../undefined) if the given index can not be found. ## Examples ### Return the last value of an array The following example provides a function which returns the last element found in a specified array. // Our array with items const cart = ['apple', 'banana', 'pear']; // A function which returns the last item of a given array function returnLast(arr) { return arr.at(-1); } // Get the last item of our array 'cart' const item1 = returnLast(cart); console.log(item1); // Logs: 'pear' // Add an item to our 'cart' array cart.push('orange'); const item2 = returnLast(cart); console.log(item2); // Logs: 'orange' ### Comparing methods This example compares different ways to select the penultimate (last but one) item of an [`Array`](../array). While all the methods shown below are valid, this example highlights the succinctness and readability of the `at()` method. // Our array with items const colors = ['red', 'green', 'blue']; // Using length property const lengthWay = colors[colors.length-2]; console.log(lengthWay); // Logs: 'green' // Using slice() method. Note an array is returned const sliceWay = colors.slice(-2, -1); console.log(sliceWay[0]); // Logs: 'green' // Using at() method const atWay = colors.at(-2); console.log(atWay); // Logs: 'green' # Math.atan() The `Math.atan()` function returns the arctangent (in radians) of a number, that is $$\\mathtt{\\operatorname{Math.atan}(x)} = \\arctan(x) = \\text{the\\ unique}\\; y \\in \\left\\lbrack {- \\frac{\\pi}{2};\\frac{\\pi}{2}} \\right\\rbrack\\,\\text{such\\ that}\\;\\tan(y) = x$$ ## Syntax Math.atan(x) ### Parameters `x` A number. ### Return value The arctangent (in radians) of the given number. ## Description The `Math.atan()` method returns a numeric value between $- \\frac{\\pi}{2}$ and $\\frac{\\pi}{2}$ radians. Because `atan()` is a static method of `Math`, you always use it as `Math.atan()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.atan() Math.atan(1); // 0.7853981633974483 Math.atan(0); // 0 Math.atan(-0); // -0 Math.atan(Infinity); // 1.5707963267948966 Math.atan(-Infinity); // -1.5707963267948966 // The angle that the line [(0,0);(x,y)] forms with the x-axis in a Cartesian coordinate system Math.atan(y / x); Note that you may want to avoid using **±**`Infinity` for stylistic reasons. In this case, [`Math.atan2()`](atan2) with `0` as the second argument may be a better solution. ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.atan
      `atan` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`Math.acos()`](acos) - [`Math.asin()`](asin) - [`Math.atan2()`](atan2) - [`Math.cos()`](cos) - [`Math.sin()`](sin) - [`Math.tan()`](tan) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan # Math.atan2() The `Math.atan2()` function returns the angle in the plane (in radians) between the positive x-axis and the ray from (0,0) to the point (x,y), for `Math.atan2(y,x)`. ## Syntax Math.atan2(y, x) ### Parameters `y` The y coordinate of the point. `x` The x coordinate of the point ### Return value The angle in radians (in \[ − *π*, *π*\]) between the positive x-axis and the ray from (0,0) to the point (x,y). ## Description The `Math.atan2()` method returns a numeric value between -π and π representing the angle theta of an `(x, y)` point. This is the counterclockwise angle, measured in radians, between the positive X axis, and the point `(x, y)`. Note that the arguments to this function pass the y-coordinate first and the x-coordinate second. A simple diagram showing the angle returned by atan2(y, x) `Math.atan2()` is passed separate `x` and `y` arguments, and `Math.atan()` is passed the ratio of those two arguments. Because `atan2()` is a static method of `Math`, you always use it as `Math.atan2()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.atan2() Math.atan2(90, 15); // 1.4056476493802699 Math.atan2(15, 90); // 0.16514867741462683 Math.atan2(±0, -0); // ±PI. Math.atan2(±0, +0); // ±0. Math.atan2(±0, -x); // ±PI for x > 0. Math.atan2(±0, x); // ±0 for x > 0. Math.atan2(-y, ±0); // -PI/2 for y > 0. Math.atan2(y, ±0); // PI/2 for y > 0. Math.atan2(±y, -Infinity); // ±PI for finite y > 0. Math.atan2(±y, +Infinity); // ±0 for finite y > 0. Math.atan2(±Infinity, x); // ±PI/2 for finite x. Math.atan2(±Infinity, -Infinity); // ±3*PI/4. Math.atan2(±Infinity, +Infinity); // ±PI/4. ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.atan2
      `atan2` 1 12 1 4 3 1 1 18 4 10.1 1 1.0 ## See also - [`Math.acos()`](acos) - [`Math.asin()`](asin) - [`Math.atan()`](atan) - [`Math.cos()`](cos) - [`Math.sin()`](sin) - [`Math.tan()`](tan) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2 # Math.atanh() The `Math.atanh()` function returns the hyperbolic arctangent of a number, that is ∀*x* ∈ (−1,1), `Math.atanh` ` (``x``) ` = arctanh (_x_) = the unique *y* such that tanh (_y_) = *x* ## Syntax Math.atanh(x) ### Parameters `x` A number. ### Return value The hyperbolic arctangent of the given number. ## Description Because `atanh()` is a static method of `Math`, you always use it as `Math.atanh()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.atanh() Math.atanh(-2); // NaN Math.atanh(-1); // -Infinity Math.atanh(0); // 0 Math.atanh(0.5); // 0.5493061443340548 Math.atanh(1); // Infinity Math.atanh(2); // NaN For values greater than 1 or less than -1, [`NaN`](../nan) is returned. ## Polyfill For |_x_| < 1, we have $\\operatorname{artanh}(x) = \\frac{1}{2}\\ln\\left( \\frac{1 + x}{1 - x} \\right)$ so this can be emulated by the following function: Math.atanh = Math.atanh || function(x) { return Math.log((1+x)/(1-x)) / 2; }; ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.atanh
      `atanh` 38 12 25 No 25 8 38 38 25 25 8 3.0 ## See also - [`Math.acosh()`](acosh) - [`Math.asinh()`](asinh) - [`Math.cosh()`](cosh) - [`Math.sinh()`](sinh) - [`Math.tanh()`](tanh) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh # Atomics The `Atomics` object provides atomic operations as static methods. They are used with [`SharedArrayBuffer`](sharedarraybuffer) and [`ArrayBuffer`](arraybuffer) objects. ## Description The Atomic operations are installed on an `Atomics` module. Unlike the other global objects, `Atomics` is not a constructor. You cannot use it with a [`new` operator](../operators/new) or invoke the `Atomics` object as a function. All properties and methods of `Atomics` are static (as is the case with the [`Math`](math) object, for example). ### Atomic operations When memory is shared, multiple threads can read and write the same data in memory. Atomic operations make sure that predictable values are written and read, that operations are finished before the next operation starts and that operations are not interrupted. ### Wait and notify The `wait()` and `notify()` methods are modeled on Linux futexes ("fast user-space mutex") and provide ways for waiting until a certain condition becomes true and are typically used as blocking constructs. ## Static methods [`Atomics.add()`](atomics/add) Adds the provided value to the existing value at the specified index of the array. Returns the old value at that index. [`Atomics.and()`](atomics/and) Computes a bitwise AND on the value at the specified index of the array with the provided value. Returns the old value at that index. [`Atomics.compareExchange()`](atomics/compareexchange) Stores a value at the specified index of the array, if it equals a value. Returns the old value. [`Atomics.exchange()`](atomics/exchange) Stores a value at the specified index of the array. Returns the old value. [`Atomics.isLockFree(size)`](atomics/islockfree) An optimization primitive that can be used to determine whether to use locks or atomic operations. Returns `true` if an atomic operation on arrays of the given element size will be implemented using a hardware atomic operation (as opposed to a lock). Experts only. [`Atomics.load()`](atomics/load) Returns the value at the specified index of the array. [`Atomics.notify()`](atomics/notify) Notifies agents that are waiting on the specified index of the array. Returns the number of agents that were notified. [`Atomics.or()`](atomics/or) Computes a bitwise OR on the value at the specified index of the array with the provided value. Returns the old value at that index. [`Atomics.store()`](atomics/store) Stores a value at the specified index of the array. Returns the value. [`Atomics.sub()`](atomics/sub) Subtracts a value at the specified index of the array. Returns the old value at that index. [`Atomics.wait()`](atomics/wait) Verifies that the specified index of the array still contains a value and sleeps awaiting or times out. Returns either "`ok`", "`not-equal`", or "`timed-out`". If waiting is not allowed in the calling agent then it throws an [`Error`](error) exception. (Most browsers will not allow `wait()` on the browser's main thread.) [`Atomics.xor()`](atomics/xor) Computes a bitwise XOR on the value at the specified index of the array with the provided value. Returns the old value at that index. ## Examples ### Using Atomics const sab = new SharedArrayBuffer(1024); const ta = new Uint8Array(sab); ta[0]; // 0 ta[0] = 5; // 5 Atomics.add(ta, 0, 12); // 5 Atomics.load(ta, 0); // 17 Atomics.and(ta, 0, 1); // 17 Atomics.load(ta, 0); // 1 Atomics.compareExchange(ta, 0, 5, 12); // 1 Atomics.load(ta, 0); // 1 Atomics.exchange(ta, 0, 12); // 1 Atomics.load(ta, 0); // 12 Atomics.isLockFree(1); // true Atomics.isLockFree(2); // true Atomics.isLockFree(3); // false Atomics.isLockFree(4); // true Atomics.or(ta, 0, 1); // 12 Atomics.load(ta, 0); // 13 Atomics.store(ta, 0, 12); // 12 Atomics.sub(ta, 0, 2); // 12 Atomics.load(ta, 0); // 10 Atomics.xor(ta, 0, 1); // 10 Atomics.load(ta, 0); // 11 ### Waiting and notifiying Given a shared `Int32Array`: const sab = new SharedArrayBuffer(1024); const int32 = new Int32Array(sab); A reading thread is sleeping and waiting on location 0 which is expected to be 0. As long as that is true, it will not go on. However, once the writing thread has stored a new value, it will be notified by the writing thread and return the new value (123). Atomics.wait(int32, 0, 0); console.log(int32[0]); // 123 A writing thread stores a new value and notifies the waiting thread once it has written: console.log(int32[0]); // 0; Atomics.store(int32, 0, 123); Atomics.notify(int32, 0, 1); ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-atomics-object
      `Atomics` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `Atomic_operations_on_non-shared_buffers` No No 79 No No No No No 79 No No No `add` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `and` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `compareExchange` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `exchange` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `isLockFree` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `load` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled SharedArrayBuffer on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled SharedArrayBuffer on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `notify` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 78 63 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 48-55 46-48 The `count` parameter defaults to `0` instead of the later-specified `+Infinity`. No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 63 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 48-55 46-48 The `count` parameter defaults to `0` instead of the later-specified `+Infinity`. No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `or` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `store` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `sub` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled SharedArrayBuffer on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled SharedArrayBuffer on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `wait` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 48-55 46-48 The method returns values `Atomics.OK`, `Atomics.TIMEDOUT`, and `Atomics.NOTEQUAL`, instead of the later-specified strings. No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 48-55 46-48 The method returns values `Atomics.OK`, `Atomics.TIMEDOUT`, and `Atomics.NOTEQUAL`, instead of the later-specified strings. No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. `xor` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. ## See also - [`ArrayBuffer`](arraybuffer) - [JavaScript typed arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) - [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) - [parlib-simple](https://github.com/lars-t-hansen/parlib-simple) – a simple library providing synchronization and work distribution abstractions. - [Shared Memory – a brief tutorial](https://github.com/tc39/ecmascript_sharedmem/blob/master/TUTORIAL.md) - [A Taste of JavaScript's New Parallel Primitives – Mozilla Hacks](https://hacks.mozilla.org/2016/05/a-taste-of-javascripts-new-parallel-primitives/) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics # await The `await` operator is used to wait for a [`Promise`](../global_objects/promise). It can only be used inside an [`async function`](../statements/async_function) within regular JavaScript code; however it can be used on its own with [JavaScript modules.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) ## Syntax [rv] = await expression; `expression` A [`Promise`](../global_objects/promise) or any value to wait for. `rv` Returns the fulfilled value of the promise, or the value itself if it's not a `Promise`. ## Description The `await` expression causes `async` function execution to pause until a `Promise` is settled (that is, fulfilled or rejected), and to resume execution of the `async` function after fulfillment. When resumed, the value of the `await` expression is that of the fulfilled `Promise`. If the `Promise` is rejected, the `await` expression throws the rejected value. If the value of the _expression_ following the `await` operator is not a `Promise`, it's converted to a [resolved Promise](../global_objects/promise/resolve). An `await` splits execution flow, allowing the caller of the async function to resume execution. After the `await` defers the continuation of the async function, execution of subsequent statements ensues. If this `await` is the last expression executed by its function, execution continues by returning to the function's caller a pending `Promise` for completion of the `await`'s function and resuming execution of that caller. ## Examples ### Awaiting a promise to be fulfilled If a `Promise` is passed to an `await` expression, it waits for the `Promise` to be fulfilled and returns the fulfilled value. function resolveAfter2Seconds(x) { return new Promise(resolve => { setTimeout(() => { resolve(x); }, 2000); }); } async function f1() { var x = await resolveAfter2Seconds(10); console.log(x); // 10 } f1(); ### Thenable objects [`Thenable objects`](../global_objects/promise/then) will be fulfilled just the same. async function f2() { const thenable = { then: function(resolve, _reject) { resolve('resolved!') } }; console.log(await thenable); // resolved! } f2(); ### Conversion to promise If the value is not a `Promise`, it converts the value to a resolved `Promise`, and waits for it. async function f3() { var y = await 20; console.log(y); // 20 } f3(); ### Promise rejection If the `Promise` is rejected, the rejected value is thrown. async function f4() { try { var z = await Promise.reject(30); } catch(e) { console.error(e); // 30 } } f4(); ### Handling rejected promises Handle rejected `Promise` without try block. var response = await promisedFunction().catch((err) => { console.error(err); }); // response will be undefined if the promise is rejected ### Top level await You can use the `await` keyword on its own (outside of an async function) within a [JavaScript module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules). This means modules, with child modules that use `await`, wait for the child module to execute before they themselves run. All while not blocking other child modules from loading. Here is an example of a simple module using the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and specifying await within the `export statement`. Any modules that include this will wait for the fetch to resolve before running any code. // fetch request const colors = fetch('../data/colors.json') .then(response => response.json()); export default await colors; # Warning: 08/09 is not a legal ECMA-262 octal constant The JavaScript warning "08 (or 09) is not a legal ECMA-262 octal constant" occurs when `08` or `09` number literals are used. They can't be interpreted as an octal number. ## Message Warning: SyntaxError: 08 is not a legal ECMA-262 octal constant. Warning: SyntaxError: 09 is not a legal ECMA-262 octal constant. ## Error type Warning. JavaScript execution won't be halted. ## What went wrong? Decimal literals can start with a zero (`0`) followed by another decimal digit, but If all digits after the leading `0` are smaller than 8, the number is interpreted as an octal number. Because this is not the case with `08` and `09`, JavaScript warns about it. Note that octal literals and octal escape sequences are deprecated and will present an additional deprecation warning. With ECMAScript 6 and later, the syntax uses a leading zero followed by a lowercase or uppercase Latin letter "O" (`0o` or `0O)`. See the page about [lexical grammar](../lexical_grammar#octal) for more information. ## Examples ### Invalid octal numbers 08; 09; // SyntaxError: 08 is not a legal ECMA-262 octal constant // SyntaxError: "0"-prefixed octal literals and octal escape sequences // are deprecated ### Valid octal numbers Use a leading zero followed by the letter "o"; 0O755; 0o644; ## See also - [Lexical grammar](../lexical_grammar#octal) - [SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated](deprecated_octal) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Bad_octal # RangeError: radix must be an integer The JavaScript exception "radix must be an integer at least 2 and no greater than 36" occurs when the optional `radix` parameter of the [`Number.prototype.toString()`](../global_objects/number/tostring) or the [`BigInt.prototype.toString()`](../global_objects/bigint/tostring) method was specified and is not between 2 and 36. ## Message RangeError: invalid argument (Edge) RangeError: radix must be an integer at least 2 and no greater than 36 (Firefox) RangeError: toString() radix argument must be between 2 and 36 (Chrome) ## Error type [`RangeError`](../global_objects/rangeerror) ## What went wrong? The optional `radix` parameter of the [`Number.prototype.toString()`](../global_objects/number/tostring) or the [`BigInt.prototype.toString()`](../global_objects/bigint/tostring) method was specified. Its value must be an integer (a number) between 2 and 36, specifying the base of the number system to be used for representing numeric values. For example, the decimal (base 10) number 169 is represented in hexadecimal (base 16) as A9. Why is this parameter's value limited to 36? A radix that is larger than 10 uses alphabetical characters as digits; therefore, the radix can't be larger than 36, since the Latin alphabet (used by English and many other languages) only has 26 characters. The most common radixes: - 2 for [binary numbers](https://en.wikipedia.org/wiki/Binary_number), - 8 for [octal numbers](https://en.wikipedia.org/wiki/Octal), - 10 for [decimal numbers](https://en.wikipedia.org/wiki/Decimal), - 16 for [hexadecimal numbers](https://en.wikipedia.org/wiki/Hexadecimal). ## Examples ### Invalid cases (42).toString(0); (42).toString(1); (42).toString(37); (42).toString(150); // You cannot use a string like this for formatting: (12071989).toString('MM-dd-yyyy'); ### Valid cases (42).toString(2); // "101010" (binary) (13).toString(8); // "15" (octal) (0x42).toString(10); // "66" (decimal) (100000).toString(16) // "186a0" (hexadecimal) ## See also - [`Number.prototype.toString()`](../global_objects/number/tostring) - [`BigInt.prototype.toString()`](../global_objects/bigint/tostring) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Bad_radix # SyntaxError: invalid regular expression flag "x" The JavaScript exception "invalid regular expression flag" occurs when the flags, defined after the second slash in regular expression literal, are not one of `g`, `i`, `m`, `s`, `u`, or `y`. ## Message SyntaxError: Syntax error in regular expression (Edge) SyntaxError: invalid regular expression flag "x" (Firefox) SyntaxError: Invalid regular expression flags (Chrome) ## Error type [`SyntaxError`](../global_objects/syntaxerror) ## What went wrong? There are invalid regular expression flags in the code. In a regular expression literal, which consists of a pattern enclosed between slashes, the flags are defined after the second slash. They can also be defined in the constructor function of the [`RegExp`](../global_objects/regexp) object (second parameter). Regular expression flags can be used separately or together in any order, but there are only six of them in ECMAScript. To include a flag with the regular expression, use this syntax: var re = /pattern/flags; or var re = new RegExp('pattern', 'flags');
      Regular expression flags
      FlagDescription
      gGlobal search.
      iCase-insensitive search.
      mMulti-line search.
      sAllow . to match newlines (added in ECMAScript 2018)
      uUnicode; treat pattern as a sequence of Unicode code points
      yPerform a "sticky" search that matches starting at the current position in the target string. See sticky
      ## Examples There are only six valid regular expression flags. /foo/bar; // SyntaxError: invalid regular expression flag "b" Did you intend to create a regular expression? An expression containing two slashes is interpreted as a regular expression literal. let obj = { url: /docs/Web }; // SyntaxError: invalid regular expression flag "W" Or did you mean to create a string instead? Add single or double quotes to create a string literal. let obj = { url: '/docs/Web' }; ### Valid regular expression flags See the table above for the six valid regular expression flags that are allowed in JavaScript. /foo/g; /foo/gims; /foo/uy; ## See also - [Regular expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) - [XRegEx flags](https://xregexp.com/flags/) – regular expression library that provides four new flags (`n`, `s`, `x`, `A`) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Bad_regexp_flag # SyntaxError: return not in function The JavaScript exception "return (or yield) not in function" occurs when a `return` or `yield` statement is called outside of a [function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions). ## Message SyntaxError: 'return' statement outside of function (Edge) SyntaxError: return not in function (Firefox) SyntaxError: yield not in function (Firefox) ## Error type [`SyntaxError`](../global_objects/syntaxerror). ## What went wrong? A `return` or `yield` statement is called outside of a [function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions). Maybe there are missing curly brackets somewhere? The `return` and `yield` statements must be in a function, because they end (or pause and resume) function execution and specify a value to be returned to the function caller. ## Examples ### Missing curly brackets var cheer = function(score) { if (score === 147) return 'Maximum!'; }; if (score > 100) { return 'Century!'; } } // SyntaxError: return not in function The curly brackets look correct at a first glance, but this code snippet is missing a `{` after the first `if` statement. Correct would be: var cheer = function(score) { if (score === 147) { return 'Maximum!'; } if (score > 100) { return 'Century!'; } }; ## See also - `return` - `yield` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Bad_return_or_yield # Intl.Locale.prototype.baseName The `Intl.Locale.prototype.baseName` property returns a substring of the `Locale`'s string representation, containing core information about the `Locale`. ## Description An [`Intl.Locale`](../locale) object represents a parsed local and options for that locale. The `baseName` property returns basic, core information about the Locale in the form of a substring of the complete data string. Specifically, the property returns the substring containing the language, and the script and region if available. `baseName` returns the `language ["-" script] ["-" region] *("-" variant)` subsequence of the [unicode_language_id grammar](https://www.unicode.org/reports/tr35/#Identifiers). ## Examples ### Basic Example let myLoc = new Intl.Locale("fr-Latn-CA"); // Sets locale to Canadian French console.log(myLoc.toString()); // Prints out "fr-Latn-CA-u-ca-gregory" console.log(myLoc.baseName); // Prints out "fr-Latn-CA" ### Example with options in the input string // Sets language to Japanese, region to Japan, // calendar to Gregorian, hour cycle to 24 hours let japan = new Intl.Locale("ja-JP-u-ca-gregory-hc-24"); console.log(japan.toString()); // Prints out "ja-JP-u-ca-gregory-hc-h24" console.log(japan.baseName); // Prints out "ja-JP" ### Example with options that override input string // Input string indicates language as Dutch and region as Belgium, // but options object overrides the region and sets it to the Netherlands let dutch = new Intl.Locale("nl-Latn-BE", {region: "NL"}); console.log(dutch.baseName); // Prints out "nl-Latn-NL" ## Specifications
      Specification
      ECMAScript Internationalization API Specification (ECMAScript Internationalization API)
      #sec-Intl.Locale.prototype.baseName
      `baseName` 74 79 75 No 62 14 74 74 79 53 14 11.0 ## See also - [`Intl.Locale`](../locale) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/baseName # String.prototype.big() **Deprecated** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the [compatibility table](#browser_compatibility) at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time. The `big()` method creates a [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/big) HTML element that causes a string to be displayed in a big font. **Note:** The <big> element has been removed in [HTML5](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5) and shouldn't be used anymore. Instead web developers should use [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS) properties. ## Syntax big() ### Return value A string containing a [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/big) HTML element. ## Description The `big()` method embeds a string in a `` element: "`str`". ## Examples ### Using big() The following example uses string methods to change the size of a string: var worldString = 'Hello, world'; console.log(worldString.small()); // Hello, world console.log(worldString.big()); // Hello, world console.log(worldString.fontsize(7)); // Hello, world With the [`element.style`](https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style) object you can get the element's `style` attribute and manipulate it more generically, for example: document.getElementById('yourElemId').style.fontSize = '2em'; ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-string.prototype.big
      `big` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`String.prototype.fontsize()`](fontsize) - [`String.prototype.small()`](small) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/big # BigInt `BigInt` is a built-in object whose constructor returns a `bigint` [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) — also called a **BigInt value**, or sometimes just a **BigInt** — to represent whole numbers larger than 253 - 1 ([`Number.MAX_SAFE_INTEGER`](number/max_safe_integer)), which is the largest number JavaScript can represent with a `number` [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) (or _Number value_). BigInt values can be used for arbitrarily large integers. ## Description A **BigInt value**, also sometimes just called a **BigInt**, is a `bigint` [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive), created by appending `n` to the end of an integer literal, or by calling the [`BigInt()`](bigint/bigint) constructor (but without the `new` operator) and giving it an integer value or string value. const previouslyMaxSafeInteger = 9007199254740991n const alsoHuge = BigInt(9007199254740991) // ↪ 9007199254740991n const hugeString = BigInt("9007199254740991") // ↪ 9007199254740991n const hugeHex = BigInt("0x1fffffffffffff") // ↪ 9007199254740991n const hugeOctal = BigInt("0o377777777777777777") // ↪ 9007199254740991n const hugeBin = BigInt("0b11111111111111111111111111111111111111111111111111111") // ↪ 9007199254740991n BigInt values are similar to Number values in some ways, but also differ in a few key matters: A BigInt value cannot be used with methods in the built-in [`Math`](math) object and cannot be mixed with a Number value in operations; they must be coerced to the same type. Be careful coercing values back and forth, however, as the precision of a BigInt value may be lost when it is coerced to a Number value. ### Type information When tested against `typeof`, a BigInt value (`bigint` primitive) will give "`bigint`": typeof 1n === 'bigint' // true typeof BigInt('1') === 'bigint' // true A BigInt value can also be wrapped in an `Object`: typeof Object(1n) === 'object' // true ### Operators The following operators may be used with BigInt values or object-wrapped BigInt values: + * - % ** [Bitwise operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators) are supported as well, except `>>>` (zero-fill right shift), as every BigInt value is signed. Also unsupported is the unary operator (`+`), [in order to not break asm.js](https://github.com/tc39/proposal-bigint/blob/master/ADVANCED.md#dont-break-asmjs). const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER) // ↪ 9007199254740991n const maxPlusOne = previousMaxSafe + 1n // ↪ 9007199254740992n const theFuture = previousMaxSafe + 2n // ↪ 9007199254740993n, this works now! const multi = previousMaxSafe * 2n // ↪ 18014398509481982n const subtr = multi – 10n // ↪ 18014398509481972n const mod = multi % 10n // ↪ 2n const bigN = 2n ** 54n // ↪ 18014398509481984n bigN * -1n // ↪ –18014398509481984n The `/` operator also works as expected with whole numbers — but operations with a fractional result will be truncated when used with a BigInt value — they won't return any fractional digits. const expected = 4n / 2n // ↪ 2n const truncated = 5n / 2n // ↪ 2n, not 2.5n ### Comparisons A BigInt value is not strictly equal to a Number value, but it _is_ loosely so: 0n === 0 // ↪ false 0n == 0 // ↪ true A Number value and a BigInt value may be compared as usual: 1n < 2 // ↪ true 2n > 1 // ↪ true 2 > 2 // ↪ false 2n > 2 // ↪ false 2n >= 2 // ↪ true BigInt values and Number values may be mixed in arrays and sorted: const mixed = [4n, 6, -12n, 10, 4, 0, 0n] // ↪ [4n, 6, -12n, 10, 4, 0, 0n] mixed.sort() // default sorting behavior // ↪ [ -12n, 0, 0n, 10, 4n, 4, 6 ] mixed.sort((a, b) => a - b) // won't work since subtraction will not work with mixed types // TypeError: can't convert BigInt value to Number value // sort with an appropriate numeric comparator mixed.sort((a, b) => (a < b) ? -1 : ((a > b) ? 1 : 0)) // ↪ [ -12n, 0, 0n, 4n, 4, 6, 10 ] Note that comparisons with `Object`-wrapped BigInt values act as with other objects, only indicating equality when the same object instance is compared: 0n === Object(0n) // false Object(0n) === Object(0n) // false const o = Object(0n) o === o // true ### Conditionals A BigInt value behaves like a Number value in cases where: - it is converted to a [`Boolean`](boolean): via the [`Boolean`](boolean) function; - when used with [logical operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators) `||`, `&&`, and `!`; or - within a conditional test like an [`if`](../statements/if...else) statement. if (0n) { console.log('Hello from the if!') } else { console.log('Hello from the else!') } // ↪ "Hello from the else!" 0n || 12n // ↪ 12n 0n && 12n // ↪ 0n Boolean(0n) // ↪ false Boolean(12n) // ↪ true !12n // ↪ false !0n // ↪ true ## Constructor [`BigInt()`](bigint/bigint) Creates a new BigInt value. ## Static methods [`BigInt.asIntN()`](bigint/asintn) Clamps a BigInt value to a signed integer value, and returns that value. [`BigInt.asUintN()`](bigint/asuintn) Clamps a BigInt value to an unsigned integer value, and returns that value. ## Instance methods [`BigInt.prototype.toLocaleString()`](bigint/tolocalestring) Returns a string with a language-sensitive representation of this BigInt value. Overrides the [`Object.prototype.toLocaleString()`](object/tolocalestring) method. [`BigInt.prototype.toString()`](bigint/tostring) Returns a string representing this BigInt value in the specified radix (base). Overrides the [`Object.prototype.toString()`](object/tostring) method. [`BigInt.prototype.valueOf()`](bigint/valueof) Returns this BigInt value. Overrides the [`Object.prototype.valueOf()`](object/valueof) method. ## Usage recommendations ### Coercion Because coercing between Number values and BigInt values can lead to loss of precision, the following are recommended: - Only use a BigInt value when values greater than 253 are reasonably expected. - Don't coerce between BigInt values and Number values. ### Cryptography The operations supported on BigInt values are not constant-time. BigInt values are therefore [unsuitable for use in cryptography](https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html). ### Use within JSON Using [`JSON.stringify()`](json/stringify) with any BigInt value will raise a `TypeError`, as BigInt values aren't serialized in JSON by default. However, you can implement your own `toJSON` method: BigInt.prototype.toJSON = function() { return this.toString() } Instead of throwing, `JSON.stringify` now produces a string like this: JSON.stringify(BigInt(1)) // '"1"' ## Examples ### Calculating Primes // Returns true if the passed BigInt value is a prime number function isPrime(p) { for (let i = 2n; i * i <= p; i++) { if (p % i === 0n) return false; } return true } // Takes a BigInt value as an argument, returns nth prime number as a BigInt value function nthPrime(nth) { let maybePrime = 2n let prime = 0n while (nth >= 0n) { if (isPrime(maybePrime)) { nth-- prime = maybePrime } maybePrime++ } return prime } nthPrime(20n) // ↪ 73n ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-bigint-objects
      `BigInt` 67 79 68 No 54 14 67 67 68 48 14 9.0 `BigInt` 67 79 68 No 54 14 67 67 68 48 14 9.0 `asIntN` 67 79 68 No 54 14 67 67 68 48 14 9.0 `asUintN` 67 79 68 No 54 14 67 67 68 48 14 9.0 `toLocaleString` 67 79 68 No 54 14 67 67 68 48 14 9.0 `toString` 67 79 68 No 54 14 67 67 68 48 14 9.0 `valueOf` 67 79 68 No 54 14 67 67 68 48 14 9.0 ## See also - [`Number`](number) - [`Number.MAX_SAFE_INTEGER`](number/max_safe_integer) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt # BigInt64Array The `BigInt64Array` typed array represents an array of 64-bit signed integers in the platform byte order. If control over byte order is needed, use [`DataView`](dataview) instead. The contents are initialized to `0n`. Once established, you can reference elements in the array using the object's methods, or by using standard array index syntax (that is, using bracket notation). ## Constructor [`BigInt64Array()`](bigint64array/bigint64array) Creates a new `BigInt64Array` object. ## Static properties [`BigInt64Array.BYTES_PER_ELEMENT`](typedarray/bytes_per_element) Returns a number value of the element size. `8` in the case of a `BigInt64Array`. [`BigInt64Array.name`](typedarray/name) Returns the string value of the constructor name. In the case of the `BigInt64Array` type, this is "BigInt64Array". ## Static methods [`BigInt64Array.from()`](typedarray/from) Creates a new `BigInt64Array` from an array-like or iterable object. See also [`Array.from()`](array/from). [`BigInt64Array.of()`](typedarray/of) Creates a new `BigInt64Array` with a variable number of arguments. See also [`Array.of()`](array/of). ## Instance properties [`BigInt64Array.prototype.buffer`](typedarray/buffer) Returns the [`ArrayBuffer`](arraybuffer) referenced by the `BigInt64Array`. This is fixed at construction time and thus **read only**. [`BigInt64Array.prototype.byteLength`](typedarray/bytelength) Returns the length (in bytes) of the `BigInt64Array` from the start of its [`ArrayBuffer`](arraybuffer). This is fixed at construction time and thus **read only.** [`BigInt64Array.prototype.byteOffset`](typedarray/byteoffset) Returns the offset (in bytes) of the `BigInt64Array` from the start of its [`ArrayBuffer`](arraybuffer). This is fixed at construction time and thus **read only.** [`BigInt64Array.prototype.length`](typedarray/length) Returns the number of elements hold in the `BigInt64Array`. This is fixed at construction time and thus **read only.** ## Instance methods [`BigInt64Array.prototype.copyWithin()`](typedarray/copywithin) Copies a sequence of array elements within the array. See also [`Array.prototype.copyWithin()`](array/copywithin). [`BigInt64Array.prototype.entries()`](typedarray/entries) Returns a new `Array Iterator` object that contains the key/value pairs for each index in the array. See also [`Array.prototype.entries()`](array/entries). [`BigInt64Array.prototype.every()`](typedarray/every) Tests whether all elements in the array pass the test provided by a function. See also [`Array.prototype.every()`](array/every). [`BigInt64Array.prototype.fill()`](typedarray/fill) Fills all the elements of an array from a start index to an end index with a static value. See also [`Array.prototype.fill()`](array/fill). [`BigInt64Array.prototype.filter()`](typedarray/filter) Creates a new array with all of the elements of this array for which the provided filtering function returns true. See also [`Array.prototype.filter()`](array/filter). [`BigInt64Array.prototype.find()`](typedarray/find) Returns the found value in the array if an element in the array satisfies the provided testing function, or `undefined` if not found. See also [`Array.prototype.find()`](array/find). [`BigInt64Array.prototype.findIndex()`](typedarray/findindex) Returns the found index in the array if an element in the array satisfies the provided testing function, or -1 if not found. See also [`Array.prototype.findIndex()`](array/findindex). [`BigInt64Array.prototype.forEach()`](typedarray/foreach) Calls a function for each element in the array. See also [`Array.prototype.forEach()`](array/foreach). [`BigInt64Array.prototype.includes()`](typedarray/includes) Determines whether a typed array includes a certain element, returning `true` or `false` as appropriate. See also [`Array.prototype.includes()`](array/includes). [`BigInt64Array.prototype.indexOf()`](typedarray/indexof) Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found. See also [`Array.prototype.indexOf()`](array/indexof). [`BigInt64Array.prototype.join()`](typedarray/join) Joins all elements of an array into a string. See also [`Array.prototype.join()`](array/join). [`BigInt64Array.prototype.keys()`](typedarray/keys) Returns a new `Array Iterator` that contains the keys for each index in the array. See also [`Array.prototype.keys()`](array/keys). [`BigInt64Array.prototype.lastIndexOf()`](typedarray/lastindexof) Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found. See also [`Array.prototype.lastIndexOf()`](array/lastindexof). [`BigInt64Array.prototype.map()`](typedarray/map) Creates a new array with the results of calling a provided function on every element in this array. See also [`Array.prototype.map()`](array/map). [`BigInt64Array.prototype.reduce()`](typedarray/reduce) Applies a function against an accumulator and each value of the array (from left-to-right) so as to reduce it to a single value. See also [`Array.prototype.reduce()`](array/reduce). [`BigInt64Array.prototype.reduceRight()`](typedarray/reduceright) Applies a function against an accumulator and each value of the array (from right-to-left) so as to reduce it to a single value. See also [`Array.prototype.reduceRight()`](array/reduceright). [`BigInt64Array.prototype.reverse()`](typedarray/reverse) Reverses the order of the elements of an array — the first becomes the last, and the last becomes the first. See also [`Array.prototype.reverse()`](array/reverse). [`BigInt64Array.prototype.set()`](typedarray/set) Stores multiple values in the typed array, reading input values from a specified array. [`BigInt64Array.prototype.slice()`](typedarray/slice) Extracts a section of an array and returns a new array. See also [`Array.prototype.slice()`](array/slice). [`BigInt64Array.prototype.some()`](typedarray/some) Returns true if at least one element in this array satisfies the provided testing function. See also [`Array.prototype.some()`](array/some). [`BigInt64Array.prototype.sort()`](typedarray/sort) Sorts the elements of an array in place and returns the array. See also [`Array.prototype.sort()`](array/sort). [`BigInt64Array.prototype.subarray()`](typedarray/subarray) Returns a new `BigUint64Array` from the given start and end element index. [`BigInt64Array.prototype.values()`](typedarray/values) Returns a new `Array Iterator` object that contains the values for each index in the array. See also [`Array.prototype.values()`](array/values). [`BigInt64Array.prototype.toLocaleString()`](typedarray/tolocalestring) Returns a localized string representing the array and its elements. See also [`Array.prototype.toLocaleString()`](array/tolocalestring). [`BigInt64Array.prototype.toString()`](typedarray/tostring) Returns a string representing the array and its elements. See also [`Array.prototype.toString()`](array/tostring). [`BigInt64Array.prototype[@@iterator]()`](typedarray/@@iterator) Returns a new `Array Iterator` object that contains the values for each index in the array. ## Examples ### Different ways to create a `BigInt64Array` // From a length var bigint64 = new BigInt64Array(2); bigint64[0] = 42n; console.log(bigint64[0]); // 42n console.log(bigint64.length); // 2 console.log(bigint64.BYTES_PER_ELEMENT); // 8 // From an array var arr = new BigInt64Array([21n,31n]); console.log(arr[1]); // 31n // From another TypedArray var x = new BigInt64Array([21n, 31n]); var y = new BigInt64Array(x); console.log(y[0]); // 21n // From an ArrayBuffer var buffer = new ArrayBuffer(32); var z = new BigInt64Array(buffer, 0, 4); // From an iterable var iterable = function*(){ yield* [1n, 2n, 3n]; }(); var bigint64 = new BigInt64Array(iterable); // BigInt64Array[1n, 2n, 3n] ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-typedarray-objects
      `BigInt64Array` 67 79 68 No 54 No 67 67 68 48 No 9.0 `BigInt64Array` 67 79 68 No 54 No 67 67 68 48 No 9.0 ## See also - [JavaScript typed arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) - [`BigUint64Array`](biguint64array) - [`DataView`](dataview) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt64Array # BigUint64Array The `BigUint64Array` typed array represents an array of 64-bit unsigned integers in the platform byte order. If control over byte order is needed, use [`DataView`](dataview) instead. The contents are initialized to `0n`. Once established, you can reference elements in the array using the object's methods, or by using standard array index syntax (that is, using bracket notation). ## Constructor [`BigUint64Array()`](biguint64array/biguint64array) Creates a new `BigUint64Array` object. ## Static properties [`BigUint64Array.BYTES_PER_ELEMENT`](typedarray/bytes_per_element) Returns a number value of the element size. `8` in the case of a `BigUint64Array`. [`BigUint64Array.name`](typedarray/name) Returns the string value of the constructor name. In the case of the `BigUint64Array` type this is "BigUint64Array". ## Static methods [`BigUint64Array.from()`](typedarray/from) Creates a new `BigUint64Array` from an array-like or iterable object. See also [`Array.from()`](array/from). [`BigUint64Array.of()`](typedarray/of) Creates a new `BigUint64Array` with a variable number of arguments. See also [`Array.of()`](array/of). ## Instance properties [`BigUint64Array.prototype.buffer`](typedarray/buffer) Returns the [`ArrayBuffer`](arraybuffer) referenced by the `BigUint64Array`. This is fixed at construction time and thus **read only**. [`BigUint64Array.prototype.byteLength`](typedarray/bytelength) Returns the length (in bytes) of the `BigUint64Array` from the start of its [`ArrayBuffer`](arraybuffer). This is fixed at construction time and thus **read only.** [`BigUint64Array.prototype.byteOffset`](typedarray/byteoffset) Returns the offset (in bytes) of the `BigUint64Array` from the start of its [`ArrayBuffer`](arraybuffer). This is fixed at construction time and thus **read only.** [`BigUint64Array.prototype.length`](typedarray/length) Returns the number of elements hold in the `BigUint64Array`. This is fixed at construction time and thus **read only.** ## Instance methods [`BigUint64Array.prototype.copyWithin()`](typedarray/copywithin) Copies a sequence of array elements within the array. See also [`Array.prototype.copyWithin()`](array/copywithin). [`BigUint64Array.prototype.entries()`](typedarray/entries) Returns a new `Array Iterator` object that contains the key/value pairs for each index in the array. See also [`Array.prototype.entries()`](array/entries). [`BigUint64Array.prototype.every()`](typedarray/every) Tests whether all elements in the array pass the test provided by a function. See also [`Array.prototype.every()`](array/every). [`BigUint64Array.prototype.fill()`](typedarray/fill) Fills all the elements of an array from a start index to an end index with a static value. See also [`Array.prototype.fill()`](array/fill). [`BigUint64Array.prototype.filter()`](typedarray/filter) Creates a new array with all of the elements of this array for which the provided filtering function returns true. See also [`Array.prototype.filter()`](array/filter). [`BigUint64Array.prototype.find()`](typedarray/find) Returns the found value in the array if an element in the array satisfies the provided testing function, or `undefined` if not found. See also [`Array.prototype.find()`](array/find). [`BigUint64Array.prototype.findIndex()`](typedarray/findindex) Returns the found index in the array if an element in the array satisfies the provided testing function, or -1 if not found. See also [`Array.prototype.findIndex()`](array/findindex). [`BigUint64Array.prototype.forEach()`](typedarray/foreach) Calls a function for each element in the array. See also [`Array.prototype.forEach()`](array/foreach). [`BigUint64Array.prototype.includes()`](typedarray/includes) Determines whether a typed array includes a certain element, returning `true` or `false` as appropriate. See also [`Array.prototype.includes()`](array/includes). [`BigUint64Array.prototype.indexOf()`](typedarray/indexof) Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found. See also [`Array.prototype.indexOf()`](array/indexof). [`BigUint64Array.prototype.join()`](typedarray/join) Joins all elements of an array into a string. See also [`Array.prototype.join()`](array/join). [`BigUint64Array.prototype.keys()`](typedarray/keys) Returns a new `Array Iterator` that contains the keys for each index in the array. See also [`Array.prototype.keys()`](array/keys). [`BigUint64Array.prototype.lastIndexOf()`](typedarray/lastindexof) Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found. See also [`Array.prototype.lastIndexOf()`](array/lastindexof). [`BigUint64Array.prototype.map()`](typedarray/map) Creates a new array with the results of calling a provided function on every element in this array. See also [`Array.prototype.map()`](array/map). [`BigUint64Array.prototype.reduce()`](typedarray/reduce) Apply a function against an accumulator and each value of the array (from left-to-right) so as to reduce it to a single value. See also [`Array.prototype.reduce()`](array/reduce). [`BigUint64Array.prototype.reduceRight()`](typedarray/reduceright) Applies a function against an accumulator and each value of the array (from right-to-left) so as to reduce it to a single value. See also [`Array.prototype.reduceRight()`](array/reduceright). [`BigUint64Array.prototype.reverse()`](typedarray/reverse) Reverses the order of the elements of an array — the first becomes the last, and the last becomes the first. See also [`Array.prototype.reverse()`](array/reverse). [`BigUint64Array.prototype.set()`](typedarray/set) Stores multiple values in the typed array, reading input values from a specified array. [`BigUint64Array.prototype.slice()`](typedarray/slice) Extracts a section of an array and returns a new array. See also [`Array.prototype.slice()`](array/slice). [`BigUint64Array.prototype.some()`](typedarray/some) Returns `true` if at least one element in this array satisfies the provided testing function. See also [`Array.prototype.some()`](array/some). [`BigUint64Array.prototype.sort()`](typedarray/sort) Sorts the elements of an array in place and returns the array. See also [`Array.prototype.sort()`](array/sort). [`BigUint64Array.prototype.subarray()`](typedarray/subarray) Returns a new `BigUint64Array` from the given start and end element index. [`BigUint64Array.prototype.values()`](typedarray/values) Returns a new `Array Iterator` object that contains the values for each index in the array. See also [`Array.prototype.values()`](array/values). [`BigUint64Array.prototype.toLocaleString()`](typedarray/tolocalestring) Returns a localized string representing the array and its elements. See also [`Array.prototype.toLocaleString()`](array/tolocalestring). [`BigUint64Array.prototype.toString()`](typedarray/tostring) Returns a string representing the array and its elements. See also [`Array.prototype.toString()`](array/tostring). [`BigUint64Array.prototype[@@iterator]()`](typedarray/@@iterator) Returns a new `Array Iterator` object that contains the values for each index in the array. ## Examples ### Different ways to create a `BigUint64Array` // From a length var biguint64 = new BigUint64Array(2); biguint64[0] = 42n; console.log(biguint64[0]); // 42n console.log(biguint64.length); // 2 console.log(biguint64.BYTES_PER_ELEMENT); // 8 // From an array var arr = new BigUint64Array([21n,31n]); console.log(arr[1]); // 31n // From another TypedArray var x = new BigUint64Array([21n, 31n]); var y = new BigUint64Array(x); console.log(y[0]); // 21n // From an ArrayBuffer var buffer = new ArrayBuffer(32); var z = new BigUint64Array(buffer, 0, 4); // From an iterable var iterable = function*(){ yield* [1n, 2n, 3n]; }(); var biguint64 = new BigUint64Array(iterable); // BigUint64Array[1n, 2n, 3n] ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-typedarray-objects
      `BigUint64Array` 67 79 68 No 54 No 67 67 68 48 No 9.0 `BigUint64Array` 67 79 68 No 54 No 67 67 68 48 No 9.0 ## See also - [JavaScript typed arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) - [`BigInt64Array`](bigint64array) - [`DataView`](dataview) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigUint64Array # Function.prototype.bind() The `bind()` method creates a new function that, when called, has its `this` keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called. ## Syntax bind(thisArg) bind(thisArg, arg1) bind(thisArg, arg1, arg2) bind(thisArg, arg1, ... , argN) ### Parameters `thisArg` The value to be passed as the `this` parameter to the target function `func` when the bound function is called. The value is ignored if the bound function is constructed using the [`new`](../../operators/new) operator. When using `bind` to create a function (supplied as a callback) inside a `setTimeout`, any primitive value passed as `thisArg` is converted to object. If no arguments are provided to `bind `, or if the `thisArg` is `null` or `undefined`, the `this` of the executing scope is treated as the `thisArg` for the new function. `arg1, arg2, ...argN` Optional Arguments to prepend to arguments provided to the bound function when invoking `func`. ### Return value A copy of the given function with the specified `this` value, and initial arguments (if provided). ## Description The `bind()` function creates a new **bound function**, which is an _exotic function object_ (a term from ECMAScript 2015) that wraps the original function object. Calling the bound function generally results in the execution of its wrapped function. A bound function has the following internal properties: `[[BoundTargetFunction]]` The wrapped function object `[[BoundThis]]` The value that is always passed as `this` value when calling the wrapped function. `[[BoundArguments]]` A list of values whose elements are used as the first arguments to any call to the wrapped function. `[[Call]]` Executes code associated with this object. Invoked via a function call expression. The arguments to the internal method are a `this` value and a list containing the arguments passed to the function by a call expression. When a bound function is called, it calls internal method `[[Call]]` on `[[BoundTargetFunction]]`, with following arguments `Call(boundThis, ...args)`. Where `boundThis` is `[[BoundThis]]`, `args` is `[[BoundArguments]]`, followed by the arguments passed by the function call. A bound function may also be constructed using the [`new`](../../operators/new) operator. Doing so acts as though the target function had instead been constructed. The provided `this` value is ignored, while prepended arguments are provided to the emulated function. ## Examples ### Creating a bound function The simplest use of `bind()` is to make a function that, no matter how it is called, is called with a particular `this` value. A common mistake for new JavaScript programmers is to extract a method from an object, then to later call that function and expect it to use the original object as its `this` (e.g., by using the method in callback-based code). Without special care, however, the original object is usually lost. Creating a bound function from the function, using the original object, neatly solves this problem: this.x = 9; // 'this' refers to global 'window' object here in a browser const module = { x: 81, getX: function() { return this.x; } }; module.getX(); // returns 81 const retrieveX = module.getX; retrieveX(); // returns 9; the function gets invoked at the global scope // Create a new function with 'this' bound to module // New programmers might confuse the // global variable 'x' with module's property 'x' const boundGetX = retrieveX.bind(module); boundGetX(); // returns 81 ### Partially applied functions The next simplest use of `bind()` is to make a function with pre-specified initial arguments. These arguments (if any) follow the provided `this` value and are then inserted at the start of the arguments passed to the target function, followed by whatever arguments are passed bound function at the time it is called. function list() { return Array.prototype.slice.call(arguments); } function addArguments(arg1, arg2) { return arg1 + arg2 } const list1 = list(1, 2, 3); // [1, 2, 3] const result1 = addArguments(1, 2); // 3 // Create a function with a preset leading argument const leadingThirtysevenList = list.bind(null, 37); // Create a function with a preset first argument. const addThirtySeven = addArguments.bind(null, 37); const list2 = leadingThirtysevenList(); // [37] const list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3] const result2 = addThirtySeven(5); // 37 + 5 = 42 const result3 = addThirtySeven(5, 10); // 37 + 5 = 42 // (the second argument is ignored) ### With `setTimeout()` By default within [`window.setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), the `this` keyword will be set to the [`window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) (or `global`) object. When working with class methods that require `this` to refer to class instances, you may explicitly bind `this` to the callback function, in order to maintain the instance. function LateBloomer() { this.petalCount = Math.floor(Math.random() * 12) + 1; } // Declare bloom after a delay of 1 second LateBloomer.prototype.bloom = function() { window.setTimeout(this.declare.bind(this), 1000); }; LateBloomer.prototype.declare = function() { console.log(`I am a beautiful flower with ${this.petalCount} petals!`); }; const flower = new LateBloomer(); flower.bloom(); // after 1 second, calls 'flower.declare()' ### Bound functions used as constructors **Warning:** This section demonstrates JavaScript capabilities and documents some edge cases of the `bind()` method. The methods shown below are not the best way to do things, and probably should not be used in any production environment. Bound functions are automatically suitable for use with the [`new`](../../operators/new) operator to construct new instances created by the target function. When a bound function is used to construct a value, the provided `this` is ignored. However, provided arguments are still prepended to the constructor call: function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function() { return `${this.x},${this.y}`; }; const p = new Point(1, 2); p.toString(); // '1,2' // not supported in the polyfill below, // works fine with native bind: const YAxisPoint = Point.bind(null, 0/*x*/); const emptyObj = {}; const YAxisPoint = Point.bind(emptyObj, 0/*x*/); const axisPoint = new YAxisPoint(5); axisPoint.toString(); // '0,5' axisPoint instanceof Point; // true axisPoint instanceof YAxisPoint; // true new YAxisPoint(17, 42) instanceof Point; // true Note that you need not do anything special to create a bound function for use with [`new`](../../operators/new). The corollary is that you need not do anything special to create a bound function to be called plainly, even if you would rather require the bound function to only be called using [`new`](../../operators/new). // Example can be run directly in your JavaScript console // ...continued from above // Can still be called as a normal function // (although usually this is undesired) YAxisPoint(13); `${emptyObj.x},${emptyObj.y}`; // > '0,13' If you wish to support the use of a bound function only using [`new`](../../operators/new), or only by calling it, the target function must enforce that restriction. ### Creating shortcuts `bind()` is also helpful in cases where you want to create a shortcut to a function which requires a specific `this` value. Take [`Array.prototype.slice()`](../array/slice), for example, which you want to use for converting an array-like object to a real array. You could create a shortcut like this: const slice = Array.prototype.slice; // ... slice.apply(arguments); With `bind()`, this can be simplified. In the following piece of code, `slice()` is a bound function to the [`apply()`](apply) function of [`Function`](../function), with the `this` value set to the [`slice()`](../array/slice) function of `Array.prototype`. This means that additional `apply()` calls can be eliminated: // same as "slice" in the previous example const unboundSlice = Array.prototype.slice; const slice = Function.prototype.apply.bind(unboundSlice); // ... slice(arguments); ## Polyfill Because older browsers are generally also slower browsers, it is far more critical than most people recognize to create performance polyfills to make the browsing experience in outdated browsers slightly less horrible. Thus, presented below are two options for `Function.prototype.bind()` polyfills: 1. The first one is much smaller and more performant, but does not work when using the `new` operator. 2. The second one is bigger and less performant, but it permits some usage of the `new` operator on bound functions. Generally, in most code it's very rare to see `new` used on a bound function, so it is generally best to go with the first option. // Does not work with `new (funcA.bind(thisArg, args))` if (!Function.prototype.bind) (function(){ var slice = Array.prototype.slice; Function.prototype.bind = function() { var thatFunc = this, thatArg = arguments[0]; var args = slice.call(arguments, 1); if (typeof thatFunc !== 'function') { // closest thing possible to the ECMAScript 5 // internal IsCallable function throw new TypeError('Function.prototype.bind - ' + 'what is trying to be bound is not callable'); } return function(){ var funcArgs = args.concat(slice.call(arguments)) return thatFunc.apply(thatArg, funcArgs); }; }; })(); You can partially work around this by inserting the following code at the beginning of your scripts, allowing use of much of the functionality of `bind()` in implementations that do not natively support it. // Yes, it does work with `new (funcA.bind(thisArg, args))` if (!Function.prototype.bind) (function(){ var ArrayPrototypeSlice = Array.prototype.slice; Function.prototype.bind = function(otherThis) { if (typeof this !== 'function') { // closest thing possible to the ECMAScript 5 // internal IsCallable function throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); } var baseArgs= ArrayPrototypeSlice.call(arguments, 1), baseArgsLength = baseArgs.length, fToBind = this, fNOP = function() {}, fBound = function() { baseArgs.length = baseArgsLength; // reset to default base arguments baseArgs.push.apply(baseArgs, arguments); return fToBind.apply( fNOP.prototype.isPrototypeOf(this) ? this : otherThis, baseArgs ); }; if (this.prototype) { // Function.prototype doesn't have a prototype property fNOP.prototype = this.prototype; } fBound.prototype = new fNOP(); return fBound; }; })(); Some of the many differences (there may well be others, as this list does not seriously attempt to be exhaustive) between this algorithm and the specified algorithm are: - The partial implementation relies on [`Array.prototype.slice()`](../array/slice), [`Array.prototype.concat()`](../array/concat), [`Function.prototype.call()`](call) and [`Function.prototype.apply()`](apply), built-in methods to have their original values. - The partial implementation creates functions that do not have immutable "poison pill" [`caller`](caller) and `arguments` properties that throw a [`TypeError`](../typeerror) upon get, set, or deletion. (This could be added if the implementation supports [`Object.defineProperty`](../object/defineproperty), or partially implemented \[without throw-on-delete behavior\] if the implementation supports the [`__defineGetter__`](../object/__definegetter__) and [`__defineSetter__`](../object/__definesetter__) extensions.) - The partial implementation creates functions that have a `prototype` property. (Proper bound functions have none.) - The partial implementation creates bound functions whose [`length`](length) property does not agree with that mandated by ECMA-262: it creates functions with `length` of `0`. A full implementation—depending on the length of the target function and the number of pre-specified arguments—may return a non-zero length. - The partial implementation creates bound functions whose [`name`](name) property is not derived from the original function name. According to ECMA-262, name of the returned bound function should be "bound " + name of target function (note the space character). If you choose to use this partial implementation, **you must not rely on those cases where behavior deviates from ECMA-262, 5th edition!** Thankfully, these deviations from the specification rarely (if ever) come up in most coding situations. If you do not understand any of the deviations from the specification above, then it is safe in this particular case to not worry about these noncompliant deviation details. **If it's absolutely necessary and performance is not a concern**, a far slower (but more specification-compliant solution) can be found at . ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-function.prototype.bind
      `bind` 7 12 4 9 11.6 5.1 4 18 4 12 6 1.0 ## See also - [`Function.prototype.apply()`](apply) - [`Function.prototype.call()`](call) - [Functions](../../functions) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind # Bitwise AND (&) The bitwise AND operator (`&`) returns a `1` in each bit position for which the corresponding bits of both operands are `1`s. ## Syntax a & b ## Description The operands are converted to 32-bit integers and expressed by a series of bits (zeroes and ones). Numbers with more than 32 bits get their most significant bits discarded. For example, the following integer with more than 32 bits will be converted to a 32 bit integer: Before: 11100110111110100000000000000110000000000001 After: 10100000000000000110000000000001 Each bit in the first operand is paired with the corresponding bit in the second operand: _first bit_ to _first bit_, _second bit_ to _second bit_, and so on. The operator is applied to each pair of bits, and the result is constructed bitwise. The truth table for the AND operation is:
      aba AND b
      000
      010
      100
      111
      . 9 (base 10) = 00000000000000000000000000001001 (base 2) 14 (base 10) = 00000000000000000000000000001110 (base 2) -------------------------------- 14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10) Bitwise ANDing any number `x` with `0` yields `0`. ## Examples ### Using bitwise AND // 5: 00000000000000000000000000000101 // 2: 00000000000000000000000000000010 5 & 2; // 0 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #prod-BitwiseANDExpression
      `Bitwise_AND` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Bitwise operators in the JS guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise) - [Bitwise AND assignment operator](bitwise_and_assignment) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND # Bitwise AND assignment (&=) The bitwise AND assignment operator (`&=`) uses the binary representation of both operands, does a bitwise AND operation on them and assigns the result to the variable. ## Syntax Operator: x &= y Meaning: x = x & y ## Examples ### Using bitwise AND assignment let a = 5; // 5: 00000000000000000000000000000101 // 2: 00000000000000000000000000000010 a &= 2; // 0 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-assignment-operators
      `Bitwise_AND_assignment` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Assignment operators in the JS guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#assignment) - [Bitwise AND operator](bitwise_and) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_AND_assignment # Bitwise NOT (~) The bitwise NOT operator (`~`) inverts the bits of its operand. ## Syntax ~a ## Description The operands are converted to 32-bit integers and expressed by a series of bits (zeroes and ones). Numbers with more than 32 bits get their most significant bits discarded. For example, the following integer with more than 32 bits will be converted to a 32 bit integer: Before: 11100110111110100000000000000110000000000001 After: 10100000000000000110000000000001 Each bit in the first operand is paired with the corresponding bit in the second operand: _first bit_ to _first bit_, _second bit_ to _second bit_, and so on. The operator is applied to each pair of bits, and the result is constructed bitwise. The truth table for the `NOT` operation is:
      aNOT a
      01
      10
      9 (base 10) = 00000000000000000000000000001001 (base 2) -------------------------------- ~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10) Bitwise NOTing any number `x` yields `-(x + 1)`. For example, `~-5` yields `4`. Note that due to using 32-bit representation for numbers both `~-1` and `~4294967295` (232-1) results in `0`. ## Examples ### Using bitwise NOT ~0; // -1 ~-1; // 0 ~1; // -2 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-bitwise-not-operator
      `Bitwise_NOT` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Bitwise operators in the JS guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT # Bitwise OR (|) The bitwise OR operator (`|`) returns a `1` in each bit position for which the corresponding bits of either or both operands are `1`s. ## Syntax a | b ## Description The operands are converted to 32-bit integers and expressed by a series of bits (zeroes and ones). Numbers with more than 32 bits get their most significant bits discarded. For example, the following integer with more than 32 bits will be converted to a 32 bit integer: Before: 11100110111110100000000000000110000000000001 After: 10100000000000000110000000000001 Each bit in the first operand is paired with the corresponding bit in the second operand: _first bit_ to _first bit_, _second bit_ to _second bit_, and so on. The operator is applied to each pair of bits, and the result is constructed bitwise. The truth table for the OR operation is:
      aba OR b
      000
      011
      101
      111
      . 9 (base 10) = 00000000000000000000000000001001 (base 2) 14 (base 10) = 00000000000000000000000000001110 (base 2) -------------------------------- 14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10) Bitwise ORing any number `x` with `0` yields `x`. ## Examples ### Using bitwise OR // 9 (00000000000000000000000000001001) // 14 (00000000000000000000000000001110) 14 | 9; // 15 (00000000000000000000000000001111) ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Bitwise OR expression' in that specification.
      `Bitwise_OR` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Bitwise operators in the JS guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise) - [Bitwise OR assignment operator](bitwise_or_assignment) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR # Bitwise OR assignment (|=) The bitwise OR assignment operator (`|=`) uses the binary representation of both operands, does a bitwise OR operation on them and assigns the result to the variable. ## Syntax Operator: x |= y Meaning: x = x | y ## Examples ### Using bitwise OR assignment let a = 5; a |= 2; // 7 // 5: 00000000000000000000000000000101 // 2: 00000000000000000000000000000010 // ----------------------------------- // 7: 00000000000000000000000000000111 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-assignment-operators
      `Bitwise_OR_assignment` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Assignment operators in the JS guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#assignment) - [Bitwise OR operator](bitwise_or) - [Logical OR assignment (`||=`)](logical_or_assignment) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR_assignment # Bitwise XOR (^) The bitwise XOR operator (`^`) returns a `1` in each bit position for which the corresponding bits of either but not both operands are `1`s. ## Syntax a ^ b ## Description The operands are converted to 32-bit integers and expressed by a series of bits (zeroes and ones). Numbers with more than 32 bits get their most significant bits discarded. For example, the following integer with more than 32 bits will be converted to a 32 bit integer: Before: 11100110111110100000000000000110000000000001 After: 10100000000000000110000000000001 Each bit in the first operand is paired with the corresponding bit in the second operand: _first bit_ to _first bit_, _second bit_ to _second bit_, and so on. The operator is applied to each pair of bits, and the result is constructed bitwise. The truth table for the XOR operation is:
      aba XOR b
      000
      011
      101
      110
      . 9 (base 10) = 00000000000000000000000000001001 (base 2) 14 (base 10) = 00000000000000000000000000001110 (base 2) -------------------------------- 14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10) Bitwise XORing any number `x` with `0` yields `x`. ## Examples ### Using bitwise XOR // 9 (00000000000000000000000000001001) // 14 (00000000000000000000000000001110) 14 ^ 9; // 7 (00000000000000000000000000000111) ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Bitwise XOR expression' in that specification.
      `Bitwise_XOR` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Bitwise operators in the JS guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise) - [Bitwise XOR assignment operator](bitwise_xor_assignment) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR # Bitwise XOR assignment (^=) The bitwise XOR assignment operator (`^=`) uses the binary representation of both operands, does a bitwise XOR operation on them and assigns the result to the variable. ## Syntax Operator: x ^= y Meaning: x = x ^ y ## Examples ### Using bitwise XOR assignment let a = 5; // 00000000000000000000000000000101 a ^= 3; // 00000000000000000000000000000011 console.log(a); // 00000000000000000000000000000110 // 6 let b = 5; // 00000000000000000000000000000101 b ^= 0; // 00000000000000000000000000000000 console.log(b); // 00000000000000000000000000000101 // 5 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-assignment-operators
      `Bitwise_XOR_assignment` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Assignment operators in the JS guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#assignment) - [Bitwise XOR operator](bitwise_xor) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR_assignment # String.prototype.blink() **Deprecated** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the [compatibility table](#browser_compatibility) at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time. The `blink()` method creates a [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blink) HTML element that causes a string to blink. **Warning:** Blinking text is frowned upon by several accessibility standards. The `` element itself is non-standard and deprecated! ## Syntax blink() ### Return value A string containing a [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blink) HTML element. ## Description The `blink()` method embeds a string in a `` element: "`str`". ## Examples ### Using blink() The following example uses string methods to change the formatting of a string: var worldString = 'Hello, world'; console.log(worldString.blink()); // Hello, world console.log(worldString.bold()); // Hello, world console.log(worldString.italics()); // Hello, world console.log(worldString.strike()); // Hello, world ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-string.prototype.blink
      `blink` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`String.prototype.bold()`](bold) - [`String.prototype.italics()`](italics) - [`String.prototype.strike()`](strike) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/blink # block A **block statement** (or **compound statement** in other languages) is used to group zero or more statements. The block is delimited by a pair of braces ("curly brackets") and may optionally be [labelled](label): ## Syntax ### Block Statement { StatementList } ### Labelled Block Statement LabelIdentifier: { StatementList } `StatementList` Statements grouped within the block statement. `LabelIdentifier` An optional [label](label) for visual identification or as a target for [`break`](break). ## Description The block statement is often called **compound statement** in other languages. It allows you to use multiple statements where JavaScript expects only one statement. Combining statements into blocks is a common practice in JavaScript. The opposite behavior is possible using an [empty statement](empty), where you provide no statement, although one is required. Blocks are commonly used in association with [`if...else`](if...else) and [`for`](for) statements. ## Examples ### Block scoping rules with var or function declaration in non-strict mode Variables declared with `var` or created by [function declarations](function) in non-strict mode **do not** have block scope. Variables introduced within a block are scoped to the containing function or script, and the effects of setting them persist beyond the block itself. In other words, block statements do not introduce a scope. For example: var x = 1; { var x = 2; } console.log(x); // logs 2 This logs 2 because the `var x` statement within the block is in the same scope as the `var x` statement before the block. In non-strict code, function declarations inside blocks behave strangely. Do not use them. ### Block scoping rules with let, const or function declaration in strict mode By contrast, identifiers declared with [`let`](let) and [`const`](const) **do have** block scope: let x = 1; { let x = 2; } console.log(x); // logs 1 The `x = 2` is limited in scope to the block in which it was defined. The same is true of `const`: const c = 1; { const c = 2; } console.log(c); // logs 1 and does not throw SyntaxError... Note that the block-scoped `const c = 2` _does not_ throw a `SyntaxError: Identifier 'c' has already been declared` because it can be declared uniquely within the block. In [strict mode](../strict_mode), starting with ES2015, functions inside blocks are scoped to that block. Prior to ES2015, block-level functions were forbidden in strict mode. ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-block
      `block` 1 12 1 11 3 1 1 18 4 10.1 1 1.0 ## See also - [`while`](while) - [`if...else`](if...else) - [`let`](let) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block # String.prototype.bold() **Deprecated** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the [compatibility table](#browser_compatibility) at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time. The `bold()` method creates a [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b) HTML element that causes a string to be displayed as bold. ## Syntax bold() ### Return value A string containing a [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b) HTML element. ## Description The `bold()` method embeds a string in a `` element: "`str`". ## Examples ### Using bold() The following example uses string methods to change the formatting of a string: var worldString = 'Hello, world'; console.log(worldString.blink()); // Hello, world console.log(worldString.bold()); // Hello, world console.log(worldString.italics()); // Hello, world console.log(worldString.strike()); // Hello, world ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-string.prototype.bold
      `bold` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`String.prototype.blink()`](blink) - [`String.prototype.italics()`](italics) - [`String.prototype.strike()`](strike) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/bold # Boolean The `Boolean` object is an object wrapper for a boolean value. ## Description The value passed as the first parameter is converted to a boolean value, if necessary. If the value is omitted or is `0`, `-0`, [`null`](null), `false`, [`NaN`](nan), [`undefined`](undefined), or the empty string (`""`), the object has an initial value of `false`. All other values, including any object, an empty array (`[]`), or the string "`false`", create an object with an initial value of `true`. Do not confuse the [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) `Boolean` values `true` and `false` with the `true` and `false` values of the `Boolean` object. **Any** object of which the value is not [`undefined`](undefined) or [`null`](null), including a `Boolean` object whose value is `false`, evaluates to `true` when passed to a conditional statement. For example, the condition in the following [`if`](../statements/if...else) statement evaluates to `true`: var x = new Boolean(false); if (x) { // this code is executed } This behavior does not apply to `Boolean` primitives. For example, the condition in the following [`if`](../statements/if...else) statement evaluates to `false`: var x = false; if (x) { // this code is not executed } Do not use a `Boolean` object to convert a non-boolean value to a boolean value. To perform this task, instead, use `Boolean` as a function, or a [double NOT operator](../operators/logical_not): var x = Boolean(expression); // use this... var x = !!(expression); // ...or this var x = new Boolean(expression); // don't use this! If you specify any object, including a `Boolean` object whose value is `false`, as the initial value of a `Boolean` object, the new `Boolean` object has a value of `true`. var myFalse = new Boolean(false); // initial value of false var g = Boolean(myFalse); // initial value of true var myString = new String('Hello'); // string object var s = Boolean(myString); // initial value of true Do not use a `Boolean` object in place of a `Boolean` primitive. **Note:** When the non-standard property `document.all` is used as an argument for this constructor, the result is a `Boolean` object with the value `false`. This property is legacy and non-standard and should not be used. ## Constructor [`Boolean()`](boolean/boolean) Creates a new `Boolean` object. ## Instance methods [`Boolean.prototype.toString()`](boolean/tostring) Returns a string of either `true` or `false` depending upon the value of the object. Overrides the [`Object.prototype.toString()`](object/tostring) method. [`Boolean.prototype.valueOf()`](boolean/valueof) Returns the primitive value of the [`Boolean`](boolean) object. Overrides the [`Object.prototype.valueOf()`](object/valueof) method. ## Examples ### Creating `Boolean` objects with an initial value of `false` var bNoParam = new Boolean(); var bZero = new Boolean(0); var bNull = new Boolean(null); var bEmptyString = new Boolean(''); var bfalse = new Boolean(false); ### Creating `Boolean` objects with an initial value of `true` var btrue = new Boolean(true); var btrueString = new Boolean('true'); var bfalseString = new Boolean('false'); var bSuLin = new Boolean('Su Lin'); var bArrayProto = new Boolean([]); var bObjProto = new Boolean({}); ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-boolean-objects
      `Boolean` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `Boolean` 1 12 1 3 4 1 1 18 4 10.1 1 1.0 `toSource` No No 1-74 Starting in Firefox 74, `toSource()` is no longer available for use by web content. It is still allowed for internal and privileged code. No No No No No 4 No No No `toString` 1 12 1 3 4 1 1 18 4 10.1 1 1.0 `valueOf` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 ## See also - [Boolean](https://developer.mozilla.org/en-US/docs/Glossary/Boolean) - [Boolean primitives](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#boolean_type) - [Boolean data type (Wikipedia)](https://en.wikipedia.org/wiki/Boolean_data_type) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean # break The `break` terminates the current loop, [`switch`](switch), or [label](label) statement and transfers program control to the statement following the terminated statement. ## Syntax break [label]; `label` Optional Identifier associated with the label of the statement. If the statement is not a loop or [`switch`](switch), this is required. ## Description The `break` statement includes an optional label that allows the program to break out of a labeled statement. The `break` statement needs to be nested within the referenced label. The labeled statement can be any [block](block) statement; it does not have to be preceded by a loop statement. A `break` statement, with or without a following label, cannot be used within the body of a function that is itself nested within the current loop, switch, or label statement that the `break` statement is intended to break out of. ## Examples ### break in while loop The following function has a `break` statement that terminates the [`while`](while) loop when `i` is 3, and then returns the value 3 \* `x`. function testBreak(x) { var i = 0; while (i < 6) { if (i == 3) { break; } i += 1; } return i * x; } ### break in switch statements The following code has a `break` statement that terminates the [`switch`](switch) statement when a case is matched and the corresponding code has ran const food = "sushi"; switch (food) { case "sushi": console.log("Sushi is originally from Japan."); break; case "pizza": console.log("Pizza is originally from Italy."); break; default: console.log("I have never heard of that dish."); break; } ### break in labeled blocks The following code uses `break` statements with labeled blocks. A `break` statement must be nested within any label it references. Notice that `inner_block` is nested within `outer_block`. outer_block: { inner_block: { console.log('1'); break outer_block; // breaks out of both inner_block and outer_block console.log(':-('); // skipped } console.log('2'); // skipped } ### break in labeled blocks that throw The following code also uses `break` statements with labeled blocks, but generates a `SyntaxError` because its `break` statement is within `block_1` but references `block_2`. A `break` statement must always be nested within any label it references. block_1: { console.log('1'); break block_2; // SyntaxError: label not found } block_2: { console.log('2'); } ### break within functions `SyntaxError`s are also generated in the following code examples which use `break` statements within functions that are nested within a loop, or labeled block that the `break` statements are intended to break out of. function testBreak(x) { var i = 0; while (i < 6) { if (i == 3) { (function() { break; })(); } i += 1; } return i * x; } testBreak(1); // SyntaxError: Illegal break statement block_1: { console.log('1'); ( function() { break block_1; // SyntaxError: Undefined label 'block_1' })(); } ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Break statement' in that specification.
      `break` 1 12 1 3 4 1 1 18 4 10.1 1 1.0 ## See also - [`continue`](continue) - [label](label) - [`switch`](switch) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break # WebAssembly.Memory.prototype.buffer The `buffer` prototype property of the [`WebAssembly.Memory`](../memory) object returns the buffer contained in the memory. ## Examples ### Using buffer The following example (see [memory.html](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/memory.html) on GitHub, and [view it live also](https://mdn.github.io/webassembly-examples/js-api-examples/memory.html)) fetches and instantiates the loaded memory.wasm byte code using the [`WebAssembly.instantiateStreaming()`](../instantiatestreaming) method, while importing the memory created in the line above. It then stores some values in that memory, then exports a function and uses it to sum some values. WebAssembly.instantiateStreaming(fetch('memory.wasm'), { js: { mem: memory } }) .then(obj => { var i32 = new Uint32Array(memory.buffer); for (var i = 0; i < 10; i++) { i32[i] = i; } var sum = obj.instance.exports.accumulate(0, 10); console.log(sum); }); ## Specifications
      Specification
      WebAssembly JavaScript Interface (WebAssembly JavaScript Interface)
      #dom-memory-buffer
      `buffer` 57 16 52 Disabled in the Firefox 52 Extended Support Release (ESR). No 44 11 57 57 52 Disabled in the Firefox 52 Extended Support Release (ESR). 43 11 7.0 ## See also - [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) overview page - [WebAssembly concepts](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts) - [Using the WebAssembly JavaScript API](https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory/buffer # SharedArrayBuffer.prototype.byteLength The `byteLength` accessor property represents the length of an [`SharedArrayBuffer`](../sharedarraybuffer) in bytes. ## Description The `byteLength` property is an accessor property whose set accessor function is `undefined`, meaning that you can only read this property. The value is established when the shared array is constructed and cannot be changed. ## Examples ### Using byteLength var sab = new SharedArrayBuffer(1024); sab.byteLength; // 1024 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-get-sharedarraybuffer.prototype.bytelength
      `byteLength` 68 60-63 Chrome disabled SharedArrayBuffer on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 79 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11 60-63 Chrome disabled SharedArrayBuffer on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 89 `SharedArrayBuffer` is gated behind COOP/COEP. For more detail, read [Making your website "cross-origin isolated" using COOP and COEP](https://web.dev/coop-coep/). 60-63 Chrome disabled SharedArrayBuffer on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 79 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11 No Chrome disabled SharedArrayBuffer on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. ## See also - [`SharedArrayBuffer`](../sharedarraybuffer) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/byteLength # TypedArray.prototype.byteOffset The `byteOffset` accessor property represents the offset (in bytes) of a typed array from the start of its [`ArrayBuffer`](../arraybuffer). ## Description The `byteOffset` property is an accessor property whose set accessor function is `undefined`, meaning that you can only read this property. The value is established when a _TypedArray_ is constructed and cannot be changed. _TypedArray_ is one of the [TypedArray objects](../typedarray#typedarray_objects). ## Examples ### Using the byteOffset property var buffer = new ArrayBuffer(8); var uint8 = new Uint8Array(buffer); uint8.byteOffset; // 0 (no offset specified) var uint8 = new Uint8Array(buffer, 3); uint8.byteOffset; // 3 (as specified when constructing Uint8Array) ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-get-%typedarray%.prototype.byteoffset
      `byteOffset` 7 14 4 10 11.6 5.1 4 18 4 12 4.2 1.0 ## See also - [JavaScript typed arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) - [`TypedArray`](../typedarray) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/byteOffset # TypedArray.BYTES_PER_ELEMENT The `TypedArray.BYTES_PER_ELEMENT` property represents the size in bytes of each element in an typed array. Property attributes of `TypedArray.BYTES_PER_ELEMENT` Writable no Enumerable no Configurable no ## Description `TypedArray` objects differ from each other in the number of bytes per element and in the way the bytes are interpreted. The `BYTES_PER_ELEMENT` constant contains the number of bytes each element in the given `TypedArray` has. ## Examples ### Using BYTES_PER_ELEMENT Int8Array.BYTES_PER_ELEMENT; // 1 Uint8Array.BYTES_PER_ELEMENT; // 1 Uint8ClampedArray.BYTES_PER_ELEMENT; // 1 Int16Array.BYTES_PER_ELEMENT; // 2 Uint16Array.BYTES_PER_ELEMENT; // 2 Int32Array.BYTES_PER_ELEMENT; // 4 Uint32Array.BYTES_PER_ELEMENT; // 4 Float32Array.BYTES_PER_ELEMENT; // 4 Float64Array.BYTES_PER_ELEMENT; // 8 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-typedarray.bytes_per_element
      `BYTES_PER_ELEMENT` 7 12 4 10 11.6 5.1 4 18 4 12 4.2 1.0 ## See also - [JavaScript typed arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) - [`TypedArray`](../typedarray) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT # Intl.Locale.prototype.calendar The `Intl.Locale.prototype.calendar` property is an accessor property which returns the type of calendar used in the `Locale`. ## Description The `calendar` property returns the part of the `Locale` that indicates the `Locale`'s calendar era. While most of the world uses the Gregorian calendar, there are several regional calendar eras used around the world. The following table shows all the valid Unicode calendar key strings, along with a description of the calendar era they represent. ### Unicode calendar keys
      Unicode calendar keys
      Calendar key (name)Description
      buddhistThai Buddhist calendar
      chineseTraditional Chinese calendar
      copticCoptic calendar
      dangiTraditional Korean calendar
      ethioaaEthiopic calendar, Amete Alem (epoch approx. 5493 B.C.E)
      ethiopicEthiopic calendar, Amete Mihret (epoch approx, 8 C.E.)
      gregoryGregorian calendar
      hebrewTraditional Hebrew calendar
      indianIndian calendar
      islamicIslamic calendar
      islamic-umalquraIslamic calendar, Umm al-Qura
      islamic-tblaIslamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - astronomical epoch)
      islamic-civilIslamic calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - civil epoch)
      islamic-rgsaIslamic calendar, Saudi Arabia sighting
      iso8601ISO calendar (Gregorian calendar using the ISO 8601 calendar week rules)
      japaneseJapanese Imperial calendar
      persianPersian calendar
      rocRepublic of China calendar

      Warning: The islamicc calendar key has been deprecated. Please use islamic-civil.

      islamicc

      Civil (algorithmic) Arabic calendar
      ## Examples ### Adding a calendar in the Locale string Calendar eras fall under the category of locale key "extension keys". These keys add additional data about the locale, and are added to locale identifiers by using the `-u` extension. Thus, the calendar era type can be added to the initial locale identifier string that is passed into the [`Intl.Locale`](locale) constructor. To add the calendar type, first add the `-u` extension to the string. Next, add the `-ca` extension to indicate that you are adding a calendar type. Finally, add the calendar era to the string. let frBuddhist = new Intl.Locale("fr-FR-u-ca-buddhist"); console.log(frBuddhist.calendar); // Prints "buddhist" ### Adding a calendar with a configuration object The [`Intl.Locale`](locale) constructor has an optional configuration object argument, which can contain any of several extension types, including calendars. Set the `calendar` property of the configuration object to your desired calendar era, and then pass it into the constructor. let frBuddhist = new Intl.Locale("fr-FR", {calendar: "buddhist"}); console.log(frBuddhist.calendar); // Prints "buddhist" ## Specifications
      Specification
      ECMAScript Internationalization API Specification (ECMAScript Internationalization API)
      #sec-Intl.Locale.prototype.calendar
      `calendar` 74 79 75 No 62 14 74 74 79 53 14 11.0 ## See also - [`Intl.Locale`](../locale) - [Unicode Calendar Identifiers](https://www.unicode.org/reports/tr35/#UnicodeCalendarIdentifier) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar # Function.prototype.call() The `call()` method calls a function with a given `this` value and arguments provided individually. ## Syntax call() call(thisArg) call(thisArg, arg1) call(thisArg, arg1, arg2) call(thisArg, arg1, ... , argN) ### Parameters `thisArg` Optional The value to use as `this` when calling `func`. **Note:** In certain cases, `thisArg` may not be the actual value seen by the method. If the method is a function in [non-strict mode](../../strict_mode), [`null`](../null) and [`undefined`](../undefined) will be replaced with the global object, and primitive values will be converted to objects. `arg1, arg2, ...argN` Optional Arguments for the function. ### Return value The result of calling the function with the specified `this` value and arguments. ## Description The `call()` allows for a function/method belonging to one object to be assigned and called for a different object. `call()` provides a new value of `this` to the function/method. With `call()`, you can write a method once and then inherit it in another object, without having to rewrite the method for the new object. **Note:** While the syntax of this function is almost identical to that of [`apply()`](apply), the fundamental difference is that `call()` accepts an **argument list**, while `apply()` accepts a **single array of arguments**. ## Examples ### Using `call` to chain constructors for an object You can use `call` to chain constructors for an object (similar to Java). In the following example, the constructor for the `Product` object is defined with two parameters: `name` and `price`. Two other functions, `Food` and `Toy`, invoke `Product`, passing `this`, `name`, and `price`. `Product` initializes the properties `name` and `price`, both specialized functions define the `category`. function Product(name, price) { this.name = name; this.price = price; } function Food(name, price) { Product.call(this, name, price); this.category = 'food'; } function Toy(name, price) { Product.call(this, name, price); this.category = 'toy'; } const cheese = new Food('feta', 5); const fun = new Toy('robot', 40); ### Using `call` to invoke an anonymous function In this example, we create an anonymous function and use `call` to invoke it on every object in an array. The main purpose of the anonymous function here is to add a `print` function to every object, which is able to print the correct index of the object in the array. **Note:** Passing the object as `this` value is not strictly necessary, but is done for explanatory purpose. const animals = [ { species: 'Lion', name: 'King' }, { species: 'Whale', name: 'Fail' } ]; for (let i = 0; i < animals.length; i++) { (function(i) { this.print = function() { console.log('#' + i + ' ' + this.species + ': ' + this.name); } this.print(); }).call(animals[i], i); } ### Using `call` to invoke a function and specifying the context for '`this`' In the example below, when we call `greet`, the value of `this` will be bound to object `obj`. function greet() { const reply = [this.animal, 'typically sleep between', this.sleepDuration].join(' '); console.log(reply); } const obj = { animal: 'cats', sleepDuration: '12 and 16 hours' }; greet.call(obj); // cats typically sleep between 12 and 16 hours ### Using `call` to invoke a function and without specifying the first argument In the example below, we invoke the `display` function without passing the first argument. If the first argument is not passed, the value of `this` is bound to the global object. var sData = 'Wisen'; function display() { console.log('sData value is %s ', this.sData); } display.call(); // sData value is Wisen **Note:** In strict mode, the value of `this` will be `undefined`. See below. 'use strict'; var sData = 'Wisen'; function display() { console.log('sData value is %s ', this.sData); } display.call(); // Cannot read the property of 'sData' of undefined ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Function.prototype.call' in that specification.
      `call` 1 12 1 5.5 4 1 1 18 4 10.1 1 1.0 ## See also - [`Function.prototype.bind()`](bind) - [`Function.prototype.apply()`](apply) - [Introduction to Object-Oriented JavaScript](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call # TypeError: X.prototype.y called on incompatible type The JavaScript exception "called on incompatible target (or object)" occurs when a function (on a given object), is called with a `this` not corresponding to the type expected by the function. ## Message TypeError: 'this' is not a Set object (EdgE) TypeError: Function.prototype.toString called on incompatible object (Firefox) TypeError: Function.prototype.bind called on incompatible target (Firefox) TypeError: Method Set.prototype.add called on incompatible receiver undefined (Chrome) TypeError: Bind must be called on a function (Chrome) ## Error type [`TypeError`](../global_objects/typeerror) ## What went wrong? When this error is thrown, a function (on a given object), is called with a `this` not corresponding to the type expected by the function. This issue can arise when using the [`Function.prototype.call()`](../global_objects/function/call) or [`Function.prototype.apply()`](../global_objects/function/apply) methods, and providing a `this` argument which does not have the expected type. This issue can also happen when providing a function that is stored as a property of an object as an argument to another function. In this case, the object that stores the function won't be the `this` target of that function when it is called by the other function. To work-around this issue, you will either need to provide a lambda which is making the call, or use the [`Function.prototype.bind()`](../global_objects/function/bind) function to force the `this` argument to the expected object. ## Examples ### Invalid cases var mySet = new Set; ['bar', 'baz'].forEach(mySet.add); // mySet.add is a function, but "mySet" is not captured as this. var myFun = function () { console.log(this); }; ['bar', 'baz'].forEach(myFun.bind); // myFun.bind is a function, but "myFun" is not captured as this. ### Valid cases var mySet = new Set; ['bar', 'baz'].forEach(mySet.add.bind(mySet)); // This works due to binding "mySet" as this. var myFun = function () { console.log(this); }; ['bar', 'baz'].forEach(x => myFun.bind(x)); // This works using the "bind" function. It creates a lambda forwarding the argument. ## See also - [`Function.prototype.call()`](../global_objects/function/call) - [`Function.prototype.apply()`](../global_objects/function/apply) - [`Function.prototype.bind()`](../global_objects/function/bind) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Called_on_incompatible_type # arguments.callee The `arguments.callee` property contains the currently executing function. ## Description `callee` is a property of the `arguments` object. It can be used to refer to the currently executing function inside the function body of that function. This is useful when the name of the function is unknown, such as within a function expression with no name (also called "anonymous functions"). **Warning:** The 5th edition of ECMAScript (ES5) forbids use of `arguments.callee()` in [strict mode](../../strict_mode). Avoid using `arguments.callee()` by either giving function expressions a name or use a function declaration where a function must call itself. ### Why was `arguments.callee` removed from ES5 strict mode? (adapted from [a Stack Overflow answer by olliej](https://stackoverflow.com/a/235760/578288)) Early versions of JavaScript did not allow named function expressions, and for this reason you could not make a recursive function expression. For example, this syntax worked: function factorial (n) { return !(n > 1) ? 1 : factorial(n - 1) * n; } [1, 2, 3, 4, 5].map(factorial); but: [1, 2, 3, 4, 5].map(function(n) { return !(n > 1) ? 1 : /* what goes here? */ (n - 1) * n; }); did not. To get around this `arguments.callee` was added so you could do [1, 2, 3, 4, 5].map(function(n) { return !(n > 1) ? 1 : arguments.callee(n - 1) * n; }); However, this was actually a really bad solution as this (in conjunction with other `arguments`, `callee`, and `caller` issues) make inlining and tail recursion impossible in the general case (you can achieve it in select cases through tracing, etc., but even the best code is suboptimal due to checks that would not otherwise be necessary.) The other major issue is that the recursive call will get a different `this` value, e.g.: var global = this; var sillyFunction = function(recursed) { if (!recursed) { return arguments.callee(true); } if (this !== global) { alert('This is: ' + this); } else { alert('This is the global'); } } sillyFunction(); ECMAScript 3 resolved these issues by allowing named function expressions. For example: [1, 2, 3, 4, 5].map(function factorial(n) { return !(n > 1) ? 1 : factorial(n - 1)*n; }); This has numerous benefits: - the function can be called like any other from inside your code - it does not create a variable in the outer scope ([except for IE 8 and below](https://kangax.github.io/nfe/#example_1_function_expression_identifier_leaks_into_an_enclosing_scope)) - it has better performance than accessing the arguments object Another feature that was deprecated was `arguments.callee.caller`, or more specifically `Function.caller`. Why is this? Well, at any point in time you can find the deepest caller of any function on the stack, and as I said above looking at the call stack has one single major effect: it makes a large number of optimizations impossible, or much more difficult. For example, if you cannot guarantee that a function `f` will not call an unknown function, it is not possible to inline `f`. Basically it means that any call site that may have been trivially inlinable accumulates a large number of guards: function f(a, b, c, d, e) { return a ? b * c : d * e; } If the JavaScript interpreter cannot guarantee that all the provided arguments are numbers at the point that the call is made, it needs to either insert checks for all the arguments before the inlined code, or it cannot inline the function. Now in this particular case a smart interpreter should be able to rearrange the checks to be more optimal and not check any values that would not be used. However in many cases that's just not possible and therefore it becomes impossible to inline. ## Examples ### Using `arguments.callee` in an anonymous recursive function A recursive function must be able to refer to itself. Typically, a function refers to itself by its name. However, an anonymous function (which can be created by a [function expression](../../operators/function) or the [`Function` constructor](../../global_objects/function)) does not have a name. Therefore if there is no accessible variable referring to it, the only way the function can refer to itself is by `arguments.callee`. The following example defines a function, which, in turn, defines and returns a factorial function. This example isn't very practical, and there are nearly no cases where the same result cannot be achieved with [named function expressions](../../operators/function). function create() { return function(n) { if (n <= 1) return 1; return n * arguments.callee(n - 1); }; } var result = create()(5); // returns 120 (5 * 4 * 3 * 2 * 1) ### A use of `arguments.callee` with no good alternative However, in a case like the following, there are not alternatives to `arguments.callee`, so its deprecation could be a bug (see [bug 725398](https://bugzilla.mozilla.org/show_bug.cgi?id=725398)): function createPerson(sIdentity) { var oPerson = new Function('alert(arguments.callee.identity);'); oPerson.identity = sIdentity; return oPerson; } var john = createPerson('John Smith'); john(); ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-arguments-exotic-objects
      `callee` 1 12 1 6 4 1 1 18 4 10.1 1 1.0 ## See also - [`Function`](../../global_objects/function) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee # Function.caller **Deprecated** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the [compatibility table](#browser_compatibility) at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time. The `function.caller` property returns the function that invoked the specified function. It returns `null` for strict, async function and generator function callers. ## Description If the function `f` was invoked by the top level code, the value of `f.caller` is [`null`](../null), otherwise it's the function that called `f`. It's also `null` for strict, async function and generator function callers. This property replaces the obsolete `arguments.caller` property of the [`arguments`](../../functions/arguments) object. The special property `__caller__`, which returned the activation object of the caller thus allowing to reconstruct the stack, was removed for security reasons. ### Notes Note that in case of recursion, you can't reconstruct the call stack using this property. Consider: function f(n) { g(n - 1); } function g(n) { if (n > 0) { f(n); } else { stop(); } } f(2); At the moment `stop()` is called the call stack will be: f(2) -> g(1) -> f(1) -> g(0) -> stop() The following is true: stop.caller === g && f.caller === g && g.caller === f so if you tried to get the stack trace in the `stop()` function like this: var f = stop; var stack = 'Stack trace:'; while (f) { stack += '\n' + f.name; f = f.caller; } the loop would never stop. ## Examples ### Checking the value of a function's `caller` property The following code checks the value a function's `caller` property. function myFunc() { if (myFunc.caller == null) { return 'The function was called from the top!'; } else { return 'This function\'s caller was ' + myFunc.caller; } } ## Specifications Not part of any standard. `caller` 1 12 1 8 9.6 3 1 18 4 10.1 1 1.0 ## See also - [`Function.name`](name) - [`arguments`](../../functions/arguments) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller # ReferenceError: can't access lexical declaration\`X' before initialization The JavaScript exception "can't access lexical declaration \`_variable_' before initialization" occurs when a lexical variable was accessed before it was initialized. This happens within any block statement, when `let` or `const` declarations are accessed before they are defined. ## Message ReferenceError: Use before delaration (Edge) ReferenceError: can't access lexical declaration `X' before initialization (Firefox) ReferenceError: 'x' is not defined (Chrome) ## Error type [`ReferenceError`](../global_objects/referenceerror) ## What went wrong? A lexical variable was accessed before it was initialized. This happens within any block statement, when `let` or `const` declarations are accessed before they are defined. ## Examples ### Invalid cases In this case, the variable "foo" is redeclared in the block statement using `let`. function test() { let foo = 33; if (true) { let foo = (foo + 55); // ReferenceError: can't access lexical // declaration `foo' before initialization } } test(); ### Valid cases To change "foo" inside the if statement, you need to remove the `let` that causes the redeclaration. function test(){ let foo = 33; if (true) { foo = (foo + 55); } } test(); ## See also - [Temporal Dead Zone and errors with let](../statements/let#temporal_dead_zone_and_errors_with_let) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_lexical_declaration_before_init # TypeError: can't access property "x" of "y" The JavaScript exception "can't access property" occurs when property access was operated on [`undefined`](../global_objects/undefined) or [`null`](../global_objects/null) values. ## Message TypeError: Unable to get property {x} of undefined or null reference (Edge) TypeError: can't access property {x} of {y} (Firefox) TypeError: {y} is undefined, can't access property {x} of it (Firefox) TypeError: {y} is null, can't access property {x} of it (Firefox) Examples: TypeError: x is undefined, can't access property "prop" of it TypeError: x is null, can't access property "prop" of it TypeError: can't access property "prop" of undefined TypeError: can't access property "prop" of null ## Error type [`TypeError`](../global_objects/typeerror). ## What went wrong? The property access was operated on [`undefined`](../global_objects/undefined) or [`null`](../global_objects/null) value. ## Examples ### Invalid cases // undefined and null cases on which the substring method won't work var foo = undefined; foo.substring(1); // TypeError: x is undefined, can't access property "substring" of it var foo = null; foo.substring(1); // TypeError: x is null, can't access property "substring" of it ### Fixing the issue To fix null pointer to `undefined` or `null` values, you can use the [typeof](../operators/typeof) operator, for example. if (typeof foo !== 'undefined') { // Now we know that foo is defined, we are good to go. } ## See also - [`undefined`](../global_objects/undefined) - [`null`](../global_objects/null) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_access_property # TypeError: can't assign to property "x" on "y": not an object The JavaScript strict mode exception "can't assign to property" occurs when attempting to create a property on [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) value such as a [symbol](https://developer.mozilla.org/en-US/docs/Glossary/Symbol), a [string](https://developer.mozilla.org/en-US/docs/Glossary/String), a [number](https://developer.mozilla.org/en-US/docs/Glossary/Number) or a [boolean](https://developer.mozilla.org/en-US/docs/Glossary/Boolean). [Primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) values cannot hold any [property](https://developer.mozilla.org/en-US/docs/Glossary/property/JavaScript). ## Message TypeError: can't assign to property "x" on {y}: not an object (Firefox) TypeError: Cannot create property 'x' on {y} (Chrome) ## Error type [`TypeError`](../global_objects/typeerror). ## What went wrong? In [`Strict_mode`](../strict_mode), a [`TypeError`](../global_objects/typeerror) is raised when attempting to create a property on [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) value such as a [symbol](https://developer.mozilla.org/en-US/docs/Glossary/Symbol), a [string](https://developer.mozilla.org/en-US/docs/Glossary/String), a [number](https://developer.mozilla.org/en-US/docs/Glossary/Number) or a [boolean](https://developer.mozilla.org/en-US/docs/Glossary/Boolean). [Primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) values cannot hold any [property](https://developer.mozilla.org/en-US/docs/Glossary/property/JavaScript). The problem might be that an unexpected value is flowing at an unexpected place, or that an object variant of a [`String`](../global_objects/string) or a [`Number`](../global_objects/number) is expected. ## Examples ### Invalid cases 'use strict'; var foo = "my string"; // The following line does nothing if not in strict mode. foo.bar = {}; // TypeError: can't assign to property "bar" on "my string": not an object ### Fixing the issue Either fix the code to prevent the [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) from being used in such places, or fix the issue is to create the object equivalent [`Object`](../global_objects/object). 'use strict'; var foo = new String("my string"); foo.bar = {}; ## See also - [`Strict_mode`](../strict_mode) - [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_assign_to_property # TypeError: can't define property "x": "obj" is not extensible The JavaScript exception "can't define property "x": "obj" is not extensible" occurs when [`Object.preventExtensions()`](../global_objects/object/preventextensions) marked an object as no longer extensible, so that it will never have properties beyond the ones it had at the time it was marked as non-extensible. ## Message TypeError: Cannot create property for a non-extensible object (Edge) TypeError: can't define property "x": "obj" is not extensible (Firefox) TypeError: Cannot define property: "x", object is not extensible. (Chrome) ## Error type [`TypeError`](../global_objects/typeerror) ## What went wrong? Usually, an object is extensible and new properties can be added to it. However, in this case [`Object.preventExtensions()`](../global_objects/object/preventextensions) marked an object as no longer extensible, so that it will never have properties beyond the ones it had at the time it was marked as non-extensible. ## Examples ### Adding new properties to a non-extensible objects In [strict mode](../strict_mode), attempting to add new properties to a non-extensible object throws a `TypeError`. In sloppy mode, the addition of the "x" property is silently ignored. 'use strict'; var obj = {}; Object.preventExtensions(obj); obj.x = 'foo'; // TypeError: can't define property "x": "obj" is not extensible In both, [strict mode](../strict_mode) and sloppy mode, a call to [`Object.defineProperty()`](../global_objects/object/defineproperty) throws when adding a new property to a non-extensible object. var obj = { }; Object.preventExtensions(obj); Object.defineProperty(obj, 'x', { value: "foo" } ); // TypeError: can't define property "x": "obj" is not extensible To fix this error, you will either need to remove the call to [`Object.preventExtensions()`](../global_objects/object/preventextensions) entirely, or move it to a position so that the property is added earlier and only later the object is marked as non-extensible. Of course you can also remove the property that was attempted to be added, if you don't need it. 'use strict'; var obj = {}; obj.x = 'foo'; // add property first and only then prevent extensions Object.preventExtensions(obj); ## See also - [`Object.preventExtensions()`](../global_objects/object/preventextensions) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_define_property_object_not_extensible # TypeError: property "x" is non-configurable and can't be deleted The JavaScript exception "property is non-configurable and can't be deleted" occurs when it was attempted to delete a property, but that property is [non-configurable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#properties). ## Message TypeError: Calling delete on 'x' is not allowed in strict mode (Edge) TypeError: property "x" is non-configurable and can't be deleted. (Firefox) TypeError: Cannot delete property 'x' of # (Chrome) ## Error type [`TypeError`](../global_objects/typeerror) in strict mode only. ## What went wrong? It was attempted to delete a property, but that property is [non-configurable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#properties). The `configurable` attribute controls whether the property can be deleted from the object and whether its attributes (other than `writable`) can be changed. This error happens only in [strict mode code](../strict_mode). In non-strict code, the operation returns `false`. ## Examples ### Attempting to delete non-configurable properties Non-configurable properties are not super common, but they can be created using [`Object.defineProperty()`](../global_objects/object/defineproperty) or [`Object.freeze()`](../global_objects/object/freeze). 'use strict'; var obj = Object.freeze({name: 'Elsa', score: 157}); delete obj.score; // TypeError 'use strict'; var obj = {}; Object.defineProperty(obj, 'foo', {value: 2, configurable: false}); delete obj.foo; // TypeError 'use strict'; var frozenArray = Object.freeze([0, 1, 2]); frozenArray.pop(); // TypeError There are also a few non-configurable properties built into JavaScript. Maybe you tried to delete a mathematical constant. 'use strict'; delete Math.PI; // TypeError ## See also - [delete operator](../operators/delete) - [`Object.defineProperty()`](../global_objects/object/defineproperty) - [`Object.freeze()`](../global_objects/object/freeze) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_delete # TypeError: can't redefine non-configurable property "x" The JavaScript exception "can't redefine non-configurable property" occurs when it was attempted to redefine a property, but that property is [non-configurable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#properties). ## Message TypeError: Cannot modify non-writable property {x} (Edge) TypeError: can't redefine non-configurable property "x" (Firefox) TypeError: Cannot redefine property: "x" (Chrome) ## Error type [`TypeError`](../global_objects/typeerror) ## What went wrong? It was attempted to redefine a property, but that property is [non-configurable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#properties). The `configurable` attribute controls whether the property can be deleted from the object and whether its attributes (other than `writable`) can be changed. Usually, properties in an object created by an [object initializer](../operators/object_initializer) are configurable. However, for example, when using [`Object.defineProperty()`](../global_objects/object/defineproperty), the property isn't configurable by default. ## Examples ### Non-configurable properties created by `Object.defineProperty` The [`Object.defineProperty()`](../global_objects/object/defineproperty) creates non-configurable properties if you haven't specified them as configurable. var obj = Object.create({}); Object.defineProperty(obj, "foo", {value: "bar"}); Object.defineProperty(obj, "foo", {value: "baz"}); // TypeError: can't redefine non-configurable property "foo" You will need to set the "foo" property to configurable, if you intend to redefine it later in the code. var obj = Object.create({}); Object.defineProperty(obj, "foo", {value: "bar", configurable: true}); Object.defineProperty(obj, "foo", {value: "baz", configurable: true}); ## See also - [\[\[Configurable\]\]](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#properties) - [`Object.defineProperty()`](../global_objects/object/defineproperty) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_redefine_property # Intl.Locale.prototype.caseFirst The `Intl.Locale.prototype.caseFirst` property is an accessor property that returns whether case is taken into account for the locale's collation rules. ## Description A locale's collation rules are used to determine how strings are ordered in that locale. Certain locales use a character's case (UPPERCASE or lowercase) in the collation process. This additional rule can be expressed in a [`Locale's`](../locale) `caseFirst` property. There are 3 values that the `caseFirst` property can have, outlined in the table below. ### `caseFirst` values
      ValueDescription
      upperUpper case to be sorted before lower case.
      lowerLower case to be sorted before upper case.
      falseNo special case ordering.
      ## Examples ### Setting the caseFirst value via the locale string In the [Unicode locale string spec](https://www.unicode.org/reports/tr35/), the values that `caseFirst` represents correspond to the key `kf`. `kf` is treated as a locale string "extension subtag". These subtags add additional data about the locale, and are added to locale identifiers by using the `-u` extension key. Thus, the `caseFirst` value can be added to the initial locale identifier string that is passed into the `Locale` constructor. To add the `caseFirst` value, first add the `-u` extension key to the string. Next, add the `-kf` extension key to indicate that you are adding a value for `caseFirst`. Finally, add the `caseFirst` value to the string. let caseFirstStr = new Intl.Locale("fr-Latn-FR-u-kf-upper"); console.log(caseFirstStr.caseFirst); // Prints "upper" ### Setting the caseFirst value via the configuration object argument The [`Intl.Locale`](locale) constructor has an optional configuration object argument, which can be used to pass extension types. Set the `caseFirst` property of the configuration object to your desired `caseFirst` value, and then pass it into the constructor. let caseFirstObj= new Intl.Locale("en-Latn-US", {caseFirst: "lower"}); console.log(us12hour.caseFirst); // Prints "lower" ## Specifications
      Specification
      ECMAScript Internationalization API Specification (ECMAScript Internationalization API)
      #sec-Intl.Locale.prototype.caseFirst
      `caseFirst` 74 79 75 No 62 14 74 74 79 53 14 11.0 ## See also - [`Intl.Locale`](../locale) - [Unicode case first collation spec](https://github.com/unicode-org/cldr/blob/master/common/bcp47/collation.xml#L49) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/caseFirst # Promise.prototype.catch() The `catch()` method returns a [`Promise`](../promise) and deals with rejected cases only. It behaves the same as calling [`Promise.prototype.then(undefined, onRejected)`](then) (in fact, calling `obj.catch(onRejected)` internally calls `obj.then(undefined, onRejected)`). This means that you have to provide an `onRejected` function even if you want to fall back to an `undefined` result value - for example `obj.catch(() => {})`. ## Syntax p.catch(onRejected); p.catch(function(reason) { // rejection }); ### Parameters `onRejected` A [`Function`](../function) called when the `Promise` is rejected. This function has one argument: `reason` The rejection reason. The Promise returned by `catch()` is rejected if `onRejected` throws an error or returns a Promise which is itself rejected; otherwise, it is resolved. ### Return value Internally calls `Promise.prototype.then` on the object upon which it was called, passing the parameters `undefined` and the received `onRejected` handler. Returns the value of that call, which is a [`Promise`](../promise). **Warning:** The examples below are throwing instances of [Error](../error). This is considered good practice in contrast to throwing Strings; otherwise, the part doing the catching would have to perform checks to see if the argument was a string or an error, and you might lose valuable information like stack traces. **Demonstration of the internal call:** // overriding original Promise.prototype.then/catch just to add some logs (function(Promise){ var originalThen = Promise.prototype.then; var originalCatch = Promise.prototype.catch; Promise.prototype.then = function(){ console.log('> > > > > > called .then on %o with arguments: %o', this, arguments); return originalThen.apply(this, arguments); }; Promise.prototype.catch = function(){ console.error('> > > > > > called .catch on %o with arguments: %o', this, arguments); return originalCatch.apply(this, arguments); }; })(this.Promise); // calling catch on an already resolved promise Promise.resolve().catch(function XXX(){}); // logs: // > > > > > > called .catch on Promise{} with arguments: Arguments{1} [0: function XXX()] // > > > > > > called .then on Promise{} with arguments: Arguments{2} [0: undefined, 1: function XXX()] ## Description The `catch` method is used for error handling in promise composition. Since it returns a [`Promise`](../promise), it [can be chained](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#chaining_after_a_catch) in the same way as its sister method, [`then()`](then). ## Examples ### Using and chaining the catch method var p1 = new Promise(function(resolve, reject) { resolve('Success'); }); p1.then(function(value) { console.log(value); // "Success!" throw new Error('oh, no!'); }).catch(function(e) { console.error(e.message); // "oh, no!" }).then(function(){ console.log('after a catch the chain is restored'); }, function () { console.log('Not fired due to the catch'); }); // The following behaves the same as above p1.then(function(value) { console.log(value); // "Success!" return Promise.reject('oh, no!'); }).catch(function(e) { console.error(e); // "oh, no!" }).then(function(){ console.log('after a catch the chain is restored'); }, function () { console.log('Not fired due to the catch'); }); ### Gotchas when throwing errors // Throwing an error will call the catch method most of the time var p1 = new Promise(function(resolve, reject) { throw new Error('Uh-oh!'); }); p1.catch(function(e) { console.error(e); // "Uh-oh!" }); // Errors thrown inside asynchronous functions will act like uncaught errors var p2 = new Promise(function(resolve, reject) { setTimeout(function() { throw new Error('Uncaught Exception!'); }, 1000); }); p2.catch(function(e) { console.error(e); // This is never called }); // Errors thrown after resolve is called will be silenced var p3 = new Promise(function(resolve, reject) { resolve(); throw new Error('Silenced Exception!'); }); p3.catch(function(e) { console.error(e); // This is never called }); ### If it is resolved //Create a promise which would not call onReject var p1 = Promise.resolve("calling next"); var p2 = p1.catch(function (reason) { //This is never called console.error("catch p1!"); console.error(reason); }); p2.then(function (value) { console.log("next promise's onFulfilled"); /* next promise's onFulfilled */ console.log(value); /* calling next */ }, function (reason) { console.log("next promise's onRejected"); console.log(reason); }); ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-promise.prototype.catch
      `catch` 32 12 29 No 19 8 4.4.3 32 29 19 8 2.0 ## See also - [`Promise`](../promise) - [`Promise.prototype.then()`](then) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch # Math.cbrt() The `Math.cbrt()` function returns the cube root of a number, that is $$\\mathtt{Math.cbrt(x)} = \\sqrt\[3\]{x} = \\text{the\\ unique}\\; y\\;\\text{such\\ that}\\; y^{3} = x$$ ## Syntax Math.cbrt(x) ### Parameters x A number. ### Return value The cube root of the given number. ## Description Because `cbrt()` is a static method of `Math`, you always use it as `Math.cbrt()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Polyfill For all *x* ≥ 0, have $\\sqrt\[3\]{x} = x^{1/3}$ so this can be emulated by the following function: if (!Math.cbrt) { Math.cbrt = (function(pow) { return function cbrt(x){ // ensure negative numbers remain negative: return x < 0 ? -pow(-x, 1/3) : pow(x, 1/3); }; })(Math.pow); // localize Math.pow to increase efficiency } ## Examples ### Using Math.cbrt() Math.cbrt(NaN); // NaN Math.cbrt(-1); // -1 Math.cbrt(-0); // -0 Math.cbrt(-Infinity); // -Infinity Math.cbrt(0); // 0 Math.cbrt(1); // 1 Math.cbrt(Infinity); // Infinity Math.cbrt(null); // 0 Math.cbrt(2); // 1.2599210498948732 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.cbrt
      `cbrt` 38 12 25 No 25 8 38 38 25 25 8 3.0 ## See also - [`Math.pow()`](pow) - [`Math.sqrt()`](sqrt) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt # Math.ceil() The `Math.ceil()` function always rounds a number up to the next largest integer. **Note:** `Math.ceil(null`) returns integer 0 and does not give a [`NaN`](../nan) error. ## Syntax Math.ceil(x) ### Parameters `x` A number. ### Return value The smallest integer greater than or equal to the given number. ## Description Because `ceil()` is a static method of `Math`, you always use it as `Math.ceil()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.ceil() The following example shows example usage of `Math.ceil()`. Math.ceil(.95); // 1 Math.ceil(4); // 4 Math.ceil(7.004); // 8 Math.ceil(-0.95); // -0 Math.ceil(-4); // -4 Math.ceil(-7.004); // -7 ### Decimal adjustment // Closure (function() { /** * Decimal adjustment of a number. * * @param {String} type The type of adjustment. * @param {Number} value The number. * @param {Integer} exp The exponent (the 10 logarithm of the adjustment base). * @returns {Number} The adjusted value. */ function decimalAdjust(type, value, exp) { // If the exp is undefined or zero... if (typeof exp === 'undefined' || +exp === 0) { return Math[type](value); } value = +value; exp = +exp; // If the value is not a number or the exp is not an integer... if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) { return NaN; } // Shift value = value.toString().split('e'); value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp))); // Shift back value = value.toString().split('e'); return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)); } // Decimal round if (!Math.round10) { Math.round10 = function(value, exp) { return decimalAdjust('round', value, exp); }; } // Decimal floor if (!Math.floor10) { Math.floor10 = function(value, exp) { return decimalAdjust('floor', value, exp); }; } // Decimal ceil if (!Math.ceil10) { Math.ceil10 = function(value, exp) { return decimalAdjust('ceil', value, exp); }; } })(); // Round Math.round10(55.55, -1); // 55.6 Math.round10(55.549, -1); // 55.5 Math.round10(55, 1); // 60 Math.round10(54.9, 1); // 50 Math.round10(-55.55, -1); // -55.5 Math.round10(-55.551, -1); // -55.6 Math.round10(-55, 1); // -50 Math.round10(-55.1, 1); // -60 // Floor Math.floor10(55.59, -1); // 55.5 Math.floor10(59, 1); // 50 Math.floor10(-55.51, -1); // -55.6 Math.floor10(-51, 1); // -60 // Ceil Math.ceil10(55.51, -1); // 55.6 Math.ceil10(51, 1); // 60 Math.ceil10(-55.59, -1); // -55.5 Math.ceil10(-59, 1); // -50 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.ceil
      `ceil` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`Math.abs()`](abs) - [`Math.floor()`](floor) - [`Math.round()`](round) - [`Math.sign()`](sign) - [`Math.trunc()`](trunc) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil # String.prototype.charAt() The [`String`](../string) object's `charAt()` method returns a new string consisting of the single UTF-16 code unit located at the specified offset into the string. ## Syntax charAt(index) ### Parameters `index` An integer between `0` and `str.length - 1`. If the `index` cannot be converted to the integer or no `index` is provided, the default is `0`, so the first character of `str` is returned. ### Return value A string representing the character (exactly one UTF-16 code unit) at the specified `index`. If `index` is out of range, `charAt()` returns an empty string. ## Description Characters in a string are indexed from left to right. The index of the first character is `0`, and the index of the last character—in a string called `stringName`—is `stringName.length - 1`. If the `index` you supply is out of this range, JavaScript returns an empty string. If no `index` is provided to `charAt()`, the default is `0`. ## Examples ### Displaying characters at different locations in a string The following example displays characters at different locations in the string "`Brave new world`": var anyString = 'Brave new world'; console.log("The character at index 0 is '" + anyString.charAt() + "'"); // No index was provided, used 0 as default console.log("The character at index 0 is '" + anyString.charAt(0) + "'"); console.log("The character at index 1 is '" + anyString.charAt(1) + "'"); console.log("The character at index 2 is '" + anyString.charAt(2) + "'"); console.log("The character at index 3 is '" + anyString.charAt(3) + "'"); console.log("The character at index 4 is '" + anyString.charAt(4) + "'"); console.log("The character at index 999 is '" + anyString.charAt(999) + "'"); These lines display the following: The character at index 0 is 'B' The character at index 0 is 'B' The character at index 1 is 'r' The character at index 2 is 'a' The character at index 3 is 'v' The character at index 4 is 'e' The character at index 999 is '' ### Getting whole characters The following provides a means of ensuring that going through a string loop always provides a whole character, even if the string contains characters that are not in the Basic Multi-lingual Plane. var str = 'A \uD87E\uDC04 Z'; // We could also use a non-BMP character directly for (var i = 0, chr; i < str.length; i++) { if ((chr = getWholeChar(str, i)) === false) { continue; } // Adapt this line at the top of each loop, passing in the whole string and // the current iteration and returning a variable to represent the // individual character console.log(chr); } function getWholeChar(str, i) { var code = str.charCodeAt(i); if (Number.isNaN(code)) { return ''; // Position not found } if (code < 0xD800 || code > 0xDFFF) { return str.charAt(i); } // High surrogate (could change last hex to 0xDB7F to treat high private // surrogates as single characters) if (0xD800 <= code && code <= 0xDBFF) { if (str.length <= (i + 1)) { throw 'High surrogate without following low surrogate'; } var next = str.charCodeAt(i + 1); if (0xDC00 > next || next > 0xDFFF) { throw 'High surrogate without following low surrogate'; } return str.charAt(i) + str.charAt(i + 1); } // Low surrogate (0xDC00 <= code && code <= 0xDFFF) if (i === 0) { throw 'Low surrogate without preceding high surrogate'; } var prev = str.charCodeAt(i - 1); // (could change last hex to 0xDB7F to treat high private // surrogates as single characters) if (0xD800 > prev || prev > 0xDBFF) { throw 'Low surrogate without preceding high surrogate'; } // We can pass over low surrogates now as the second component // in a pair which we have already processed return false; } In an ECMAScript 2016 environment which allows destructured assignment, the following is a more succinct and somewhat more flexible alternative in that it does increment for an incrementing variable automatically (if the character warrants it in being a surrogate pair). let str = 'A\uD87E\uDC04Z' // We could also use a non-BMP character directly for (let i = 0, chr; i < str.length; i++) { [chr, i] = getWholeCharAndI(str, i) // Adapt this line at the top of each loop, passing in the whole string and // the current iteration and returning an array with the individual character // and 'i' value (only changed if a surrogate pair) console.log(chr) } function getWholeCharAndI(str, i) { let code = str.charCodeAt(i) if (Number.isNaN(code)) { return '' // Position not found } if (code < 0xD800 || code > 0xDFFF) { return [str.charAt(i), i] // Normal character, keeping 'i' the same } // High surrogate (could change last hex to 0xDB7F to treat high private // surrogates as single characters) if (0xD800 <= code && code <= 0xDBFF) { if (str.length <= (i + 1)) { throw 'High surrogate without following low surrogate' } let next = str.charCodeAt(i + 1) if (0xDC00 > next || next > 0xDFFF) { throw 'High surrogate without following low surrogate' } return [str.charAt(i) + str.charAt(i + 1), i + 1] } // Low surrogate (0xDC00 <= code && code <= 0xDFFF) if (i === 0) { throw 'Low surrogate without preceding high surrogate' } let prev = str.charCodeAt(i - 1) // (could change last hex to 0xDB7F to treat high private surrogates // as single characters) if (0xD800 > prev || prev > 0xDBFF) { throw 'Low surrogate without preceding high surrogate' } // Return the next character instead (and increment) return [str.charAt(i + 1), i + 1] } ### Fixing charAt() to support non-Basic-Multilingual-Plane (BMP) characters While the previous example may be more useful for programs that must support non-BMP characters (since it does not require the caller to know where any non-BMP character might appear), in the event that one _does_ wish, in choosing a character by index, to treat the surrogate pairs within a string as the single characters they represent, one can use the following: function fixedCharAt(str, idx) { let ret = '' str += '' let end = str.length let surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g while ((surrogatePairs.exec(str)) != null) { let lastIdx = surrogatePairs.lastIndex if (lastIdx - 2 < idx) { idx++ } else { break } } if (idx >= end || idx < 0) { return '' } ret += str.charAt(idx) if (/[\uD800-\uDBFF]/.test(ret) && /[\uDC00-\uDFFF]/.test(str.charAt(idx + 1))) { // Go one further, since one of the "characters" is part of a surrogate pair ret += str.charAt(idx + 1) } return ret } ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'String.prototype.charAt' in that specification.
      `charAt` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`String.prototype.indexOf()`](indexof) - [`String.prototype.lastIndexOf()`](lastindexof) - [`String.prototype.charCodeAt()`](charcodeat) - [`String.prototype.codePointAt()`](codepointat) - [`String.prototype.split()`](split) - [`String.fromCodePoint()`](fromcodepoint) - [JavaScript has a Unicode problem – Mathias Bynens](https://mathiasbynens.be/notes/javascript-unicode) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charAt # String.prototype.charCodeAt() The `charCodeAt()` method returns an integer between `0` and `65535` representing the UTF-16 code unit at the given index. The UTF-16 code unit matches the Unicode code point for code points which can be represented in a single UTF-16 code unit. If the Unicode code point cannot be represented in a single UTF-16 code unit (because its value is greater than `0xFFFF`) then the code unit returned will be _the first part of a surrogate pair_ for the code point. If you want the entire code point value, use [`codePointAt()`](codepointat). ## Syntax charCodeAt(index) ### Parameters `index` An integer greater than or equal to `0` and less than the `length` of the string. If `index` is not a number, it defaults to `0`. ### Return value A number representing the UTF-16 code unit value of the character at the given `index`. If `index` is out of range, `charCodeAt()` returns [`NaN`](../nan). ## Description Unicode code points range from `0` to `1114111` (`0x10FFFF`). The first 128 Unicode code points are a direct match of the ASCII character encoding. (For information on Unicode, see the [JavaScript Guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#unicode).) **Note:** `charCodeAt()` will always return a value that is less than `65536`. This is because the higher code points are represented by _a pair_ of (lower valued) "surrogate" pseudo-characters which are used to comprise the real character. Because of this, in order to examine (or reproduce) the full character for individual character values of `65536` or greater, for such characters, it is necessary to retrieve not only `charCodeAt(i)`, but also `charCodeAt(i+1)` (as if manipulating a string with two letters), or to use `codePointAt(i)` instead. See examples 2 and 3 (below). `charCodeAt()` returns [`NaN`](../nan) if the given index is less than `0`, or if it is equal to or greater than the `length` of the string. Backward compatibility: In historic versions (like JavaScript 1.2) the `charCodeAt()` method returns a number indicating the ISO-Latin-1 codeset value of the character at the given index. The ISO-Latin-1 codeset ranges from `0` to `255`. The first `0` to `127` are a direct match of the ASCII character set. ## Examples ### Using charCodeAt() The following example returns `65`, the Unicode value for A. 'ABC'.charCodeAt(0) // returns 65 ### Fixing charCodeAt() to handle non-Basic-Multilingual-Plane characters if their presence earlier in the string is unknown This version might be used in for loops and the like when it is unknown whether non-BMP characters exist before the specified index position. function fixedCharCodeAt(str, idx) { // ex. fixedCharCodeAt('\uD800\uDC00', 0); // 65536 // ex. fixedCharCodeAt('\uD800\uDC00', 1); // false idx = idx || 0; var code = str.charCodeAt(idx); var hi, low; // High surrogate (could change last hex to 0xDB7F // to treat high private surrogates // as single characters) if (0xD800 <= code && code <= 0xDBFF) { hi = code; low = str.charCodeAt(idx + 1); if (isNaN(low)) { throw 'High surrogate not followed by ' + 'low surrogate in fixedCharCodeAt()'; } return ( (hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; } if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate // We return false to allow loops to skip // this iteration since should have already handled // high surrogate above in the previous iteration return false; // hi = str.charCodeAt(idx - 1); // low = code; // return ((hi - 0xD800) * 0x400) + // (low - 0xDC00) + 0x10000; } return code; } ### Fixing charCodeAt() to handle non-Basic-Multilingual-Plane characters if their presence earlier in the string is known function knownCharCodeAt(str, idx) { str += ''; var code, end = str.length; var surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; while ((surrogatePairs.exec(str)) != null) { var li = surrogatePairs.lastIndex; if (li - 2 < idx) { idx++; } else { break; } } if (idx >= end || idx < 0) { return NaN; } code = str.charCodeAt(idx); var hi, low; if (0xD800 <= code && code <= 0xDBFF) { hi = code; low = str.charCodeAt(idx + 1); // Go one further, since one of the "characters" // is part of a surrogate pair return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; } return code; } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-string.prototype.charcodeat
      `charCodeAt` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 ## See also - [`String.fromCharCode()`](fromcharcode) - [`String.prototype.charAt()`](charat) - [`String.fromCodePoint()`](fromcodepoint) - [`String.prototype.codePointAt()`](codepointat) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt # class expression The **class expression** is one way to define a class in ECMAScript 2015. Similar to [function expressions](function), class expressions can be named or unnamed. If named, the name of the class is local to the class body only. JavaScript classes use prototype-based inheritance. ## Syntax const MyClass = class [className] [extends otherClassName] { // class body }; ## Description A class expression has a similar syntax to a [class declaration (statement)](../statements/class). As with `class` statements, the body of a `class` expression is executed in [strict mode](../strict_mode). There are several differences between class expressions and [class statements](../statements/class), however: - Class expressions may omit the class name ("binding identifier"), which is not possible with [class statements](../statements/class). - Class expressions allow you to redefine (re-declare) classes **without throwing** a [`SyntaxError`](../global_objects/syntaxerror). This is not the case with [class statements](../statements/class). The `constructor` method is optional. Classes generated with class expressions will always respond to [`typeof`](typeof) with the value "`function`". 'use strict'; let Foo = class {}; // constructor property is optional Foo = class {}; // Re-declaration is allowed typeof Foo; // returns "function" typeof class {}; // returns "function" Foo instanceof Object; // true Foo instanceof Function; // true class Foo {} // Throws SyntaxError (class declarations do not allow re-declaration) ## Examples ### A simple class expression This is just a simple anonymous class expression which you can refer to using the variable `Foo`. const Foo = class { constructor() {} bar() { return 'Hello World!'; } }; const instance = new Foo(); instance.bar(); // "Hello World!" Foo.name; // "Foo" ### Named class expressions If you want to refer to the current class inside the class body, you can create a _named class expression_. The name is only visible within the scope of the class expression itself. const Foo = class NamedFoo { constructor() {} whoIsThere() { return NamedFoo.name; } } const bar = new Foo(); bar.whoIsThere(); // "NamedFoo" NamedFoo.name; // ReferenceError: NamedFoo is not defined Foo.name; // "NamedFoo" ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-class-definitions
      `class` 42 13 45 No 29 7 42 42 45 29 7 4.0 ## See also - [function expression](function) - [class declaration](../statements/class) - [Classes](../classes) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/class # Classes Classes are a template for creating objects. They encapsulate data with code to work on that data. Classes in JS are built on prototypes but also have some syntax and semantics that are not shared with ES5 class-like semantics. ## Defining classes Classes are in fact "special functions", and just as you can define [function expressions](operators/function) and [function declarations](statements/function), the class syntax has two components: [class expressions](operators/class) and [class declarations](statements/class). ### Class declarations One way to define a class is using a **class declaration**. To declare a class, you use the `class` keyword with the name of the class ("Rectangle" here). class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } #### Hoisting An important difference between **function declarations** and **class declarations** is that function declarations are [hoisted](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting) and class declarations are not. You first need to declare your class and then access it, otherwise code like the following will throw a [`ReferenceError`](global_objects/referenceerror): const p = new Rectangle(); // ReferenceError class Rectangle {} ### Class expressions A **class expression** is another way to define a class. Class expressions can be named or unnamed. The name given to a named class expression is local to the class's body. (it can be retrieved through the class's (not an instance's) [`name`](global_objects/function/name) property, though). // unnamed let Rectangle = class { constructor(height, width) { this.height = height; this.width = width; } }; console.log(Rectangle.name); // output: "Rectangle" // named let Rectangle = class Rectangle2 { constructor(height, width) { this.height = height; this.width = width; } }; console.log(Rectangle.name); // output: "Rectangle2" **Note:** Class **expressions** are subject to the same hoisting restrictions as described in the [Class declarations](#class_declarations) section. ## Class body and method definitions The body of a class is the part that is in curly brackets `{}`. This is where you define class members, such as methods or constructor. ### Strict mode The body of a class is executed in [strict mode](strict_mode), i.e., code written here is subject to stricter syntax for increased performance, some otherwise silent errors will be thrown, and certain keywords are reserved for future versions of ECMAScript. ### Constructor The [constructor](classes/constructor) method is a special method for creating and initializing an object created with a `class`. There can only be one special method with the name "constructor" in a class. A [`SyntaxError`](global_objects/syntaxerror) will be thrown if the class contains more than one occurrence of a `constructor` method. A constructor can use the `super` keyword to call the constructor of the super class. ### Prototype methods See also [method definitions](functions/method_definitions). class Rectangle { constructor(height, width) { this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100 ### Generator methods See also [Iterators and generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators). class Polygon { constructor(...sides) { this.sides = sides; } // Method *getSides() { for(const side of this.sides){ yield side; } } } const pentagon = new Polygon(1,2,3,4,5); console.log([...pentagon.getSides()]); // [1,2,3,4,5] ### Static methods and properties The [static](classes/static) keyword defines a static method or property for a class. Static members (properties and methods) are called without [instantiating]() their class and **cannot** be called through a class instance. Static methods are often used to create utility functions for an application, whereas static properties are useful for caches, fixed-configuration, or any other data you don't need to be replicated across instances. class Point { constructor(x, y) { this.x = x; this.y = y; } static displayName = "Point"; static distance(a, b) { const dx = a.x - b.x; const dy = a.y - b.y; return Math.hypot(dx, dy); } } const p1 = new Point(5, 5); const p2 = new Point(10, 10); p1.displayName; // undefined p1.distance; // undefined p2.displayName; // undefined p2.distance; // undefined console.log(Point.displayName); // "Point" console.log(Point.distance(p1, p2)); // 7.0710678118654755 ### Binding `this` with prototype and static methods When a static or prototype method is called without a value for [`this`](operators/this), such as by assigning the method to a variable and then calling it, the `this` value will be `undefined` inside the method. This behavior will be the same even if the [`"use strict"`](strict_mode) directive isn't present, because code within the `class` body's syntactic boundary is always executed in strict mode. class Animal { speak() { return this; } static eat() { return this; } } let obj = new Animal(); obj.speak(); // the Animal object let speak = obj.speak; speak(); // undefined Animal.eat() // class Animal let eat = Animal.eat; eat(); // undefined If we rewrite the above using traditional function-based syntax in non–strict mode, then `this` method calls are automatically bound to the initial `this` value, which by default is the [global object](https://developer.mozilla.org/en-US/docs/Glossary/Global_object). In strict mode, autobinding will not happen; the value of `this` remains as passed. function Animal() { } Animal.prototype.speak = function() { return this; } Animal.eat = function() { return this; } let obj = new Animal(); let speak = obj.speak; speak(); // global object (in non–strict mode) let eat = Animal.eat; eat(); // global object (in non-strict mode) ### Instance properties Instance properties must be defined inside of class methods: class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } Static (class-side) data properties and prototype data properties must be defined outside of the ClassBody declaration: Rectangle.staticWidth = 20; Rectangle.prototype.prototypeWidth = 25; ### Field declarations **Warning:** Public and private field declarations are an [experimental feature (stage 3)](https://github.com/tc39/proposal-class-fields) proposed at [TC39](https://tc39.es), the JavaScript standards committee. Support in browsers is limited, but the feature can be used through a build step with systems like [Babel](https://babeljs.io/). #### Public field declarations With the JavaScript field declaration syntax, the above example can be written as: class Rectangle { height = 0; width; constructor(height, width) { this.height = height; this.width = width; } } By declaring fields up-front, class definitions become more self-documenting, and the fields are always present. As seen above, the fields can be declared with or without a default value. See [public class fields](classes/public_class_fields) for more information. #### Private field declarations Using private fields, the definition can be refined as below. class Rectangle { #height = 0; #width; constructor(height, width) { this.#height = height; this.#width = width; } } It's an error to reference private fields from outside of the class; they can only be read or written within the class body. By defining things that are not visible outside of the class, you ensure that your classes' users can't depend on internals, which may change from version to version. **Note:** Private fields can only be declared up-front in a field declaration. Private fields cannot be created later through assigning to them, the way that normal properties can. For more information, see [private class fields](classes/private_class_fields). ## Sub classing with `extends` The [`extends`](classes/extends) keyword is used in _class declarations_ or _class expressions_ to create a class as a child of another class. class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } } class Dog extends Animal { constructor(name) { super(name); // call the super class constructor and pass in the name parameter } speak() { console.log(`${this.name} barks.`); } } let d = new Dog('Mitzie'); d.speak(); // Mitzie barks. If there is a constructor present in the subclass, it needs to first call super() before using "this". One may also extend traditional function-based "classes": function Animal (name) { this.name = name; } Animal.prototype.speak = function () { console.log(`${this.name} makes a noise.`); } class Dog extends Animal { speak() { console.log(`${this.name} barks.`); } } let d = new Dog('Mitzie'); d.speak(); // Mitzie barks. // For similar methods, the child's method takes precedence over parent's method Note that classes cannot extend regular (non-constructible) objects. If you want to inherit from a regular object, you can instead use [`Object.setPrototypeOf()`](global_objects/object/setprototypeof): const Animal = { speak() { console.log(`${this.name} makes a noise.`); } }; class Dog { constructor(name) { this.name = name; } } // If you do not do this you will get a TypeError when you invoke speak Object.setPrototypeOf(Dog.prototype, Animal); let d = new Dog('Mitzie'); d.speak(); // Mitzie makes a noise. ## Species You might want to return [`Array`](global_objects/array) objects in your derived array class `MyArray`. The species pattern lets you override default constructors. For example, when using methods such as [`map()`](global_objects/array/map) that returns the default constructor, you want these methods to return a parent `Array` object, instead of the `MyArray` object. The [`Symbol.species`](global_objects/symbol/species) symbol lets you do this: class MyArray extends Array { // Overwrite species to the parent Array constructor static get [Symbol.species]() { return Array; } } let a = new MyArray(1,2,3); let mapped = a.map(x => x * x); console.log(mapped instanceof MyArray); // false console.log(mapped instanceof Array); // true ## Super class calls with `super` The [`super`](operators/super) keyword is used to call corresponding methods of super class. This is one advantage over prototype-based inheritance. class Cat { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } } class Lion extends Cat { speak() { super.speak(); console.log(`${this.name} roars.`); } } let l = new Lion('Fuzzy'); l.speak(); // Fuzzy makes a noise. // Fuzzy roars. ## Mix-ins Abstract subclasses or _mix-ins_ are templates for classes. An ECMAScript class can only have a single superclass, so multiple inheritance from tooling classes, for example, is not possible. The functionality must be provided by the superclass. A function with a superclass as input and a subclass extending that superclass as output can be used to implement mix-ins in ECMAScript: let calculatorMixin = Base => class extends Base { calc() { } }; let randomizerMixin = Base => class extends Base { randomize() { } }; A class that uses these mix-ins can then be written like this: class Foo { } class Bar extends calculatorMixin(randomizerMixin(Foo)) { } ## Re-running a class definition A class can't be redefined. Attempting to do so produces a `SyntaxError`. If you're experimenting with code in a web browser, such as the Firefox Web Console (**Tools** > **Web Developer** > **Web Console**) and you 'Run' a definition of a class with the same name twice, you'll get a `SyntaxError: redeclaration of let ClassName;`. (See further discussion of this issue in [bug 1428672](https://bugzilla.mozilla.org/show_bug.cgi?id=1428672).) Doing something similar in Chrome Developer Tools gives you a message like `Uncaught SyntaxError: Identifier 'ClassName' has already been declared at :1:1`. ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Class definitions' in that specification.
      `Classes` 49 42-49 Strict mode is required. 42-49 13 45 No 36 29-36 Strict mode is required. 29-36 9 49 42-49 Strict mode is required. 49 42-49 Strict mode is required. 42-49 45 36 29-36 Strict mode is required. 29-36 9 5.0 4.0-5.0 Strict mode is required. `constructor` 49 42-49 Strict mode is required. 42-49 13 45 No 36 29-36 Strict mode is required. 29-36 9 49 42-49 Strict mode is required. 49 42-49 Strict mode is required. 42-49 45 36 29-36 Strict mode is required. 29-36 9 5.0 4.0-5.0 Strict mode is required. `extends` 49 42-49 Strict mode is required. 42-49 13 45 No 36 29-36 Strict mode is required. 29-36 9 49 42-49 Strict mode is required. 49 42-49 Strict mode is required. 42-49 45 36 29-36 Strict mode is required. 29-36 9 5.0 4.0-5.0 Strict mode is required. `private_class_fields` 74 79 No Available only in nightly builds. See [bug 1562054](https://bugzil.la/1562054). No 62 14.1 74 74 No Available only in nightly builds. See [bug 1562054](https://bugzil.la/1562054). 53 14.5 No `public_class_fields` 72 79 69 No 60 14.1 14-14.1 Doesn't support public static fields. See WebKit bug [194095](https://webkit.org/b/194095). 72 72 79 51 14.5 14-14.5 Doesn't support public static fields. See WebKit bug [194095](https://webkit.org/b/194095). No `static` 49 42-49 Strict mode is required. 42-49 13 45 No 36 29-36 Strict mode is required. 29-36 14.1 49 42-49 Strict mode is required. 49 42-49 Strict mode is required. 42-49 45 36 29-36 Strict mode is required. 29-36 14.5 5.0 4.0-5.0 Strict mode is required. `static_class_fields` 72 79 75 No 60 14.1 72 72 79 51 14.5 No ## See also - Functions - [class declaration](statements/class) - [class expression](operators/class) - [Public class fields](classes/public_class_fields) - [Private class fields](classes/private_class_fields) - [`super`](operators/super) - [Blog post: "ES6 In Depth: Classes"](https://hacks.mozilla.org/2015/07/es6-in-depth-classes/) - [Fields and public/private class properties proposal (stage 3)](https://github.com/tc39/proposal-class-fields) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes # Set.prototype.clear() The `clear()` method removes all elements from a `Set` object. ## Syntax clear() ### Return value [`undefined`](../undefined). ## Examples ### Using the clear() method var mySet = new Set(); mySet.add(1); mySet.add('foo'); mySet.size; // 2 mySet.has('foo'); // true mySet.clear(); mySet.size; // 0 mySet.has('bar') // false ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-set.prototype.clear
      `clear` 38 12 19 11 25 8 38 38 19 25 8 3.0 ## See also - [`Set`](../set) - [`Set.prototype.delete()`](delete) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear # Math.clz32() The `Math.clz32()` function returns the number of leading zero bits in the 32-bit binary representation of a number. ## Syntax Math.clz32(x) ### Parameters `x` A number. ### Return value The number of leading zero bits in the 32-bit binary representation of the given number. ## Description "`clz32`" is short for **CountLeadingZeroes32**. If `x` is not a number, then it will be converted to a number first, then converted to a 32-bit unsigned integer. If the converted 32-bit unsigned integer is `0`, then return `32`, because all bits are `0`. This function is particularly useful for systems that compile to JS, like [Emscripten](https://developer.mozilla.org/en-US/docs/Emscripten). ### Count Leading Ones and beyond At present, there is no `Math.clon` for "Count Leading Ones" (named "clon", not "clo", because "clo" and "clz" are too similar especially for non-English-speaking people). However, a `clon` function can easily be created by inversing the bits of a number and passing the result to `Math.clz32`. Doing this will work because the inverse of 1 is 0 and vice-versa. Thus, inversing the bits will inverse the measured quantity of 0's (from `Math.clz32`), thereby making `Math.clz32` count the number of ones instead of counting the number of zeros. Consider the following 32-bit word: var a = 32776; // 00000000000000001000000000001000 (16 leading zeros) Math.clz32(a); // 16 var b = ~32776; // 11111111111111110111111111110111 (32776 inversed, 0 leading zeros) Math.clz32(b); // 0 (this is equal to how many leading one's there are in a) Using this logic, a `clon` function can be created as follows: var clz = Math.clz32; function clon(integer){ return clz(~integer); } Further, this technique could be extended to create jumpless "Count Trailing Zeros" and "Count Trailing Ones" functions as seen below. The `ctrz` function below fills in all the high bits with the lowest filled bit, then negates the bits to erase all higher set bits so that clz can then be used. var clz = Math.clz32; function ctrz(integer){ // count trailing zeros // 1. fill in all the higher bits after the first one integer |= integer << 16; integer |= integer << 8; integer |= integer << 4; integer |= integer << 2; integer |= integer << 1; // 2. Now, inversing the bits reveals the lowest bits return 32 - clz(~integer) |0; // `|0` ensures integer coercion } function ctron(integer){ // count trailing ones // No shift-filling-in-with-ones operator is available in // JavaScript, so the below code is the fastest return ctrz(~integer); /* Alternate implementation for demonstrational purposes: // 1. erase all the higher bits after the first zero integer &= (integer << 16) | 0xffff; integer &= (integer << 8 ) | 0x00ff; integer &= (integer << 4 ) | 0x000f; integer &= (integer << 2 ) | 0x0003; integer &= (integer << 1 ) | 0x0001; // 2. Now, inversing the bits reveals the lowest zeros return 32 - clon(~integer) |0; */ } Make these helper functions into ASM.JS module; then, you have a true performance masterpiece. Situations like these are exactly what ASM.JS was designed for. var countTrailsMethods = (function(stdlib, foreign, heap) { "use asm"; var clz = stdlib.Math.clz32; function ctrz(integer) { // count trailing zeros integer = integer | 0; // coerce to an integer // 1. fill in all the higher bits after the first one // ASMjs for some reason does not allow ^=,&=, or |= integer = integer | (integer << 16); integer = integer | (integer << 8); integer = integer | (integer << 4); integer = integer | (integer << 2); integer = integer | (integer << 1); // 2. Now, inversing the bits reveals the lowest bits return 32 - clz(~integer) |0; } function ctron(integer) { // count trailing ones integer = integer | 0; // coerce to an integer return ctrz(~integer) |0; } // unfourtunately, ASM.JS demands slow crummy objects: return {a: ctrz, b: ctron}; })(window, null, null); var ctrz = countTrailsMethods.a; var ctron = countTrailsMethods.b; ## Examples ### Using Math.clz32() Math.clz32(1); // 31 Math.clz32(1000); // 22 Math.clz32(); // 32 var stuff = [NaN, Infinity, -Infinity, 0, -0, false, null, undefined, 'foo', {}, []]; stuff.every(n => Math.clz32(n) == 32); // true Math.clz32(true); // 31 Math.clz32(3.5); // 30 ## Polyfill The following polyfill is the most efficient. if (!Math.clz32) Math.clz32 = (function(log, LN2){ return function(x) { // Let n be ToUint32(x). // Let p be the number of leading zero bits in // the 32-bit binary representation of n. // Return p. var asUint = x >>> 0; if (asUint === 0) { return 32; } return 31 - (log(asUint) / LN2 | 0) |0; // the "| 0" acts like math.floor }; })(Math.log, Math.LN2); ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.clz32
      `clz32` 38 12 31 No 25 7 38 38 31 25 7 3.0 ## See also - [`Math`](../math) - [`Math.imul`](imul) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 # String.prototype.codePointAt() The `codePointAt()` method returns a non-negative integer that is the UTF-16 code point value. ## Syntax codePointAt(pos) ### Parameters `pos` Position of an element in `str` to return the code point value from. ### Return value A number representing the code point value of the character at the given `pos`. If there is no element at `pos`, returns [`undefined`](../undefined). ## Description If there is no element at the specified position, [`undefined`](../undefined) is returned. If no UTF-16 surrogate pair begins at `pos`, the code unit at `pos` is returned. ## Examples ### Using codePointAt() 'ABC'.codePointAt(1) // 66 '\uD800\uDC00'.codePointAt(0) // 65536 'XYZ'.codePointAt(42) // undefined ### Looping with codePointAt() for (let codePoint of '\ud83d\udc0e\ud83d\udc71\u2764') { console.log(codePoint.codePointAt(0).toString(16)) } // '1f40e', '1f471', '2764' ## Polyfill The following extends Strings to include the `codePointAt()` function as specified in ECMAScript 2015 for browsers without native support. /*! https://mths.be/codepointat v0.2.0 by @mathias */ if (!String.prototype.codePointAt) { (function() { 'use strict'; // needed to support `apply`/`call` with `undefined`/`null` var defineProperty = (function() { // IE 8 only supports `Object.defineProperty` on DOM elements try { var object = {}; var $defineProperty = Object.defineProperty; var result = $defineProperty(object, object, object) && $defineProperty; } catch(error) {} return result; }()); var codePointAt = function(position) { if (this == null) { throw TypeError(); } var string = String(this); var size = string.length; // `ToInteger` var index = position ? Number(position) : 0; if (index != index) { // better `isNaN` index = 0; } // Account for out-of-bounds indices: if (index < 0 || index >= size) { return undefined; } // Get the first code unit var first = string.charCodeAt(index); var second; if ( // check if it's the start of a surrogate pair first >= 0xD800 && first <= 0xDBFF && // high surrogate size > index + 1 // there is a next code unit ) { second = string.charCodeAt(index + 1); if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; } } return first; }; if (defineProperty) { defineProperty(String.prototype, 'codePointAt', { 'value': codePointAt, 'configurable': true, 'writable': true }); } else { String.prototype.codePointAt = codePointAt; } }()); } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-string.prototype.codepointat
      `codePointAt` 41 12 29 No 28 10 41 41 29 28 10 4.0 ## See also - [`String.fromCodePoint()`](fromcodepoint) - [`String.fromCharCode()`](fromcharcode) - [`String.prototype.charCodeAt()`](charcodeat) - [`String.prototype.charAt()`](charat) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt # Intl.Locale.prototype.collation The `Intl.Locale.prototype.collation` property is an accessor property that returns the [collation type](https://www.unicode.org/reports/tr35/tr35-collation.html#CLDR_Collation) for the `Locale`, which is used to order strings according to the locale's rules. ## Description Collation is the process of ordering strings of characters. It is used whenever strings must be sorted and placed into a certain order, from search query results to ordering records in a database. While the idea of placing strings in order might seem trivial, the idea of order can vary from region to region and language to language. The `collation` property helps to make it easier for JavaScript programmers to access the collation type used by a particular locale. Below is a table with the available collation types, taken from the [Unicode collation specification](https://github.com/unicode-org/cldr/blob/2dd06669d833823e26872f249aa304bc9d9d2a90/common/bcp47/collation.xml). ### Valid collation types
      Collation TypeDescription
      big5hanPinyin ordering for Latin, big5 charset ordering for CJK characters (used in Chinese)
      compatA previous version of the ordering, for compatibility
      dictDictionary style ordering (such as in Sinhala)

      Warning: The direct collation type has been deprected. Do not use.

      direct

      Binary code point order (used in Hindi)
      ducetThe default Unicode collation element table order
      emojiRecommended ordering for emoji characters
      eorEuropean ordering rules
      gb2312Pinyin ordering for Latin, gb2312han charset ordering for CJK characters (used in Chinese)
      phonebkPhonebook style ordering (such as in German)
      phoneticPhonetic ordering (sorting based on pronunciation)
      pinyinPinyin ordering for Latin and for CJK characters (used in Chinese)
      reformedReformed ordering (such as in Swedish)
      searchSpecial collation type for string search
      searchjlSpecial collation type for Korean initial consonant search
      standardDefault ordering for each language
      strokePinyin ordering for Latin, stroke order for CJK characters (used in Chinese)
      tradTraditional style ordering (such as in Spanish)
      unihanPinyin ordering for Latin, Unihan radical-stroke ordering for CJK characters (used in Chinese)
      zhuyin

      Pinyin ordering for Latin, zhuyin order for Bopomofo and CJK characters (used in Chinese)

      ## Examples Like other locale subtags, the collation type can be added to the [`Intl.Locale`](../locale) object via the locale string, or a configuration object argument to the constructor. ### Adding a collation type via the locale string In the [Unicode locale string spec](https://www.unicode.org/reports/tr35/), collation types are locale key "extension subtags". These subtags add additional data about the locale, and are added to locale identifiers by using the `-u` extension. Thus, the collation type can be added to the initial locale identifier string that is passed into the [`Locale`](locale) constructor. To add the collation type, first add the `-u` extension to the string. Next, add the `-co` extension to indicate that you are adding a collation type. Finally, add the collation to the string. let stringColl = new Intl.Locale("en-Latn-US-u-co-emoji"); console.log(stringColl.collation); // Prints "emoji" ### Adding a collation type via the configuration object argument The [`Intl.Locale`](locale) constructor has an optional configuration object argument, which can contain any of several extension types, including collation types. Set the `collation` property of the configuration object to your desired collation type, and then pass it into the constructor. let configColl = new Intl.Locale("en-Latn-US", {collation: "emoji"}); console.log(configColl.collation); // Prints "emoji" ## Specifications
      Specification
      ECMAScript Internationalization API Specification (ECMAScript Internationalization API)
      #sec-Intl.Locale.prototype.collation
      `collation` 74 79 75 No 62 14 74 74 79 53 14 11.0 ## See also - [`Intl.Locale`](../locale) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/collation # Intl.Collator() constructor The `Intl.Collator()` constructor creates [`Intl.Collator`](../collator) objects that enable language-sensitive string comparison. ## Syntax new Intl.Collator() new Intl.Collator(locales) new Intl.Collator(locales, options) ### Parameters `locales` Optional Optional. A string with a BCP 47 language tag, or an array of such strings. For the general form and interpretation of the `locales` argument, see the [Intl page](../../intl#locale_identification_and_negotiation). The following Unicode extension keys are allowed: **Note:** These keys can usually also be set with `options` (as listed below). When both are set, the `options` property takes precedence. `co` Variant collations for certain locales. Possible values include: "`big5han`", "`dict`", "`direct`", "`ducet`", "`gb2312`", "`phonebk`", "`phonetic`", "`pinyin`", "`reformed`", "`searchjl`", "`stroke`", "`trad`", "`unihan`". This option can be also be set through the `options` property "`collation`". `kn` Whether numeric collation should be used, such that "1" < "2" < "10". Possible values are "`true`" and "`false`". This option can be also be set through the `options` property "`numeric`". `kf` Whether upper case or lower case should sort first. Possible values are "`upper`", "`lower`", or "`false`" (use the locale's default). This option can be also be set through the `options` property "`caseFirst`". `options` Optional An object with some or all of the following properties: `localeMatcher` The locale matching algorithm to use. Possible values are "`lookup`" and "`best fit`"; the default is "`best fit`". For information about this option, see the [Intl](../../intl#locale_negotiation) page. `usage` Whether the comparison is for sorting or for searching for matching strings. Possible values are "`sort`" and "`search`"; the default is "`sort`". `sensitivity` Which differences in the strings should lead to non-zero result values. Possible values are: - "`base`": Only strings that differ in base letters compare as unequal. Examples: a ≠ b, a = á, a = A. - "`accent`": Only strings that differ in base letters or accents and other diacritic marks compare as unequal. Examples: a ≠ b, a ≠ á, a = A. - "`case`": Only strings that differ in base letters or case compare as unequal. Examples: a ≠ b, a = á, a ≠ A. - "`variant`": Strings that differ in base letters, accents and other diacritic marks, or case compare as unequal. Other differences may also be taken into consideration. Examples: a ≠ b, a ≠ á, a ≠ A. The default is "`variant`" for usage "`sort`"; it's locale dependent for usage "`search`". `ignorePunctuation` Whether punctuation should be ignored. Possible values are `true` and `false`; the default is `false`. `numeric` Whether numeric collation should be used, such that "1" < "2" < "10". Possible values are `true` and `false`; the default is `false`. **Note:** This option can also be set through the `kn` Unicode extension key; if both are provided, this `options` property takes precedence. `caseFirst` Whether upper case or lower case should sort first. Possible values are "`upper`", "`lower`", or "`false`" (use the locale's default). This option can be set through an `options` property or through a Unicode extension key; if both are provided, the `options` property takes precedence. **Note:** This option can also be set through the `kf` Unicode extension key; if both are provided, this `options` property takes precedence. `collation` Variant collations for certain locales. Possible values include: "`big5han`", "`dict`", "`direct`", "`ducet`", "`gb2312`", "`phonebk`" (only supported in German), "`phonetic`", "`pinyin`", "`reformed`", "`searchjl`", "`stroke`", "`trad`", "`unihan`". **Note:** This option can also be set through the `co` Unicode extension key; if both are provided, this `options` property takes precedence. ## Examples ### Using Collator The following example demonstrates the different potential results for a string occurring before, after, or at the same level as another: console.log(new Intl.Collator().compare('a', 'c')); // → a negative value console.log(new Intl.Collator().compare('c', 'a')); // → a positive value console.log(new Intl.Collator().compare('a', 'a')); // → 0 Note that the results shown in the code above can vary between browsers and browser versions. This is because the values are implementation-specific. That is, the specification requires only that the before and after values are negative and positive. ## Specifications
      Specification
      ECMAScript Internationalization API Specification (ECMAScript Internationalization API)
      #sec-the-intl-collator-constructor
      `Collator` 24 12 29 11 15 10 4.4 25 56 14 10 1.5 `caseFirst` 24 18 55 No 15 11 4.4 25 56 14 11 1.5 `collation` 87 87 85 No 73 No 87 87 85 No No No ## See also - [`Intl.Collator`](../collator) - [`Intl`](../../intl) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator # Error.prototype.columnNumber **Non-standard** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future. The `columnNumber` property contains the column number in the line of the file that raised this error. ## Examples ### Using columnNumber var e = new Error('Could not parse input'); throw e; console.log(e.columnNumber) // 0 ## Specifications Not part of any standard. `columnNumber` No No 1 No No No No No 4 No No No ## See also - [`Error.prototype.stack`](stack) - [`Error.prototype.lineNumber`](linenumber) - [`Error.prototype.fileName`](filename) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/columnNumber # Comma operator (,) The **comma operator** (`,`) evaluates each of its operands (from left to right) and returns the value of the last operand. This lets you create a compound expression in which multiple expressions are evaluated, with the compound expression's final value being the value of the rightmost of its member expressions. This is commonly used to provide multiple parameters to a `for` loop. ## Syntax expr1, expr2, expr3... ### Parameters `expr1`, `expr2`, `expr3`... One or more expressions, the last of which is returned as the value of the compound expression. ## Usage notes You can use the comma operator when you want to include multiple expressions in a location that requires a single expression. The most common usage of this operator is to supply multiple parameters in a `for` loop. The comma operator is fully different from the comma within arrays, objects, and function arguments and parameters. ## Examples If `a` is a 2-dimensional array with 10 elements on each side, the following code uses the comma operator to increment `i` and decrement `j` at once. The following code prints the values of the diagonal elements in the array: for (var i = 0, j = 9; i <= 9; i++, j--) console.log('a[' + i + '][' + j + '] = ' + a[i][j]); Note that the comma operators in assignments may appear not to have the normal effect of comma operators because they don't exist within an expression. In the following example, `a` is set to the value of `b = 3` (which is 3), but the `c = 4` expression still evaluates and its result returned to console (i.e., 4). This is due to [operator precedence and associativity](operator_precedence). var a, b, c; a = b = 3, c = 4; // Returns 4 in console console.log(a); // 3 (left-most) var x, y, z; x = (y = 5, z = 6); // Returns 6 in console console.log(x); // 6 (right-most) ### Processing and then returning Another example that one could make with comma operator is processing before returning. As stated, only the last element will be returned but all others are going to be evaluated as well. So, one could do: function myFunc() { var x = 0; return (x += 1, x); // the same as return ++x; } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-comma-operator
      `Comma_Operator` 1 12 1 3 4 1 1 18 4 10.1 1 1.0 ## See also - [`for` loop](../statements/for) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator # Intl.Collator.prototype.compare() The `Intl.Collator.prototype.compare()` method compares two strings according to the sort order of this [`Intl/Collator`](../collator) object. ## Syntax compare(string1, string2) ### Parameters `string1` `string2` The strings to compare against each other. ## Description The `compare` getter function returns a number indicating how `string1` and `string2` compare to each other according to the sort order of this [`Intl/Collator`](../collator) object: a negative value if `string1` comes before `string2`; a positive value if `string1` comes after `string2`; 0 if they are considered equal. ## Examples ### Using compare for array sort Use the `compare` getter function for sorting arrays. Note that the function is bound to the collator from which it was obtained, so it can be passed directly to [`Array.prototype.sort()`](../../array/sort). var a = ['Offenbach', 'Österreich', 'Odenwald']; var collator = new Intl.Collator('de-u-co-phonebk'); a.sort(collator.compare); console.log(a.join(', ')); // → "Odenwald, Österreich, Offenbach" ### Using compare for array search Use the `compare` getter function for finding matching strings in arrays: var a = ['Congrès', 'congres', 'Assemblée', 'poisson']; var collator = new Intl.Collator('fr', { usage: 'search', sensitivity: 'base' }); var s = 'congres'; var matches = a.filter(v => collator.compare(v, s) === 0); console.log(matches.join(', ')); // → "Congrès, congres" ## Specifications
      Specification
      ECMAScript Internationalization API Specification (ECMAScript Internationalization API)
      #sec-intl.collator.prototype.compare
      `compare` 24 12 29 11 15 10 4.4 25 56 14 10 1.5 ## See also - [`Intl.Collator`](../collator) - [`String.prototype.localeCompare()`](../../string/localecompare) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/compare # Atomics.compareExchange() The static ` Atomics``.compareExchange() ` method exchanges a given replacement value at a given position in the array, if a given expected value equals the old value. It returns the old value at that position whether it was equal to the expected value or not. This atomic operation guarantees that no other write happens until the modified value is written back. ## Syntax Atomics.compareExchange(typedArray, index, expectedValue, replacementValue) ### Parameters `typedArray` An integer typed array. One of [`Int8Array`](../int8array), [`Uint8Array`](../uint8array), [`Int16Array`](../int16array), [`Uint16Array`](../uint16array), [`Int32Array`](../int32array), [`Uint32Array`](../uint32array), [`BigInt64Array`](../bigint64array), or [`BigUint64Array`](../biguint64array). `index` The position in the `typedArray` to exchange a `value`. `expectedValue` The value to check for equality. `replacementValue` The number to exchange. ### Return value The old value at the given position (`typedArray[index]`). ### Exceptions - Throws a [`TypeError`](../typeerror), if `typedArray` is not one of the allowed integer types. - Throws a [`RangeError`](../rangeerror), if `index` is out of bounds in the `typedArray`. ## Examples ### Using compareExchange() const sab = new SharedArrayBuffer(1024); const ta = new Uint8Array(sab); ta[0] = 7; Atomics.compareExchange(ta, 0, 7, 12); // returns 7, the old value Atomics.load(ta, 0); // 12 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-atomics.compareexchange
      `compareExchange` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. ## See also - [`Atomics`](../atomics) - [`Atomics.exchange()`](exchange) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/compareExchange # Comparing Reflect and Object methods The [`Reflect`](../reflect) object, introduced in ES2015, is a built-in object that provides methods to interface with JavaScript objects. Some of the static functions that exist on `Reflect` also correspond to methods available on [`Object`](../object), which predates ES2015. Although some of the methods appear to be similar in their behavior, there are often subtle differences between them. The table below details the differences between the methods available on the `Object` and `Reflect` APIs. Please note that if a method does not exist in an API, it is marked as N/A.
      Method NameObjectReflect
      defineProperty()Object.defineProperty() returns the object that was passed to the function. Returns a TypeError if the property was not successfully defined on the object.Reflect.defineProperty() returns true if the property was defined on the object and false if it was not.
      defineProperties()Object.defineProperties() returns the objects that were passed to the function. Returns a TypeError if any properties were not successfully defined on the object.N/A
      set()N/AReflect.set() returns true if the property was set successfully on the object and false if it was not. Throws a TypeError if the target was not an Object.
      get()N/AReflect.get() returns the value of the property. Throws a TypeError if the target was not an Object.
      deleteProperty()N/AReflect.deleteProperty() returns true if the property was deleted from the object and false if it was not.
      getOwnPropertyDescriptor()Object.getOwnPropertyDescriptor() returns a property descriptor of the given property if it exists on the object argument passed in, and returns undefined if it does not exist. However, if an object is not passed in as the first argument, it will be coerced into an object.Reflect.getOwnPropertyDescriptor() returns a property descriptor of the given property if it exists on the object. Returns undefined if it does not exist, and a TypeError if anything other than an object (a primitive) is passed in as the first argument.
      getOwnPropertyDescriptors()Object.getOwnPropertyDescriptors() returns an object containing a property descriptor of each passed-in object. Returns an empty object if the passed-in object has no owned property descriptors.N/A
      getPrototypeOf()Object.getPrototypeOf() returns the prototype of the given object. Returns null if there are no inherited properties. Throws a TypeError for non-objects in ES5, but coerces non-objects in ES2015.Reflect.getPrototypeOf() returns the prototype of the given object. Returns null if there are no inherited properties, and throws a TypeError for non-objects.
      setPrototypeOf()Object.setPrototypeOf() returns the object itself if its prototype was set successfully. Throws a TypeError if the prototype being set was anything other than an Object or null, or if the prototype for the object being modified is non-extensible.Reflect.setPrototypeOf() returns true if the prototype was successfully set on the object and false if it wasn't (including if the prototype is non-extensible). Throws a TypeError if the target passed in was not an Object, or if the prototype being set was anything other than an Object or null.
      isExtensible()Object.isExtensible() returns true if the object is extensible, and false if it is not. Throws a TypeError in ES5 if the first argument is not an object (a primitive). In ES2015, it will be coerced into a non-extensible, ordinary object and will return false.

      Reflect.isExtensible() returns true if the object is extensible, and false if it is not. Throws a TypeError if the first argument is not an object (a primitive).

      preventExtensions()

      Object.preventExtensions() returns the object that is being made non-extensible. Throws a TypeErrorin ES5 if the argument is not an object (a primitive). In ES2015, treats the argument as a non-extensible, ordinary object and returns the object itself.

      Reflect.preventExtensions() returns true if the object has been made non-extensible, and false if it has not. Throws a TypeError if the argument is not an object (a primitive).
      keys()Object.keys() returns an Array of strings that map to the target object's own (enumerable) property keys. Throws a TypeError in ES5 if the target is not an object, but coerces non-object targets into objects in ES2015.N/A
      ownKeys()N/AReflect.ownKeys() returns an Array of property names that map to the target object's own property keys. Throws a TypeError if the target is not an Object.
      © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/Comparing_Reflect_and_Object_methods # WebAssembly.compile() The `WebAssembly.compile()` function compiles WebAssembly binary code into a [`WebAssembly.Module`](module) object. This function is useful if it is necessary to a compile a module before it can be instantiated (otherwise, the [`WebAssembly.instantiate()`](instantiate) function should be used). ## Syntax WebAssembly.compile(bufferSource) ### Parameters _bufferSource_ A [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) or [ArrayBuffer](../arraybuffer) containing the binary code of the .wasm module you want to compile. ### Return value A `Promise` that resolves to a [`WebAssembly.Module`](module) object representing the compiled module. ### Exceptions - If `bufferSource` is not a [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays), a [`TypeError`](../typeerror) is thrown. - If compilation fails, the promise rejects with a [`WebAssembly.CompileError`](compileerror). ## Examples ### Using compile The following example compiles the loaded simple.wasm byte code using the `compile()` function and then sends it to a [worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) using [postMessage()](https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage). var worker = new Worker("wasm_worker.js"); fetch('simple.wasm').then(response => response.arrayBuffer() ).then(bytes => WebAssembly.compile(bytes) ).then(mod => worker.postMessage(mod) ); **Note:** You'll probably want to use [`WebAssembly.compileStreaming()`](compilestreaming) in most cases, as it is more efficient than `compile()`. ## Specifications
      Specification
      WebAssembly JavaScript Interface (WebAssembly JavaScript Interface)
      #dom-webassembly-compile
      `compile` 57 16 52 Disabled in the Firefox 52 Extended Support Release (ESR). No 44 11 57 57 52 Disabled in the Firefox 52 Extended Support Release (ESR). 43 11 7.0 ## See also - [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) overview page - [WebAssembly concepts](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts) - [Using the WebAssembly JavaScript API](https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compile # WebAssembly.CompileError The `WebAssembly.CompileError` object indicates an error during WebAssembly decoding or validation. ## Constructor [`WebAssembly.CompileError()`](compileerror/compileerror) Creates a new `WebAssembly.CompileError` object. ## Instance properties [`WebAssembly.CompileError.prototype.message`](../error/message) Error message. Although ECMA-262 specifies that [`URIError`](../urierror) should provide its own `message` property, in [SpiderMonkey](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey), it inherits [`Error.prototype.message`](../error/message). [`WebAssembly.CompileError.prototype.name`](../error/name) Error name. Inherited from [`Error`](../error). [`WebAssembly.CompileError.prototype.fileName`](../error/filename) Path to file that raised this error. Inherited from [`Error`](../error). [`WebAssembly.CompileError.prototype.lineNumber`](../error/linenumber) Line number in file that raised this error. Inherited from [`Error`](../error). [`WebAssembly.CompileError.prototype.columnNumber`](../error/columnnumber) Column number in line that raised this error. Inherited from [`Error`](../error). [`WebAssembly.CompileError.prototype.stack`](../error/stack) Stack trace. Inherited from [`Error`](../error). ## Instance methods [`WebAssembly.CompileError.prototype.toSource()`](../error/tosource) Returns code that could eval to the same error. Inherited from [`Error`](../error). [`WebAssembly.CompileError.prototype.toString()`](../error/tostring) Returns a string representing the specified `Error` object.. Inherited from [`Error`](../error). ## Examples ### Creating a new CompileError instance The following snippet creates a new `CompileError` instance, and logs its details to the console: try { throw new WebAssembly.CompileError('Hello', 'someFile', 10); } catch (e) { console.log(e instanceof CompileError); // true console.log(e.message); // "Hello" console.log(e.name); // "CompileError" console.log(e.fileName); // "someFile" console.log(e.lineNumber); // 10 console.log(e.columnNumber); // 0 console.log(e.stack); // returns the location where the code was run } ## Specifications
      Specification
      WebAssembly JavaScript Interface (WebAssembly JavaScript Interface)
      #exceptiondef-compileerror
      ECMAScript Language Specification (ECMAScript)
      #sec-native-error-types-used-in-this-standard
      `CompileError` 57 16 52 Disabled in the Firefox 52 Extended Support Release (ESR). No 44 11 57 57 52 Disabled in the Firefox 52 Extended Support Release (ESR). 43 11 7.0 `CompileError` 57 16 52 Disabled in the Firefox 52 Extended Support Release (ESR). No 44 11 57 57 52 Disabled in the Firefox 52 Extended Support Release (ESR). 43 11 7.0 ## See also - [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) overview page - [WebAssembly concepts](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts) - [Using the WebAssembly JavaScript API](https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError # WebAssembly.compileStreaming() The `WebAssembly.compileStreaming()` function compiles a [`WebAssembly.Module`](module) directly from a streamed underlying source. This function is useful if it is necessary to a compile a module before it can be instantiated (otherwise, the [`WebAssembly.instantiateStreaming()`](instantiatestreaming) function should be used). ## Syntax WebAssembly.compileStreaming(source) ### Parameters _source_ A [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object or a promise that will fulfill with one, representing the underlying source of a .wasm module you want to stream and compile. ### Return value A `Promise` that resolves to a [`WebAssembly.Module`](module) object representing the compiled module. ### Exceptions - If `bufferSource` is not a [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays), a [`TypeError`](../typeerror) is thrown. - If compilation fails, the promise rejects with a [`WebAssembly.CompileError`](compileerror). ## Examples ### Compile streaming The following example (see our [compile-streaming.html](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/compile-streaming.html) demo on GitHub, and [view it live](https://mdn.github.io/webassembly-examples/js-api-examples/compile-streaming.html) also) directly streams a .wasm module from an underlying source then compiles it to a [`WebAssembly.Module`](module) object. Because the `compileStreaming()` function accepts a promise for a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object, you can directly pass it a [`WindowOrWorkerGlobalScope.fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch) call, and it will pass the response into the function when it fulfills. var importObject = { imports: { imported_func: arg => console.log(arg) } }; WebAssembly.compileStreaming(fetch('simple.wasm')) .then(module => WebAssembly.instantiate(module, importObject)) .then(instance => instance.exports.exported_func()); The resulting module instance is then instantiated using [`WebAssembly.instantiate()`](instantiate), and the exported function invoked. ## Specifications
      Specification
      WebAssembly Web API (WebAssembly Web API)
      #dom-webassembly-compilestreaming
      `compileStreaming` 61 16 58 No 47 No 61 61 58 45 No 8.0 ## See also - [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) overview page - [WebAssembly concepts](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts) - [Using the WebAssembly JavaScript API](https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming # Array.prototype.concat() The `concat()` method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array. ## Syntax concat() concat(value0) concat(value0, value1) concat(value0, value1, ... , valueN) ### Parameters `valueN` Optional Arrays and/or values to concatenate into a new array. If all `valueN` parameters are omitted, `concat` returns a shallow copy of the existing array on which it is called. See the description below for more details. ### Return value A new [`Array`](../array) instance. ## Description The `concat` method creates a new array consisting of the elements in the object on which it is called, followed in order by, for each argument, the elements of that argument (if the argument is an array) or the argument itself (if the argument is not an array). It does not recurse into nested array arguments. The `concat` method does not alter `this` or any of the arrays provided as arguments but instead returns a shallow copy that contains copies of the same elements combined from the original arrays. Elements of the original arrays are copied into the new array as follows: - Object references (and not the actual object): `concat` copies object references into the new array. Both the original and new array refer to the same object. That is, if a referenced object is modified, the changes are visible to both the new and original arrays. This includes elements of array arguments that are also arrays. - Data types such as strings, numbers and booleans (not [`String`](../string), [`Number`](../number), and [`Boolean`](../boolean) objects): `concat` copies the values of strings and numbers into the new array. **Note:** Concatenating array(s)/value(s) will leave the originals untouched. Furthermore, any operation on the new array (except operations on elements which are object references) will have no effect on the original arrays, and vice versa. ## Examples ### Concatenating two arrays The following code concatenates two arrays: const letters = ['a', 'b', 'c']; const numbers = [1, 2, 3]; letters.concat(numbers); // result in ['a', 'b', 'c', 1, 2, 3] ### Concatenating three arrays The following code concatenates three arrays: const num1 = [1, 2, 3]; const num2 = [4, 5, 6]; const num3 = [7, 8, 9]; const numbers = num1.concat(num2, num3); console.log(numbers); // results in [1, 2, 3, 4, 5, 6, 7, 8, 9] ### Concatenating values to an array The following code concatenates three values to an array: const letters = ['a', 'b', 'c']; const alphaNumeric = letters.concat(1, [2, 3]); console.log(alphaNumeric); // results in ['a', 'b', 'c', 1, 2, 3] ### Concatenating nested arrays The following code concatenates nested arrays and demonstrates retention of references: const num1 = [[1]]; const num2 = [2, [3]]; const numbers = num1.concat(num2); console.log(numbers); // results in [[1], 2, [3]] // modify the first element of num1 num1[0].push(4); console.log(numbers); // results in [[1, 4], 2, [3]] ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-array.prototype.concat
      `concat` 1 12 1 5.5 4 1 1 18 4 10.1 1 1.0 ## See also - [`push`](push) / [`pop`](pop) — add/remove elements from the end of the array - [`unshift`](unshift) / [`shift`](shift) — add/remove elements from the beginning of the array - [`splice`](splice) — add/remove elements from the specified location of the array - [`String.prototype.concat()`](../string/concat) - [`Symbol.isConcatSpreadable`](../symbol/isconcatspreadable) – control flattening. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat # Conditional (ternary) operator The **conditional (ternary) operator** is the only JavaScript operator that takes three operands: a condition followed by a question mark (`?`), then an expression to execute if the condition is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) followed by a colon (`:`), and finally the expression to execute if the condition is [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy). This operator is frequently used as a shortcut for the [`if`](../statements/if...else) statement. ## Syntax condition ? exprIfTrue : exprIfFalse ### Parameters `condition` An expression whose value is used as a condition. `exprIfTrue` An expression which is evaluated if the `condition` evaluates to a [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) value (one which equals or can be converted to `true`). `exprIfFalse` An expression which is executed if the `condition` is [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) (that is, has a value which can be converted to `false`). ## Description Besides `false`, possible falsy expressions are: `null`, `NaN`, `0`, the empty string (`""`), and `undefined`. If `condition` is any of these, the result of the conditional expression will be the result of executing the expression `exprIfFalse`. ## Examples ### A simple example var age = 26; var beverage = (age >= 21) ? "Beer" : "Juice"; console.log(beverage); // "Beer" ### Handling null values One common usage is to handle a value that may be `null`: let greeting = person => { let name = person ? person.name : `stranger` return `Howdy, ${name}` } console.log(greeting({name: `Alice`})); // "Howdy, Alice" console.log(greeting(null)); // "Howdy, stranger" ### Conditional chains The ternary operator is right-associative, which means it can be "chained" in the following way, similar to an `if … else if … else if … else` chain: function example(…) { return condition1 ? value1 : condition2 ? value2 : condition3 ? value3 : value4; } // Equivalent to: function example(…) { if (condition1) { return value1; } else if (condition2) { return value2; } else if (condition3) { return value3; } else { return value4; } } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-conditional-operator
      `Conditional_Operator` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [if statement](../statements/if...else) - [Nullish coalescing operator](nullish_coalescing_operator) - [Optional chaining](optional_chaining) - [Making decisions in your code — conditionals](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/conditionals) - [Expressions and operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator # const Constants are block-scoped, much like variables declared using the `let` keyword. The value of a constant can't be changed through reassignment, and it can't be redeclared. ## Syntax const name1 = value1 [, name2 = value2 [, ... [, nameN = valueN]]]; `nameN` The constant's name, which can be any legal [identifier](https://developer.mozilla.org/en-US/docs/Glossary/Identifier). `valueN` The constant's value. This can be any legal [expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#expressions), including a function expression. The [Destructuring Assignment](../operators/destructuring_assignment) syntax can also be used to declare variables. const { bar } = foo; // where foo = { bar:10, baz:12 }; /* This creates a constant with the name 'bar', which has a value of 10 */ ## Description This declaration creates a constant whose scope can be either global or local to the block in which it is declared. Global constants do **not** become properties of the [`window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) object, unlike [`var`](var) variables. An initializer for a constant is required. You must specify its value in the same statement in which it's declared. (This makes sense, given that it can't be changed later.) The `const` creates a read-only reference to a value. It does **not** mean the value it holds is immutable—just that the variable identifier cannot be reassigned. For instance, in the case where the content is an object, this means the object's contents (e.g., its properties) can be altered. All the considerations about the "[temporal dead zone](let#temporal_dead_zone_tdz)" apply to both [`let`](let) and `const`. A constant cannot share its name with a function or a variable in the same scope. ## Examples ### Basic const usage Constants can be declared with uppercase or lowercase, but a common convention is to use all-uppercase letters. // define MY_FAV as a constant and give it the value 7 const MY_FAV = 7; // this will throw an error - Uncaught TypeError: Assignment to constant variable. MY_FAV = 20; // MY_FAV is 7 console.log('my favorite number is: ' + MY_FAV); // trying to redeclare a constant throws an error // Uncaught SyntaxError: Identifier 'MY_FAV' has already been declared const MY_FAV = 20; // the name MY_FAV is reserved for constant above, so this will fail too var MY_FAV = 20; // this throws an error too let MY_FAV = 20; ### Block scoping It's important to note the nature of block scoping. if (MY_FAV === 7) { // this is fine and creates a block scoped MY_FAV variable // (works equally well with let to declare a block scoped non const variable) let MY_FAV = 20; // MY_FAV is now 20 console.log('my favorite number is ' + MY_FAV); // this gets hoisted into the global context and throws an error var MY_FAV = 20; } // MY_FAV is still 7 console.log('my favorite number is ' + MY_FAV); ### const needs to be initialized // throws an error // Uncaught SyntaxError: Missing initializer in const declaration const FOO; ### const in objects and arrays const also works on objects and arrays. const MY_OBJECT = {'key': 'value'}; // Attempting to overwrite the object throws an error // Uncaught TypeError: Assignment to constant variable. MY_OBJECT = {'OTHER_KEY': 'value'}; // However, object keys are not protected, // so the following statement is executed without problem MY_OBJECT.key = 'otherValue'; // Use Object.freeze() to make object immutable // The same applies to arrays const MY_ARRAY = []; // It's possible to push items into the array MY_ARRAY.push('A'); // ["A"] // However, assigning a new array to the variable throws an error // Uncaught TypeError: Assignment to constant variable. MY_ARRAY = ['B']; ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-let-and-const-declarations
      `const` 21 12 36 \["Prior to Firefox 13, `const` is implemented, but re-assignment is not failing.", "Prior to Firefox 46, a `TypeError` was thrown on redeclaration instead of a `SyntaxError`."\] 11 9 5.1 ≤37 25 36 \["Prior to Firefox 13, `const` is implemented, but re-assignment is not failing.", "Prior to Firefox 46, a `TypeError` was thrown on redeclaration instead of a `SyntaxError`."\] 10.1 6 1.5 ## See also - [`var`](var) - [`let`](let) - [Constants in the JavaScript Guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#constants) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const # Reflect.construct() The static `Reflect.construct()` method acts like the [`new`](../../operators/new) operator, but as a function. It is equivalent to calling `new target(...args)`. It gives also the added option to specify a different prototype. ## Syntax Reflect.construct(target, argumentsList) Reflect.construct(target, argumentsList, newTarget) ### Parameters `target` The target function to call. `argumentsList` An array-like object specifying the arguments with which `target` should be called. `newTarget` Optional The constructor whose prototype should be used. See also the [`new.target`](../../operators/new.target) operator. If `newTarget` is not present, its value defaults to `target`. ### Return value A new instance of `target` (or `newTarget`, if present), initialized by `target` as a constructor with the given `argumentsList`. ### Exceptions A [`TypeError`](../typeerror), if `target` or `newTarget` are not constructors. ## Description `Reflect.construct()` allows you to invoke a constructor with a variable number of arguments. (This would also be possible by using the [spread syntax](../../operators/spread_syntax) combined with the [`new` operator](../../operators/new).) let obj = new Foo(...args) let obj = Reflect.construct(Foo, args) ### `Reflect.construct()` vs `Object.create()` Prior to the introduction of `Reflect`, objects could be constructed using an arbitrary combination of constructor and prototype by using [`Object.create()`](../object/create). function OneClass() { this.name = 'one' } function OtherClass() { this.name = 'other' } // Calling this: let obj1 = Reflect.construct(OneClass, args, OtherClass) // ...has the same result as this: let obj2 = Object.create(OtherClass.prototype) OneClass.apply(obj2, args) console.log(obj1.name) // 'one' console.log(obj2.name) // 'one' console.log(obj1 instanceof OneClass) // false console.log(obj2 instanceof OneClass) // false console.log(obj1 instanceof OtherClass) // true console.log(obj2 instanceof OtherClass) // true //Another example to demonstrate below: function func1(a, b, c, d) { console.log(arguments[3]); } function func2(d, e, f, g) { console.log(arguments[3]); } let obj1 = Reflect.construct(func1, ['I', 'Love', 'my', 'India']) obj1 However, while the end result is the same, there is one important difference in the process. When using `Object.create()` and [`Function.prototype.apply()`](../function/apply), the `new.target` operator will point to `undefined` within the function used as the constructor, since the `new` keyword is not being used to create the object. When invoking `Reflect.construct()`, on the other hand, the `new.target` operator will point to the `newTarget` parameter if supplied, or `target` if not. function OneClass() { console.log('OneClass') console.log(new.target) } function OtherClass() { console.log('OtherClass') console.log(new.target) } let obj1 = Reflect.construct(OneClass, args) // Output: // OneClass // function OneClass { ... } let obj2 = Reflect.construct(OneClass, args, OtherClass) // Output: // OneClass // function OtherClass { ... } let obj3 = Object.create(OtherClass.prototype); OneClass.apply(obj3, args) // Output: // OneClass // undefined ## Examples ### Using `Reflect.construct()` let d = Reflect.construct(Date, [1776, 6, 4]) d instanceof Date // true d.getFullYear() // 1776 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-reflect.construct
      `construct` 49 12 42 No 36 10 49 49 42 36 10 5.0 ## See also - [`Reflect`](../reflect) - [`new`](../../operators/new) - `new.target` © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/construct # Object.prototype.constructor The `constructor` property returns a reference to the [`Object`](../object) constructor function that created the instance object. Note that the value of this property is a reference to _the function itself_, not a string containing the function's name. The value is only read-only for primitive values such as `1`, `true`, and `"test"`. ## Description All objects (with the exception of objects created with `Object.create(null)`) will have a `constructor` property. Objects created without the explicit use of a constructor function (such as object- and array-literals) will have a `constructor` property that points to the Fundamental Object constructor type for that object. let o = {} o.constructor === Object // true let o = new Object o.constructor === Object // true let a = [] a.constructor === Array // true let a = new Array a.constructor === Array // true let n = new Number(3) n.constructor === Number // true ## Examples ### Displaying the constructor of an object The following example creates a constructor (`Tree`) and an object of that type (`theTree`). The example then displays the `constructor` property for the object `theTree`. function Tree(name) { this.name = name } let theTree = new Tree('Redwood') console.log('theTree.constructor is ' + theTree.constructor) This example displays the following output: theTree.constructor is function Tree(name) { this.name = name } ### Changing the constructor of an object One can assign the `constructor` property for any value except `null` and `undefined` since those don't have a corresponding constructor function (like `String`, `Number`, `Boolean` etc.), but values which are primitives won't keep the change (with no exception thrown). This is due to the same mechanism, which allows one to set any property on primitive values (except `null` and `undefined`) with no effect. Namely whenever one uses such a primitive as an object an instance of the corresponding constructor is created and discarded right after the statement was executed. let val = null; val.constructor = 1; //TypeError: var is null val = 'abc'; val.constructor = Number; //val.constructor === String val.foo = 'bar'; //An implicit instance of String('abc') was created and assigned the prop foo val.foo === undefined; //true, since a new instance of String('abc') was created for this comparison, which doesn't have the foo property So basically one can change the value of the `constructor` property for anything, except the primitives mentioned above, **note that changing the** `constructor` **property does not affect the instanceof operator**: let a = []; a.constructor = String a.constructor === String // true a instanceof String //false a instanceof Array //true a = new Foo(); a.constructor = 'bar' a.constructor === 'bar' // true //etc. If the object is sealed/frozen then the change has no effect and no exception is thrown: let a = Object.seal({}); a.constructor = Number; a.constructor === Object; //true ### Changing the constructor of a function Mostly this property is used for defining a function as a **function-constructor** with further calling it with **new** and prototype-inherits chain. function Parent() { /* ... */ } Parent.prototype.parentMethod = function parentMethod() {} function Child() { Parent.call(this) // Make sure everything is initialized properly } Child.prototype = Object.create(Parent.prototype) // re-define child prototype to Parent prototype Child.prototype.constructor = Child // return original constructor to Child But when do we need to perform the last line here? Unfortunately, the answer is: _it depends_. Let's try to define the cases in which re-assignment of the original constructor will play a major role, and when it will be one superfluous line of code. Take the following case: the object has the `create()` method to create itself. function Parent() { /* ... */ } function CreatedConstructor() { Parent.call(this) } CreatedConstructor.prototype = Object.create(Parent.prototype) CreatedConstructor.prototype.create = function create() { return new this.constructor() } new CreatedConstructor().create().create() // TypeError undefined is not a function since constructor === Parent In the example above the exception will be shown since the constructor links to Parent. To avoid this, just assign the necessary constructor you are going to use. function Parent() { /* ... */ } function CreatedConstructor() { /* ... */ } CreatedConstructor.prototype = Object.create(Parent.prototype) CreatedConstructor.prototype.constructor = CreatedConstructor // sets the correct constructor for future use CreatedConstructor.prototype.create = function create() { return new this.constructor() } new CreatedConstructor().create().create() // it's pretty fine Ok, now it's pretty clear why changing the constructor can be useful. Let's consider one more case. function ParentWithStatic() {} ParentWithStatic.startPosition = { x: 0, y:0 } // Static member property ParentWithStatic.getStartPosition = function getStartPosition() { return this.startPosition } function Child(x, y) { this.position = { x: x, y: y } } Child = Object.assign(Child, ParentWithStatic) // copies over the static members from ParentWithStatic to Child Child.prototype = Object.create(ParentWithStatic.prototype) Child.prototype.constructor = Child Child.prototype.getOffsetByInitialPosition = function getOffsetByInitialPosition() { let position = this.position let startPosition = this.constructor.getStartPosition() // error undefined is not a function, since the constructor is Child return { offsetX: startPosition.x - position.x, offsetY: startPosition.y - position.y } }; For this example we need either to stay parent constructor to continue to work properly or reassign static properties to child's constructor: ... Child = Object.assign(Child, ParentWithStatic) // Notice that we assign it before we create(...) a prototype below Child.prototype = Object.create(ParentWithStatic.prototype) ... or assign parent constructor identifier to a separate property on the Child constructor function and access it via that property: ... Child.parentConstructor = ParentWithStatic Child.prototype = Object.create(ParentWithStatic.prototype) ... let startPosition = this.constructor.parentConstructor.getStartPosition() ... **Note:** Manually updating or setting the constructor can lead to different and sometimes confusing consequences. To prevent this, just define the role of `constructor` in each specific case. In most cases, `constructor` is not used and reassignment of it is not necessary. ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Object.prototype.constructor' in that specification.
      `constructor` 1 12 1 8 4 1 1 18 4 10.1 1 1.0 ## See also - [Class declaration](../../statements/class) - [Class constructor](../../classes/constructor) - Glossary: [constructor](https://developer.mozilla.org/en-US/docs/Glossary/Constructor) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor # continue The `continue` terminates execution of the statements in the current iteration of the current or labeled loop, and continues execution of the loop with the next iteration. ## Syntax continue [label]; `label` Identifier associated with the label of the statement. ## Description In contrast to the [`break`](break) statement, `continue` does not terminate the execution of the loop entirely: instead, - In a [`while`](while) loop, it jumps back to the condition. - In a [`for`](for) loop, it jumps to the update expression. The `continue` statement can include an optional label that allows the program to jump to the next iteration of a labeled loop statement instead of the current loop. In this case, the `continue` statement needs to be nested within this labeled statement. ## Examples ### Using continue with while The following example shows a [`while`](while) loop that has a `continue` statement that executes when the value of `i` is 3. Thus, `n` takes on the values 1, 3, 7, and 12. var i = 0; var n = 0; while (i < 5) { i++; if (i === 3) { continue; } n += i; } ### Using continue with a label In the following example, a statement labeled `checkiandj` contains a statement labeled `checkj`. If `continue` is encountered, the program continues at the top of the `checkj` statement. Each time `continue` is encountered, `checkj` reiterates until its condition returns false. When false is returned, the remainder of the `checkiandj` statement is completed. If `continue` had a label of `checkiandj`, the program would continue at the top of the `checkiandj` statement. See also [label](label). var i = 0; var j = 8; checkiandj: while (i < 4) { console.log('i: ' + i); i += 1; checkj: while (j > 4) { console.log('j: ' + j); j -= 1; if ((j % 2) == 0) continue checkj; console.log(j + ' is odd.'); } console.log('i = ' + i); console.log('j = ' + j); } Output: i: 0 // start checkj j: 8 7 is odd. j: 7 j: 6 5 is odd. j: 5 // end checkj i = 1 j = 4 i: 1 i = 2 j = 4 i: 2 i = 3 j = 4 i: 3 i = 4 j = 4 ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Continue statement' in that specification.
      `continue` 1 12 1 3 4 1 1 18 4 10.1 1 1.0 ## See also - [`break`](break) - [label](label) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue # Array.prototype.copyWithin() The `copyWithin()` method shallow copies part of an array to another location in the same array and returns it without modifying its length. ## Syntax copyWithin(target) copyWithin(target, start) copyWithin(target, start, end) ### Parameters `target` Zero-based index at which to copy the sequence to. If negative, `target` will be counted from the end. If `target` is at or greater than `arr.length`, nothing will be copied. If `target` is positioned after `start`, the copied sequence will be trimmed to fit `arr.length`. `start` Optional Zero-based index at which to start copying elements from. If negative, `start` will be counted from the end. If `start` is omitted, `copyWithin` will copy from index `0`. `end` Optional Zero-based index at which to end copying elements from. `copyWithin` copies up to but not including `end`. If negative, `end` will be counted from the end. If `end` is omitted, `copyWithin` will copy until the last index (default to `arr.length`). ### Return value The modified array. ## Description The `copyWithin` works like C and C++'s `memmove`, and is a high-performance method to shift the data of an [`Array`](../array). This especially applies to the [`TypedArray`](../typedarray/copywithin) method of the same name. The sequence is copied and pasted as one operation; pasted sequence will have the copied values even when the copy and paste region overlap. The `copyWithin` function is intentionally _generic_, it does not require that its `this` value be an [`Array`](../array) object. The `copyWithin` method is a mutable method. It does not alter the length of `this`, but it will change its content and create new properties, if necessary. ## Examples ### Using copyWithin [1, 2, 3, 4, 5].copyWithin(-2) // [1, 2, 3, 1, 2] [1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5] [1, 2, 3, 4, 5].copyWithin(0, 3, 4) // [4, 2, 3, 4, 5] [1, 2, 3, 4, 5].copyWithin(-2, -3, -1) // [1, 2, 3, 3, 4] [].copyWithin.call({length: 5, 3: 1}, 0, 3) // {0: 1, 3: 1, length: 5} // ES2015 Typed Arrays are subclasses of Array var i32a = new Int32Array([1, 2, 3, 4, 5]) i32a.copyWithin(0, 2) // Int32Array [3, 4, 5, 4, 5] // On platforms that are not yet ES2015 compliant: [].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4); // Int32Array [4, 2, 3, 4, 5] ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-array.prototype.copywithin
      `copyWithin` 45 12 32 No 32 9 45 45 32 32 9 5.0 ## See also - [A polyfill](https://github.com/behnammodi/polyfill/blob/master/array.polyfill.js) - [`Array`](../array) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin # Math.cos() The `Math.cos()` static function returns the [cosine](https://en.wikipedia.org/wiki/Cosine) of the specified angle, which must be specified in [radians](https://en.wikipedia.org/wiki/Radians). ## Syntax Math.cos(x) ### Parameters `x` The angle in radians for which to return the cosine. ### Return value The cosine of the given number. ## Description The `Math.cos()` method returns a numeric value between -1 and 1, which represents the cosine of the angle. Because `cos()` is a static method of `Math`, you always use it as `Math.cos()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.cos() Math.cos(0); // 1 Math.cos(1); // 0.5403023058681398 Math.cos(Math.PI); // -1 Math.cos(2 * Math.PI); // 1 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.cos
      `cos` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`Math.acos()`](acos) - [`Math.asin()`](asin) - [`Math.atan()`](atan) - [`Math.atan2()`](atan2) - [`Math.sin()`](sin) - [`Math.tan()`](tan) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos # Math.cosh() The `Math.cosh()` function returns the hyperbolic cosine of a number, that can be expressed using the [constant e](e): $$\\mathtt{\\operatorname{Math.cosh(x)}} = \\frac{e^{x} + e^{- x}}{2}$$ ## Syntax Math.cosh(x) ### Parameters `x` A number. ### Return value The hyperbolic cosine of the given number. ## Description Because `cosh()` is a static method of `Math`, you always use it as `Math.cosh()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.cosh() Math.cosh(0); // 1 Math.cosh(1); // 1.5430806348152437 Math.cosh(-1); // 1.5430806348152437 ## Polyfill This can be emulated with the help of the [`Math.exp()`](exp) function: Math.cosh = Math.cosh || function(x) { return (Math.exp(x) + Math.exp(-x)) / 2; } or using only one call to the [`Math.exp()`](exp) function: Math.cosh = Math.cosh || function(x) { var y = Math.exp(x); return (y + 1 / y) / 2; }; ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.cosh
      `cosh` 38 12 25 No 25 8 38 38 25 25 8 3.0 ## See also - [`Math.acosh()`](acosh) - [`Math.asinh()`](asinh) - [`Math.atanh()`](atanh) - [`Math.sinh()`](sinh) - [`Math.tanh()`](tanh) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh # Object.create() The `Object.create()` method creates a new object, using an existing object as the prototype of the newly created object. ## Syntax Object.create(proto) Object.create(proto, propertiesObject) ### Parameters `proto` The object which should be the prototype of the newly-created object. `propertiesObject` Optional If specified and not [`undefined`](../undefined), an object whose enumerable own properties (that is, those properties defined upon itself and _not_ enumerable properties along its prototype chain) specify property descriptors to be added to the newly-created object, with the corresponding property names. These properties correspond to the second argument of [`Object.defineProperties()`](defineproperties). ### Return value A new object with the specified prototype object and properties. ### Exceptions The `proto` parameter has to be either - [`null`](../null) or - an [`Object`](../object) excluding [primitive wrapper objects](https://developer.mozilla.org/en-US/docs/Glossary/Primitive#primitive_wrapper_objects_in_javascript). If `proto` is neither of these a [`TypeError`](../typeerror) is thrown. ## Custom and Null objects A new object created from a completely custom object (especially one created from the `null` object, which is basically a custom object with NO members) can behave in unexpected ways. This is especially true when debugging, since common object-property converting/detecting utility functions may generate errors, or lose information (especially if using silent error-traps that ignore errors). For example, here are two objects: oco = Object.create( {} ); // create a normal object ocn = Object.create( null ); // create a "null" object > console.log(oco) // {} -- Seems normal > console.log(ocn) // {} -- Seems normal here too, so far oco.p = 1; // create a simple property on normal obj ocn.p = 0; // create a simple property on "null" obj > console.log(oco) // {p: 1} -- Still seems normal > console.log(ocn) // {p: 0} -- Still seems normal here too. BUT WAIT... As shown above, all seems normal so far. However, when attempting to actually use these objects, their differences quickly become apparent: > "oco is: " + oco // shows "oco is: [object Object]" > "ocn is: " + ocn // throws error: Cannot convert object to primitive value Testing just a few of the many most basic built-in functions shows the magnitude of the problem more clearly: > alert(oco) // shows [object Object] > alert(ocn) // throws error: Cannot convert object to primitive value > oco.toString() // shows [object Object] > ocn.toString() // throws error: ocn.toString is not a function > oco.valueOf() // shows {} > ocn.valueOf() // throws error: ocn.valueOf is not a function > oco.hasOwnProperty("p") // shows "true" > ocn.hasOwnProperty("p") // throws error: ocn.hasOwnProperty is not a function > oco.constructor // shows "Object() { [native code] }" > ocn.constructor // shows "undefined" As said, these differences can make debugging even simple-seeming problems quickly go astray. For example: _A simple common debugging function:_ // display top-level property name:value pairs of given object function ShowProperties(obj){ for(var prop in obj){ console.log(prop + ": " + obj[prop] + "\n" ); } } _Not such simple results: (especially if silent error-trapping had hidden the error messages)_ ob={}; ob.po=oco; ob.pn=ocn; // create a compound object using the test objects from above as property values > ShowProperties( ob ) // display top-level properties - po: [object Object] - Error: Cannot convert object to primitive value Note that only first property gets shown. _(But if the same object is created in a different order -- at least in some implementations...)_ ob={}; ob.pn=ocn; ob.po=oco; // create same compound object again, but create same properties in different order > ShowProperties( ob ) // display top-level properties - Error: Cannot convert object to primitive value Note that neither property gets shown. Note that such a different order may arise statically via disparate fixed codings such as here, but also dynamically via whatever the order any such property-adding code-branches actually get executed at runtime as depends on inputs and/or random-variables. Then again, the actual iteration order is not guaranteed no matter what the order members are added. Be aware of, also, that using Object.entries() on an object created via Object.create() will result in an empty array being returned. var obj = Object.create({ a: 1, b: 2 }); > console.log(Object.entries(obj)); // shows "[]" #### Some NON-solutions A good solution for the missing object-methods is not immediately apparent. Adding the missing object-method directly from the standard-object does NOT work: ocn = Object.create( null ); // create "null" object (same as before) ocn.toString = Object.toString; // since new object lacks method then try assigning it directly from standard-object > ocn.toString // shows "toString() { [native code] }" -- missing method seems to be there now > ocn.toString == Object.toString // shows "true" -- method seems to be same as the standard object-method > ocn.toString() // error: Function.prototype.toString requires that 'this' be a Function Adding the missing object-method directly to new object's "prototype" does not work either, since the new object does not have a real prototype (which is really the cause of ALL these problems) and one cannot be **directly** added: ocn = Object.create( null ); // create "null" object (same as before) ocn.prototype.toString = Object.toString; // Error: Cannot set property 'toString' of undefined ocn.prototype = {}; // try to create a prototype ocn.prototype.toString = Object.toString; // since new object lacks method then try assigning it from standard-object > ocn.toString() // error: ocn.toString is not a function Adding the missing object-method by using the standard-object as new object's prototype does not work either: ocn = Object.create( null ); // create "null" object (same as before) Object.setPrototypeOf(ocn, Object); // set new object's prototype to the standard-object > ocn.toString() // error: Function.prototype.toString requires that 'this' be a Function #### Some OK solutions Again, adding the missing object-method directly from the **standard-object** does NOT work. However, adding the **generic** method directly, DOES: ocn = Object.create( null ); // create "null" object (same as before) ocn.toString = toString; // since new object lacks method then assign it directly from generic version > ocn.toString() // shows "[object Object]" > "ocn is: " + ocn // shows "ocn is: [object Object]" ob={}; ob.pn=ocn; ob.po=oco; // create a compound object (same as before) > ShowProperties(ob) // display top-level properties - po: [object Object] - pn: [object Object] However, setting the generic **prototype** as the new object's prototype works even better: ocn = Object.create( null ); // create "null" object (same as before) Object.setPrototypeOf(ocn, Object.prototype); // set new object's prototype to the "generic" object (NOT standard-object) _(In addition to all the string-related functions shown above, this also adds:)_ > ocn.valueOf() // shows {} > ocn.hasOwnProperty("x") // shows "false" > ocn.constructor // shows "Object() { [native code] }" // ...and all the rest of the properties and methods of Object.prototype. As shown, objects modified this way now look very much like ordinary objects. ## Polyfill This polyfill covers the main use case, which is creating a new object for which the prototype has been chosen but doesn't take the second argument into account. Note that while the setting of `null` as `[[Prototype]]` is supported in the real ES5 `Object.create`, this polyfill cannot support it due to a limitation inherent in versions of ECMAScript lower than 5. if (typeof Object.create !== "function") { Object.create = function (proto, propertiesObject) { if (typeof proto !== 'object' && typeof proto !== 'function') { throw new TypeError('Object prototype may only be an Object: ' + proto); } else if (proto === null) { throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument."); } if (typeof propertiesObject != 'undefined') { throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument."); } function F() {} F.prototype = proto; return new F(); }; } ## Examples ### Classical inheritance with `Object.create()` Below is an example of how to use `Object.create()` to achieve classical inheritance. This is for a single inheritance, which is all that JavaScript supports. // Shape - superclass function Shape() { this.x = 0; this.y = 0; } // superclass method Shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info('Shape moved.'); }; // Rectangle - subclass function Rectangle() { Shape.call(this); // call super constructor. } // subclass extends superclass Rectangle.prototype = Object.create(Shape.prototype); //If you don't set Rectangle.prototype.constructor to Rectangle, //it will take the prototype.constructor of Shape (parent). //To avoid that, we set the prototype.constructor to Rectangle (child). Rectangle.prototype.constructor = Rectangle; var rect = new Rectangle(); console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); // true console.log('Is rect an instance of Shape?', rect instanceof Shape); // true rect.move(1, 1); // Outputs, 'Shape moved.' If you wish to inherit from multiple objects, then mixins are a possibility. function MyClass() { SuperClass.call(this); OtherSuperClass.call(this); } // inherit one class MyClass.prototype = Object.create(SuperClass.prototype); // mixin another Object.assign(MyClass.prototype, OtherSuperClass.prototype); // re-assign constructor MyClass.prototype.constructor = MyClass; MyClass.prototype.myMethod = function() { // do something }; [`Object.assign()`](assign) copies properties from the OtherSuperClass prototype to the MyClass prototype, making them available to all instances of MyClass. `Object.assign()` was introduced with ES2015 and [can be polyfilled](assign#polyfill). If support for older browsers is necessary, `jQuery.extend()` or `_.assign()` can be used. ### Using propertiesObject argument with Object.create() var o; // create an object with null as prototype o = Object.create(null); o = {}; // is equivalent to: o = Object.create(Object.prototype); // Example where we create an object with a couple of // sample properties. (Note that the second parameter // maps keys to *property descriptors*.) o = Object.create(Object.prototype, { // foo is a regular 'value property' foo: { writable: true, configurable: true, value: 'hello' }, // bar is a getter-and-setter (accessor) property bar: { configurable: false, get: function() { return 10; }, set: function(value) { console.log('Setting `o.bar` to', value); } /* with ES2015 Accessors our code can look like this get() { return 10; }, set(value) { console.log('Setting `o.bar` to', value); } */ } }); function Constructor() {} o = new Constructor(); // is equivalent to: o = Object.create(Constructor.prototype); // Of course, if there is actual initialization code // in the Constructor function, // the Object.create() cannot reflect it // Create a new object whose prototype is a new, empty // object and add a single property 'p', with value 42. o = Object.create({}, { p: { value: 42 } }); // by default properties ARE NOT writable, // enumerable or configurable: o.p = 24; o.p; // 42 o.q = 12; for (var prop in o) { console.log(prop); } // 'q' delete o.p; // false // to specify an ES3 property o2 = Object.create({}, { p: { value: 42, writable: true, enumerable: true, configurable: true } }); /* is not equivalent to: This will create an object with prototype : {p: 42 } o2 = Object.create({p: 42}) */ ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-object.create
      `create` 5 12 4 9 11.6 5 1 18 4 12 5 1.0 ## See also - [`Object.defineProperty()`](defineproperty) - [`Object.defineProperties()`](defineproperties) - [`Object.prototype.isPrototypeOf()`](isprototypeof) - [`Reflect.construct()`](../reflect/construct) - John Resig's post on [getPrototypeOf()](http://ejohn.org/blog/objectgetprototypeof/) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create # WebAssembly.Module.customSections() The `WebAssembly.customSections()` function returns a copy of the contents of all custom sections in the given module with the given string name. ## Syntax WebAssembly.Module.customSections(module, sectionName) ### Parameters _module_ The [`WebAssembly.Module`](../module) object whose custom sections are being considered. _sectionName_ The string name of the desired custom section. ### Return value A (possibly empty) array containing [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) copies of the contents of all custom sections matching `sectionName`. ### Exceptions If `module` is not a [`WebAssembly.Module`](../module) object instance, a [`TypeError`](../../typeerror) is thrown. ## Description A wasm module is comprised of a sequence of **sections**. Most of these sections are fully specified and validated by the wasm spec, but modules can also contain **custom sections** that are ignored and skipped over during validation. (Read [High level structure](https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#high-level-structure) for information on section structures, and how normal sections ("known sections") and custom sections are distinguished.) This provides developers with a way to include custom data inside wasm modules for other purposes, for example the [name custom section](https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#name-section), which allows developers to provide names for all the functions and locals in the module (like "symbols" in a native build). Note that the WebAssembly text format currently doesn't have a syntax specified for adding new custom sections; you can however add a name section to your wasm during conversion from text format over to .wasm. The wast2wasm command available as part of the [wabt tool](https://github.com/webassembly/wabt) has a `--debug-names` option — specify this during conversion to get a .wasm with a names custom section, for example: wast2wasm simple-name-section.was -o simple-name-section.wasm --debug-names ## Examples ### Using customSections The following example (see the custom-section.html [source](https://github.com/mdn/webassembly-examples/blob/master/other-examples/custom-section.html) and [live example](https://mdn.github.io/webassembly-examples/other-examples/custom-section.html)) compiles the loaded simple-name-section.wasm byte code. We then do a check using `WebAssembly.Module.customSections`, looking to see whether the module instance contains a "name" custom section by checking that its `length` is more than 0. Since there is a "name" section in the example, an `ArrayBuffer` object is returned. WebAssembly.compileStreaming(fetch('simple-name-section.wasm')) .then(function(mod) { var nameSections = WebAssembly.Module.customSections(mod, "name"); if (nameSections.length != 0) { console.log("Module contains a name section"); console.log(nameSections[0]); }; }); ## Specifications
      Specification
      WebAssembly JavaScript Interface (WebAssembly JavaScript Interface)
      #dom-module-customsections
      `customSections` 57 16 52 Disabled in the Firefox 52 Extended Support Release (ESR). No 44 11 57 57 52 Disabled in the Firefox 52 Extended Support Release (ESR). 43 11 7.0 ## See also - [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) overview page - [WebAssembly concepts](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts) - [Using the WebAssembly JavaScript API](https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/customSections # TypeError: cyclic object value The JavaScript exception "cyclic object value" occurs when object references were found in [JSON](https://www.json.org/). [`JSON.stringify()`](../global_objects/json/stringify) doesn't try to solve them and fails accordingly. ## Message TypeError: cyclic object value (Firefox) TypeError: Converting circular structure to JSON (Chrome and Opera) TypeError: Circular reference in value argument not supported (Edge) ## Error type [`TypeError`](../global_objects/typeerror) ## What went wrong? The [JSON format](https://www.json.org/) per se doesn't support object references (although an [IETF draft exists](https://datatracker.ietf.org/doc/html/draft-pbryan-zyp-json-ref-03)), hence [`JSON.stringify()`](../global_objects/json/stringify) doesn't try to solve them and fails accordingly. ## Examples ### Circular references In a circular structure like the following var circularReference = {otherData: 123}; circularReference.myself = circularReference; [`JSON.stringify()`](../global_objects/json/stringify) will fail JSON.stringify(circularReference); // TypeError: cyclic object value To serialize circular references you can use a library that supports them (e.g. [cycle.js](https://github.com/douglascrockford/JSON-js/blob/master/cycle.js)) or implement a solution by yourself, which will require finding and replacing (or removing) the cyclic references by serializable values. The snippet below illustrates how to find and filter (thus causing data loss) a cyclic reference by using the `replacer` parameter of [`JSON.stringify()`](../global_objects/json/stringify): const getCircularReplacer = () => { const seen = new WeakSet(); return (key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) { return; } seen.add(value); } return value; }; }; JSON.stringify(circularReference, getCircularReplacer()); // {"otherData":123} ## See also - [`JSON.stringify`](../global_objects/json/stringify) - [cycle.js](https://github.com/douglascrockford/JSON-js/blob/master/cycle.js) – Introduces two functions, `JSON.decycle` and `JSON.retrocycle`, which makes it possible to encode and decode cyclical structures and dags into an extended and retrocompatible JSON format. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value # DataView The `DataView` view provides a low-level interface for reading and writing multiple number types in a binary [`ArrayBuffer`](arraybuffer), without having to care about the platform's [endianness](https://developer.mozilla.org/en-US/docs/Glossary/Endianness). ## Description ### Endianness Multi-byte number formats are represented in memory differently depending on machine architecture — see [Endianness](https://developer.mozilla.org/en-US/docs/Glossary/Endianness) for an explanation. `DataView` accessors provide explicit control of how data is accessed, regardless of the executing computer's endianness. var littleEndian = (function() { var buffer = new ArrayBuffer(2); new DataView(buffer).setInt16(0, 256, true /* littleEndian */); // Int16Array uses the platform's endianness. return new Int16Array(buffer)[0] === 256; })(); console.log(littleEndian); // true or false ### 64-bit Integer Values Some browsers don't have support for [`DataView.prototype.setBigInt64()`](dataview/setbigint64) and [`DataView.prototype.setBigUint64()`](dataview/setbiguint64). So to enable 64-bit operations in your code that will work across browsers, you could implement your own `getUint64()` function, to obtain values with precision up to [`Number.MAX_SAFE_INTEGER`](number/max_safe_integer) — which could suffice for certain cases. function getUint64(dataview, byteOffset, littleEndian) { // split 64-bit number into two 32-bit (4-byte) parts const left = dataview.getUint32(byteOffset, littleEndian); const right = dataview.getUint32(byteOffset+4, littleEndian); // combine the two 32-bit values const combined = littleEndian? left + 2**32*right : 2**32*left + right; if (!Number.isSafeInteger(combined)) console.warn(combined, 'exceeds MAX_SAFE_INTEGER. Precision may be lost'); return combined; } Alternatively, if you need full 64-bit range, you can create a [`BigInt`](bigint). Further, although native BigInts are much faster than user-land library equivalents, BigInts will always be much slower than 32-bit integers in JavaScript due to the nature of their variable size. const BigInt = window.BigInt, bigThirtyTwo = BigInt(32), bigZero = BigInt(0); function getUint64BigInt(dataview, byteOffset, littleEndian) { // split 64-bit number into two 32-bit (4-byte) parts const left = BigInt(dataview.getUint32(byteOffset|0, !!littleEndian)>>>0); const right = BigInt(dataview.getUint32((byteOffset|0) + 4|0, !!littleEndian)>>>0); // combine the two 32-bit values and return return littleEndian ? (right<SpecificationECMAScript Language Specification (ECMAScript)
      #sec-dataview-objects
      `DataView` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `DataView` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `buffer` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `byteLength` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `byteOffset` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `getBigInt64` 67 79 68 No 54 No 67 67 68 48 No 9.0 `getBigUint64` 67 79 68 No 54 No 67 67 68 48 No 9.0 `getFloat32` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `getFloat64` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `getInt16` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `getInt32` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `getInt8` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `getUint16` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `getUint32` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `getUint8` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `setBigInt64` 67 79 68 No 54 No 67 67 68 48 No 9.0 `setBigUint64` 67 79 68 No 54 No 67 67 68 48 No 9.0 `setFloat32` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `setFloat64` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `setInt16` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `setInt32` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `setInt8` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `setUint16` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `setUint32` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 `setUint8` 9 12 15 10 12.1 5.1 4 18 15 12.1 4.2 1.0 ## See also - [jDataView](https://github.com/jDataView/jDataView): JavaScript library that polyfills and extends the `DataView` API to all browsers and Node.js. - [`ArrayBuffer`](arraybuffer) - [`SharedArrayBuffer`](sharedarraybuffer) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView # Date JavaScript `Date` objects represent a single moment in time in a platform-independent format. `Date` objects contain a `Number` that represents milliseconds since 1 January 1970 UTC. **Note:** TC39 is working on [Temporal](https://tc39.es/proposal-temporal/docs/index.html), a new Date/Time API. Read more about it on the [Igalia blog](https://blogs.igalia.com/compilers/2020/06/23/dates-and-times-in-javascript/). It is not yet ready for production use! ## Description ### The ECMAScript epoch and timestamps A JavaScript date is fundamentally specified as the number of milliseconds that have elapsed since midnight on January 1, 1970, UTC. This date and time are not the same as the **UNIX epoch** (the number of seconds that have elapsed since midnight on January 1, 1970, UTC), which is the predominant base value for computer-recorded date and time values. **Note:** It's important to keep in mind that while the time value at the heart of a Date object is UTC, the basic methods to fetch the date and time or its components all work in the local (i.e. host system) time zone and offset. It should be noted that the maximum `Date` is not of the same value as the maximum safe integer (`Number.MAX_SAFE_INTEGER` is 9,007,199,254,740,991). Instead, it is defined in ECMA-262 that a maximum of ±100,000,000 (one hundred million) days relative to January 1, 1970 UTC (that is, April 20, 271821 BCE ~ September 13, 275760 CE) can be represented by the standard `Date` object (equivalent to ±8,640,000,000,000,000 milliseconds). ### Date format and time zone conversions There are several methods available to obtain a date in various formats, as well as to perform time zone conversions. Particularly useful are the functions that output the date and time in Coordinated Universal Time (UTC), the global standard time defined by the World Time Standard. (This time is historically known as _Greenwich Mean Time_, as UTC lies along the meridian that includes London—and nearby Greenwich—in the United Kingdom.) The user's device provides the local time. In addition to methods to read and alter individual components of the local date and time (such as [`getDay()`](date/getday) and [`setHours()`](date/sethours)), there are also versions of the same methods that read and manipulate the date and time using UTC (such as [`getUTCDay()`](date/getutcday) and [`setUTCHours()`](date/setutchours)). ## Constructor [`Date()`](date/date) When called as a function, returns a string representation of the current date and time, exactly as `new Date().toString()` does. [`new Date()`](date/date) When called as a constructor, returns a new `Date` object. ## Static methods [`Date.now()`](date/now) Returns the numeric value corresponding to the current time—the number of milliseconds elapsed since January 1, 1970 00:00:00 UTC, with leap seconds ignored. [`Date.parse()`](date/parse) Parses a string representation of a date and returns the number of milliseconds since 1 January, 1970, 00:00:00 UTC, with leap seconds ignored. **Note:** Parsing of strings with `Date.parse` is strongly discouraged due to browser differences and inconsistencies. [`Date.UTC()`](date/utc) Accepts the same parameters as the longest form of the constructor (i.e. 2 to 7) and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC, with leap seconds ignored. ## Instance methods [`Date.prototype.getDate()`](date/getdate) Returns the day of the month (`1`–`31`) for the specified date according to local time. [`Date.prototype.getDay()`](date/getday) Returns the day of the week (`0`–`6`) for the specified date according to local time. [`Date.prototype.getFullYear()`](date/getfullyear) Returns the year (4 digits for 4-digit years) of the specified date according to local time. [`Date.prototype.getHours()`](date/gethours) Returns the hour (`0`–`23`) in the specified date according to local time. [`Date.prototype.getMilliseconds()`](date/getmilliseconds) Returns the milliseconds (`0`–`999`) in the specified date according to local time. [`Date.prototype.getMinutes()`](date/getminutes) Returns the minutes (`0`–`59`) in the specified date according to local time. [`Date.prototype.getMonth()`](date/getmonth) Returns the month (`0`–`11`) in the specified date according to local time. [`Date.prototype.getSeconds()`](date/getseconds) Returns the seconds (`0`–`59`) in the specified date according to local time. [`Date.prototype.getTime()`](date/gettime) Returns the numeric value of the specified date as the number of milliseconds since January 1, 1970, 00:00:00 UTC. (Negative values are returned for prior times.) [`Date.prototype.getTimezoneOffset()`](date/gettimezoneoffset) Returns the time-zone offset in minutes for the current locale. [`Date.prototype.getUTCDate()`](date/getutcdate) Returns the day (date) of the month (`1`–`31`) in the specified date according to universal time. [`Date.prototype.getUTCDay()`](date/getutcday) Returns the day of the week (`0`–`6`) in the specified date according to universal time. [`Date.prototype.getUTCFullYear()`](date/getutcfullyear) Returns the year (4 digits for 4-digit years) in the specified date according to universal time. [`Date.prototype.getUTCHours()`](date/getutchours) Returns the hours (`0`–`23`) in the specified date according to universal time. [`Date.prototype.getUTCMilliseconds()`](date/getutcmilliseconds) Returns the milliseconds (`0`–`999`) in the specified date according to universal time. [`Date.prototype.getUTCMinutes()`](date/getutcminutes) Returns the minutes (`0`–`59`) in the specified date according to universal time. [`Date.prototype.getUTCMonth()`](date/getutcmonth) Returns the month (`0`–`11`) in the specified date according to universal time. [`Date.prototype.getUTCSeconds()`](date/getutcseconds) Returns the seconds (`0`–`59`) in the specified date according to universal time. [`Date.prototype.getYear()`](date/getyear) Returns the year (usually 2–3 digits) in the specified date according to local time. Use [`getFullYear()`](date/getfullyear) instead. [`Date.prototype.setDate()`](date/setdate) Sets the day of the month for a specified date according to local time. [`Date.prototype.setFullYear()`](date/setfullyear) Sets the full year (e.g. 4 digits for 4-digit years) for a specified date according to local time. [`Date.prototype.setHours()`](date/sethours) Sets the hours for a specified date according to local time. [`Date.prototype.setMilliseconds()`](date/setmilliseconds) Sets the milliseconds for a specified date according to local time. [`Date.prototype.setMinutes()`](date/setminutes) Sets the minutes for a specified date according to local time. [`Date.prototype.setMonth()`](date/setmonth) Sets the month for a specified date according to local time. [`Date.prototype.setSeconds()`](date/setseconds) Sets the seconds for a specified date according to local time. [`Date.prototype.setTime()`](date/settime) Sets the [`Date`](date) object to the time represented by a number of milliseconds since January 1, 1970, 00:00:00 UTC. Use negative numbers for times prior. [`Date.prototype.setUTCDate()`](date/setutcdate) Sets the day of the month for a specified date according to universal time. [`Date.prototype.setUTCFullYear()`](date/setutcfullyear) Sets the full year (e.g. 4 digits for 4-digit years) for a specified date according to universal time. [`Date.prototype.setUTCHours()`](date/setutchours) Sets the hour for a specified date according to universal time. [`Date.prototype.setUTCMilliseconds()`](date/setutcmilliseconds) Sets the milliseconds for a specified date according to universal time. [`Date.prototype.setUTCMinutes()`](date/setutcminutes) Sets the minutes for a specified date according to universal time. [`Date.prototype.setUTCMonth()`](date/setutcmonth) Sets the month for a specified date according to universal time. [`Date.prototype.setUTCSeconds()`](date/setutcseconds) Sets the seconds for a specified date according to universal time. [`Date.prototype.setYear()`](date/setyear) Sets the year (usually 2–3 digits) for a specified date according to local time. Use [`setFullYear()`](date/setfullyear) instead. [`Date.prototype.toDateString()`](date/todatestring) Returns the "date" portion of the [`Date`](date) as a human-readable string like `'Thu Apr 12 2018'`. [`Date.prototype.toISOString()`](date/toisostring) Converts a date to a string following the ISO 8601 Extended Format. [`Date.prototype.toJSON()`](date/tojson) Returns a string representing the [`Date`](date) using [`toISOString()`](date/toisostring). Intended for use by [`JSON.stringify()`](json/stringify). [`Date.prototype.toGMTString()`](date/togmtstring) Returns a string representing the [`Date`](date) based on the GMT (UTC) time zone. Use [`toUTCString()`](date/toutcstring) instead. [`Date.prototype.toLocaleDateString()`](date/tolocaledatestring) Returns a string with a locality sensitive representation of the date portion of this date based on system settings. `Date.prototype.toLocaleFormat()` Converts a date to a string, using a format string. [`Date.prototype.toLocaleString()`](date/tolocalestring) Returns a string with a locality-sensitive representation of this date. Overrides the [`Object.prototype.toLocaleString()`](object/tolocalestring) method. [`Date.prototype.toLocaleTimeString()`](date/tolocaletimestring) Returns a string with a locality-sensitive representation of the time portion of this date, based on system settings. [`Date.prototype.toString()`](date/tostring) Returns a string representing the specified [`Date`](date) object. Overrides the [`Object.prototype.toString()`](object/tostring) method. [`Date.prototype.toTimeString()`](date/totimestring) Returns the "time" portion of the [`Date`](date) as a human-readable string. [`Date.prototype.toUTCString()`](date/toutcstring) Converts a date to a string using the UTC timezone. [`Date.prototype.valueOf()`](date/valueof) Returns the primitive value of a [`Date`](date) object. Overrides the [`Object.prototype.valueOf()`](object/valueof) method. ## Examples ### Several ways to create a Date object The following examples show several ways to create JavaScript dates: **Note:** Parsing of date strings with the `Date` constructor (and `Date.parse`, they are equivalent) is strongly discouraged due to browser differences and inconsistencies. let today = new Date() let birthday = new Date('December 17, 1995 03:24:00') let birthday = new Date('1995-12-17T03:24:00') let birthday = new Date(1995, 11, 17) // the month is 0-indexed let birthday = new Date(1995, 11, 17, 3, 24, 0) let birthday = new Date(628021800000) // passing epoch timestamp ### To get Date, Month and Year or Time let [month, date, year] = new Date().toLocaleDateString("en-US").split("/") let [hour, minute, second] = new Date().toLocaleTimeString("en-US").split(/:| /) ### Two digit years map to 1900 – 1999 Values from `0` to `99` map to the years `1900` to `1999`. All other values are the actual year . In order to create and get dates between the years `0` and `99` the [`Date.prototype.setFullYear()`](date/setfullyear) and [`Date.prototype.getFullYear()`](date/getfullyear) methods should be used. let date = new Date(98, 1) // Sun Feb 01 1998 00:00:00 GMT+0000 (GMT) // Deprecated method; 98 maps to 1998 here as well date.setYear(98) // Sun Feb 01 1998 00:00:00 GMT+0000 (GMT) date.setFullYear(98) // Sat Feb 01 0098 00:00:00 GMT+0000 (BST) ### Calculating elapsed time The following examples show how to determine the elapsed time between two JavaScript dates in milliseconds. Due to the differing lengths of days (due to daylight saving changeover), months, and years, expressing elapsed time in units greater than hours, minutes, and seconds requires addressing a number of issues, and should be thoroughly researched before being attempted. // Using Date objects let start = Date.now() // The event to time goes here: doSomethingForALongTime() let end = Date.now() let elapsed = end - start // elapsed time in milliseconds // Using built-in methods let start = new Date() // The event to time goes here: doSomethingForALongTime() let end = new Date() let elapsed = end.getTime() - start.getTime() // elapsed time in milliseconds // To test a function and get back its return function printElapsedTime(fTest) { let nStartTime = Date.now(), vReturn = fTest(), nEndTime = Date.now() console.log(`Elapsed time: ${ String(nEndTime - nStartTime) } milliseconds`) return vReturn } let yourFunctionReturn = printElapsedTime(yourFunction) **Note:** In browsers that support the [Web Performance API](https://developer.mozilla.org/en-US/docs/Web/API/Window/performance)'s high-resolution time feature, [`Performance.now()`](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now) can provide more reliable and precise measurements of elapsed time than [`Date.now()`](date/now). ### Get the number of seconds since the ECMAScript Epoch let seconds = Math.floor(Date.now() / 1000) In this case, it's important to return only an integer—so a simple division won't do. It's also important to only return actually elapsed seconds. (That's why this code uses [`Math.floor()`](math/floor), and _not_ [`Math.round()`](math/round).) ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-date-objects
      `Date` 1 12 1 3 The [ISO8601 Date Format](https://en.wikipedia.org/wiki/ISO_8601) is not supported in Internet Explorer 8 or earlier. 3 1 1 18 4 10.1 1 1.0 `Date` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `UTC` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `getDate` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `getDay` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `getFullYear` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `getHours` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `getMilliseconds` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `getMinutes` 1 12 1 4 3 1 1 18 4 10.1 1 1.0 `getMonth` 1 12 1 4 3 1 1 18 4 10.1 1 1.0 `getSeconds` 1 12 1 4 3 1 1 18 4 10.1 1 1.0 `getTime` 1 12 1 4 3 1 1 18 4 10.1 1 1.0 `getTimezoneOffset` 1 12 1 5 3 1 1 18 4 10.1 1 1.0 `getUTCDate` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `getUTCDay` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `getUTCFullYear` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `getUTCHours` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `getUTCMilliseconds` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `getUTCMinutes` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `getUTCMonth` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `getUTCSeconds` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `getYear` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `now` 5 12 3 9 10.5 4 1 18 4 14 4 1.0 `parse` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `setDate` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `setFullYear` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `setHours` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `setMilliseconds` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `setMinutes` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `setMonth` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `setSeconds` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `setTime` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `setUTCDate` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `setUTCFullYear` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `setUTCHours` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `setUTCMilliseconds` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `setUTCMinutes` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `setUTCMonth` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `setUTCSeconds` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `setYear` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `toDateString` 1 12 1 5.5 5 1 1 18 4 10.1 1 1.0 `toGMTString` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `toISOString` 3 12 1 9 10.5 5 ≤37 18 4 11 4.2 1.0 `toJSON` 3 12 1 8 10.5 5 ≤37 18 4 11 4.2 1.0 `toLocaleDateString` 1 12 1 5.5 5 1 1 18 4 10.1 1 1.0 `toLocaleString` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `toLocaleTimeString` 1 12 1 5.5 5 1 1 18 4 10.1 1 1.0 `toSource` No No 1-74 Starting in Firefox 74, `toSource()` is no longer available for use by web content. It is still allowed for internal and privileged code. No No No No No 4 No No No `toString` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 `toTimeString` 1 12 1 5.5 5 1 1 18 4 10.1 1 1.0 `toUTCString` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 `valueOf` 1 12 1 4 3 1 1 18 4 10.1 1 1.0 `@@toPrimitive` 47 15 44 No 34 10 47 47 44 34 10 5.0 ## See also - [`Date()`](date/date) constructor https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date # Intl.DateTimeFormat() constructor The `Intl.DateTimeFormat()` constructor creates [`Intl.DateTimeFormat`](../datetimeformat) objects that enable language-sensitive date and time formatting. ## Syntax new Intl.DateTimeFormat() new Intl.DateTimeFormat(locales) new Intl.DateTimeFormat(locales, options) ### Parameters `locales` Optional A string with a BCP 47 language tag, or an array of such strings. To use the browser's default locale, pass an empty array. Unicode extension are supported (for example "`en-US-u-ca-buddhist`"). For the general form and interpretation of the `locales` argument, see the [Intl](../../intl#locale_identification_and_negotiation) page. The following Unicode extension keys are allowed: `nu` Numbering system. Possible values include: "`arab`", "`arabext`", "`bali`", "`beng`", "`deva`", "`fullwide`", "`gujr`", "`guru`", "`hanidec`", "`khmr`", "`knda`", "`laoo`", "`latn`", "`limb`", "`mlym`", "`mong`", "`mymr`", "`orya`", "`tamldec`", "`telu`", "`thai`", "`tibt`". `ca` Calendar. Possible values include: "`buddhist`", "`chinese`", "`coptic`", "`ethiopia`", "`ethiopic`", "`gregory`", "`hebrew`", "`indian`", "`islamic`", "`iso8601`", "`japanese`", "`persian`", "`roc`". `hc` Hour cycle. Possible values include: "`h11`", "`h12`", "`h23`", "`h24`". `options` Optional An object with some or all of the following properties: `dateStyle` The date formatting style to use when calling `format()`. Possible values include: - "`full`" - "`long`" - "`medium`" - "`short`" **Note:** `dateStyle` can be used with `timeStyle`, but not with other options (e.g. `weekday`, `hour`, `month`, etc.). `timeStyle` The time formatting style to use when calling `format()`. Possible values include: - "`full`" - "`long`" - "`medium`" - "`short`" **Note:** `timeStyle` can be used with `dateStyle`, but not with other options (e.g. `weekday`, `hour`, `month`, etc.). `calendar` Calendar. Possible values include: "`buddhist`", "`chinese`", " `coptic`", "`ethiopia`", "`ethiopic`", "`gregory`", " `hebrew`", "`indian`", "`islamic`", "`iso8601`", " `japanese`", "`persian`", "`roc`". `dayPeriod` The way day periods should be expressed. Possible values include: "`narrow`", "`short`", " `long`". `numberingSystem` Numbering System. Possible values include: "`arab`", "`arabext`", " `bali`", "`beng`", "`deva`", "`fullwide`", " `gujr`", "`guru`", "`hanidec`", "`khmr`", " `knda`", "`laoo`", "`latn`", "`limb`", "`mlym`", " `mong`", "`mymr`", "`orya`", "`tamldec`", " `telu`", "`thai`", "`tibt`". `localeMatcher` The locale matching algorithm to use. Possible values are "`lookup`" and "`best fit`"; the default is "`best fit`". For information about this option, see the [Intl](../../intl#locale_negotiation) page. `timeZone` The time zone to use. The only value implementations must recognize is "`UTC`"; the default is the runtime's default time zone. Implementations may also recognize the time zone names of the [IANA time zone database](https://www.iana.org/time-zones), such as "`Asia/Shanghai`", "`Asia/Kolkata`", "`America/New_York`". `hour12` Whether to use 12-hour time (as opposed to 24-hour time). Possible values are `true` and `false`; the default is locale dependent. This option overrides the `hc` language tag and/or the `hourCycle` option in case both are present. `hourCycle` The hour cycle to use. Possible values are "`h11`", "`h12`", "`h23`", or "`h24`". This option overrides the `hc` language tag, if both are present, and the `hour12` option takes precedence in case both options have been specified. `formatMatcher` The format matching algorithm to use. Possible values are "`basic`" and "`best fit`"; the default is "`best fit`". See the following paragraphs for information about the use of this property. The following properties describe the date-time components to use in formatted output, and their desired representations. Implementations are required to support at least the following subsets: - `weekday`, `year`, `month`, `day`, `hour`, `minute`, `second` - `weekday`, `year`, `month`, `day` - `year`, `month`, `day` - `year`, `month` - `month`, `day` - `hour`, `minute`, `second` - `hour`, `minute` Implementations may support other subsets, and requests will be negotiated against all available subset-representation combinations to find the best match. Two algorithms are available for this negotiation and selected by the `formatMatcher` property: A [fully specified "`basic`" algorithm](https://www.ecma-international.org/ecma-402/1.0/#BasicFormatMatcher) and an implementation-dependent "`best fit`" algorithm. `weekday` The representation of the weekday. Possible values are: - "`long`" (e.g., `Thursday`) - "`short`" (e.g., `Thu`) - "`narrow`" (e.g., `T`). Two weekdays may have the same narrow style for some locales (e.g. `Tuesday`'s narrow style is also `T`). `era` The representation of the era. Possible values are: - "`long`" (e.g., `Anno Domini`) - "`short`" (e.g., `AD`) - "`narrow`" (e.g., `A`) `year` The representation of the year. Possible values are: - "`numeric`" (e.g., `2012`) - "`2-digit`" (e.g., `12`) `month` The representation of the month. Possible values are: - "`numeric`" (e.g., `2`) - "`2-digit`" (e.g., `02`) - "`long`" (e.g., `March`) - "`short`" (e.g., `Mar`) - "`narrow`" (e.g., `M`). Two months may have the same narrow style for some locales (e.g. `May`'s narrow style is also `M`). `day` The representation of the day. Possible values are: - "`numeric`" (e.g., `1`) - "`2-digit`" (e.g., `01`) `hour` The representation of the hour. Possible values are "`numeric`", "`2-digit`". `minute` The representation of the minute. Possible values are "`numeric`", "`2-digit`". `second` The representation of the second. Possible values are "`numeric`", "`2-digit`". `fractionalSecondDigits` The number of digits used to represent fractions of a second (any additional digits are truncated). Possible values are: - `0` (Fractional part dropped.) - `1` (Fractional part represented as 1 digit. For example, 736 is formatted as `7`.) - `2` (Fractional part represented as 2 digits. For example, 736 is formatted as `73`.) - `3` (Fractional part represented as 3 digits. For example, 736 is formatted as `736`.) `timeZoneName` The representation of the time zone name. Possible values are: - "`long`" (e.g., `British Summer Time`) - "`short`" (e.g., `GMT+1`) The default value for each date-time component property is [`undefined`](../../undefined), but if all component properties are [`undefined`](../../undefined), then `year`, `month`, and `day` are assumed to be "`numeric`". ## Examples ### Using DateTimeFormat In basic use without specifying a locale, `DateTimeFormat` uses the default locale and default options. var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0)); // toLocaleString without arguments depends on the implementation, // the default locale, and the default time zone console.log(new Intl.DateTimeFormat().format(date)); // → "12/19/2012" if run with en-US locale (language) and time zone America/Los_Angeles (UTC-0800) ### Using timeStyle and dateStyle let o = new Intl.DateTimeFormat("en" , { timeStyle: "short" }); console.log(o.format(Date.now())); // "13:31 AM" let o = new Intl.DateTimeFormat("en" , { dateStyle: "short" }); console.log(o.format(Date.now())); // "07/07/20" let o = new Intl.DateTimeFormat("en" , { timeStyle: "medium", dateStyle: "short" }); console.log(o.format(Date.now())); // "07/07/20, 13:31:55 AM" ## Specifications
      Specification
      ECMAScript Internationalization API Specification (ECMAScript Internationalization API)
      #sec-intl-datetimeformat-constructor
      `DateTimeFormat` 24 12 29 11 15 10 4.4 25 56 14 10 1.5 `dateStyle` 76 79 79 No 63 14.1 76 76 79 54 14.5 No `fractionalSecondDigits` 84 84 84 No 70 No 84 84 84 60 No No `hourCycle` 73 18 58 No 60 13 73 73 58 52 13 No `iana_time_zone_names` 24 14 52 No 15 10 37 25 56 14 10 1.5 `timeStyle` 76 79 79 No 63 14.1 76 76 79 54 14.5 No ## See also - [`Intl.DateTimeFormat`](../datetimeformat) - [`Intl`](../../intl) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat # TypeError: can't access dead object The JavaScript exception "can't access dead object" occurs when Firefox disallows add-ons to keep strong references to DOM objects after their parent document has been destroyed to improve in memory usage and to prevent memory leaks. ## Message TypeError: can't access dead object ## Error type [`TypeError`](../global_objects/typeerror) ## What went wrong? To improve in memory usage and to prevent memory leaks, Firefox disallows add-ons to keep strong references to DOM objects after their parent document has been destroyed. A dead object, is holding a strong (keep alive) reference to a DOM element that persists even after it was destroyed in the DOM. To avoid these issues, references to DOM nodes in foreign document should instead be stored in an object which is specific to that document, and cleaned up when the document is unloaded, or stored as [weak references](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.getWeakReference). ## Examples ### Checking if an object is dead [Components.utils](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils) offers a `isDeadWrapper()` method, which privileged code might use. if (Components.utils.isDeadWrapper(window)) { // dead } Unprivileged code has no access to Component.utils and might just be able catch the exception. try { String(window); } catch (e) { console.log("window is likely dead"); } ## See also - [What does "can't access dead object” mean?](https://blog.mozilla.org/addons/2012/09/12/what-does-cant-access-dead-object-mean/) - [Common causes of memory leaks in extensions](https://developer.mozilla.org/en-US/docs/Extensions/Common_causes_of_memory_leaks_in_extensions) - [Components.utils](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils) - [Zombie Compartments](https://developer.mozilla.org/en-US/docs/Mozilla/Zombie_compartments) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Dead_object # debugger The `debugger` invokes any available debugging functionality, such as setting a breakpoint. If no debugging functionality is available, this statement has no effect. ## Syntax debugger; ## Examples ### Using the debugger statement The following example shows code where a `debugger` statement has been inserted, to invoke a debugger (if one exists) when the function is called. function potentiallyBuggyCode() { debugger; // do potentially buggy stuff to examine, step through, etc. } When the debugger is invoked, execution is paused at the `debugger` statement. It is like a breakpoint in the script source. [Paused at a debugger statement.](https://mdn.mozillademos.org/files/6963/Screen%20Shot%202014-02-07%20at%209.14.35%20AM.png) ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-debugger-statement
      `debugger` 5 12 1 4 10 5 1 18 4 10.1 4.2 1.0 ## See also - [Debugging JavaScript](https://developer.mozilla.org/en-US/docs/Mozilla/Debugging/Debugging_JavaScript) - [The Debugger in the Firefox Developer Tools](https://developer.mozilla.org/en-US/docs/Tools/Debugger) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger # decodeURI() The `decodeURI()` function decodes a Uniform Resource Identifier (URI) previously created by [`encodeURI()`](encodeuri) or by a similar routine. ## Syntax 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 Throws an [`URIError`](urierror) ("malformed URI sequence") exception when `encodedURI` contains invalid character sequences. ## Description Replaces each escape sequence in the encoded URI with the character that it represents, but does not decode escape sequences that could not have been introduced by [`encodeURI`](encodeuri). The character "`#`” is not decoded from escape sequences. ## Examples ### Decoding a Cyrillic URL 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_шеллы" ### Catching errors try { var a = decodeURI('%E0%A4%A'); } catch(e) { console.error(e); } // URIError: malformed URI sequence ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-decodeuri-encodeduri
      `decodeURI` 1 12 1 5.5 7 1.1 1 18 4 10.1 1 1.0 ## See also - [`decodeURIComponent()`](decodeuricomponent) - [`encodeURI()`](encodeuri) - [`encodeURIComponent()`](encodeuricomponent) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI # decodeURIComponent() The `decodeURIComponent()` function decodes a Uniform Resource Identifier (URI) component previously created by [`encodeURIComponent`](encodeuricomponent) or by a similar routine. ## Syntax 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 Throws an [`URIError`](urierror) ("malformed URI sequence") exception when used wrongly. ## Description Replaces each escape sequence in the encoded URI component with the character that it represents. ## Examples ### Decoding a Cyrillic URL component decodeURIComponent('JavaScript_%D1%88%D0%B5%D0%BB%D0%BB%D1%8B'); // "JavaScript_шеллы" ### Catching errors try { var 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. function decodeQueryParam(p) { return decodeURIComponent(p.replace(/\+/g, ' ')); } decodeQueryParam('search+query%20%28correct%29'); // 'search query (correct)' ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-decodeuricomponent-encodeduricomponent
      `decodeURIComponent` 1 12 1 5.5 7 1.1 1 18 4 10.1 1 1.0 ## See also - [`decodeURI`](decodeuri) - [`encodeURI`](encodeuri) - [`encodeURIComponent`](encodeuricomponent) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent # Decrement (--) The decrement operator (`--`) decrements (subtracts one from) its operand and returns a value. ## Syntax Operator: x-- or --x ## Description If used postfix, with operator after operand (for example, `x--`), the decrement operator decrements and returns the value before decrementing. If used prefix, with operator before operand (for example, `--x`), the decrement operator decrements and returns the value after decrementing. ## Examples ### Postfix decrement let x = 3; y = x--; // y = 3 // x = 2 ### Prefix decrement let a = 2; b = --a; // a = 1 // b = 1 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-postfix-decrement-operator
      `Decrement` 2 12 1 3 3 4 1 18 4 10.1 3.2 1.0 ## See also - [Addition operator](addition) - [Subtraction operator](subtraction) - [Division operator](division) - [Multiplication operator](multiplication) - [Remainder operator](remainder) - [Exponentiation operator](exponentiation) - [Increment operator](increment) - [Unary negation operator](unary_negation) - [Unary plus operator](unary_plus) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Decrement # Default parameters **Default function parameters** allow named parameters to be initialized with default values if no value or `undefined` is passed. ## Syntax function fnName(param1 = defaultValue1, ..., paramN = defaultValueN) { ... } ## Description In JavaScript, function parameters default to [`undefined`](../global_objects/undefined). However, it's often useful to set a different default value. This is where default parameters can help. In the past, the general strategy for setting defaults was to test parameter values in the function body and assign a value if they are `undefined`. In the following example, if no value is provided for `b` when `multiply` is called, `b`'s value would be `undefined` when evaluating `a * b` and `multiply` would return `NaN`. function multiply(a, b) { return a * b } multiply(5, 2) // 10 multiply(5) // NaN ! To guard against this, something like the second line would be used, where `b` is set to `1` if `multiply` is called with only one argument: function multiply(a, b) { b = (typeof b !== 'undefined') ? b : 1 return a * b } multiply(5, 2) // 10 multiply(5) // 5 With default parameters in ES2015, checks in the function body are no longer necessary. Now, you can assign `1` as the default value for `b` in the function head: function multiply(a, b = 1) { return a * b } multiply(5, 2) // 10 multiply(5) // 5 multiply(5, undefined) // 5 ## Examples ### Passing `undefined` vs. other falsy values In the second call in this example, even if the first argument is set explicitly to `undefined` (though not `null` or other [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) values), the value of the `num` argument is still the default. function test(num = 1) { console.log(typeof num) } test() // 'number' (num is set to 1) test(undefined) // 'number' (num is set to 1 too) // test with other falsy values: test('') // 'string' (num is set to '') test(null) // 'object' (num is set to null) ### Evaluated at call time The default argument is evaluated at _call time_. So, unlike (for example) Python, a new object is created each time the function is called. function append(value, array = []) { array.push(value) return array } append(1) // [1] append(2) // [2], not [1, 2] This even applies to functions and variables: function callSomething(thing = something()) { return thing } let numberOfTimesCalled = 0 function something() { numberOfTimesCalled += 1 return numberOfTimesCalled } callSomething() // 1 callSomething() // 2 ### Earlier parameters are available to later default parameters Parameters defined earlier (to the left) are available to later default parameters: function greet(name, greeting, message = greeting + ' ' + name) { return [name, greeting, message] } greet('David', 'Hi') // ["David", "Hi", "Hi David"] greet('David', 'Hi', 'Happy Birthday!') // ["David", "Hi", "Happy Birthday!"] This functionality can be approximated like this, which demonstrates how many edge cases are handled: function go() { return ':P' } function withDefaults(a, b = 5, c = b, d = go(), e = this, f = arguments, g = this.value) { return [a, b, c, d, e, f, g] } function withoutDefaults(a, b, c, d, e, f, g) { switch (arguments.length) { case 0: a; case 1: b = 5; case 2: c = b; case 3: d = go(); case 4: e = this; case 5: f = arguments; case 6: g = this.value; default: } return [a, b, c, d, e, f, g]; } withDefaults.call({value: '=^_^='}); // [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="] withoutDefaults.call({value: '=^_^='}); // [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="] ### Scope Effects If default parameters are defined for one or more parameter, then a [second scope](https://tc39.es/ecma262/#sec-functiondeclarationinstantiation) (Environment Record) is created, specifically for the identifiers within the parameter list. This scope is a parent of the scope created for the function body. This means that functions and variables declared in the function body cannot be referred to from default value parameter initializers; attempting to do so throws a run-time [`ReferenceError`](../global_objects/referenceerror). It also means that variables declared inside the function body using `var` will mask parameters of the same name, instead of the usual behavior of duplicate `var` declarations having no effect. The following function will throw a `ReferenceError` when invoked, because the default parameter value does not have access to the child scope of the function body: function f(a = go()) { // Throws a `ReferenceError` when `f` is invoked. function go() { return ':P' } } ...and this function will print `undefined` because variable `var a` is hoisted only to the top of the scope created for the function body (and not the parent scope created for the parameter list): function f(a, b = () => console.log(a)) { var a = 1 b() // Prints `undefined`, because default parameter values exist in their own scope } ### Parameters without defaults after default parameters Parameters are still set left-to-right, overwriting default parameters even if there are later parameters without defaults. function f(x = 1, y) { return [x, y] } f() // [1, undefined] f(2) // [2, undefined] ### Destructured parameter with default value assignment You can use default value assignment with the [destructuring assignment](../operators/destructuring_assignment) notation: function f([x, y] = [1, 2], {z: z} = {z: 3}) { return x + y + z } f() // 6 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-function-definitions
      `Default_parameters` 49 14 15 No 36 10 49 49 15 36 10 5.0 `destructured_parameter_with_default_value_assignment` 49 14 41 No 36 10 49 49 41 36 10 5.0 `parameters_without_defaults_after_default_parameters` 49 14 26 No 36 10 49 49 26 36 10 5.0 ## See also - [Original proposal at ecmascript.org](http://wiki.ecmascript.org/doku.php?id=harmony:parameter_default_values) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters # Object.defineProperties() The `Object.defineProperties()` method defines new or modifies existing properties directly on an object, returning the object. ## Syntax Object.defineProperties(obj, props) ### Parameters `obj` The object on which to define or modify properties. `props` An object whose keys represent the names of properties to be defined or modified and whose values are objects describing those properties. Each value in `props` must be either a data descriptor or an accessor descriptor; it cannot be both (see [`Object.defineProperty()`](defineproperty) for more details). Data descriptors and accessor descriptors may optionally contain the following keys: `configurable` `true` if and only if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object. `false` `enumerable` `true` if and only if this property shows up during enumeration of the properties on the corresponding object. `false` A data descriptor also has the following optional keys: `value` The value associated with the property. Can be any valid JavaScript value (number, object, function, etc). **Defaults to [`undefined`](../undefined).** `writable` `true` if and only if the value associated with the property may be changed with an [assignment operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#assignment_operators). `false` An accessor descriptor also has the following optional keys: `get` A function which serves as a getter for the property, or [`undefined`](../undefined) if there is no getter. The function's return value will be used as the value of the property. **Defaults to [`undefined`](../undefined).** `set` A function which serves as a setter for the property, or [`undefined`](../undefined) if there is no setter. The function will receive as its only argument the new value being assigned to the property. **Defaults to [`undefined`](../undefined).** If a descriptor has neither of `value`, `writable`, `get` and `set` keys, it is treated as a data descriptor. If a descriptor has both `value` or `writable` and `get` or `set` keys, an exception is thrown. ### Return value The object that was passed to the function. ## Examples ### Using Object.defineProperties var obj = {}; Object.defineProperties(obj, { 'property1': { value: true, writable: true }, 'property2': { value: 'Hello', writable: false } // etc. etc. }); ## Polyfill Assuming a pristine execution environment with all names and properties referring to their initial values, `Object.defineProperties` is almost completely equivalent (note the comment in `isCallable`) to the following reimplementation in JavaScript: function defineProperties(obj, properties) { function convertToDescriptor(desc) { function hasProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } function isCallable(v) { // NB: modify as necessary if other values than functions are callable. return typeof v === 'function'; } if (typeof desc !== 'object' || desc === null) throw new TypeError('bad desc'); var d = {}; if (hasProperty(desc, 'enumerable')) d.enumerable = !!desc.enumerable; if (hasProperty(desc, 'configurable')) d.configurable = !!desc.configurable; if (hasProperty(desc, 'value')) d.value = desc.value; if (hasProperty(desc, 'writable')) d.writable = !!desc.writable; if (hasProperty(desc, 'get')) { var g = desc.get; if (!isCallable(g) && typeof g !== 'undefined') throw new TypeError('bad get'); d.get = g; } if (hasProperty(desc, 'set')) { var s = desc.set; if (!isCallable(s) && typeof s !== 'undefined') throw new TypeError('bad set'); d.set = s; } if (('get' in d || 'set' in d) && ('value' in d || 'writable' in d)) throw new TypeError('identity-confused descriptor'); return d; } if (typeof obj !== 'object' || obj === null) throw new TypeError('bad obj'); properties = Object(properties); var keys = Object.keys(properties); var descs = []; for (var i = 0; i < keys.length; i++) descs.push([keys[i], convertToDescriptor(properties[keys[i]])]); for (var i = 0; i < descs.length; i++) Object.defineProperty(obj, descs[i][0], descs[i][1]); return obj; } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-object.defineproperties
      `defineProperties` 5 12 4 9 11.6 5 1 18 4 12 5 1.0 ## See also - [`Object.defineProperty()`](defineproperty) - [`Object.keys()`](keys) - [Enumerability and ownership of properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties # Object.defineProperty() The static method `Object.defineProperty()` defines a new property directly on an object, or modifies an existing property on an object, and returns the object. ## Syntax Object.defineProperty(obj, prop, descriptor) ### Parameters `obj` The object on which to define the property. `prop` The name or [`Symbol`](../symbol) of the property to be defined or modified. `descriptor` The descriptor for the property being defined or modified. ### Return value The object that was passed to the function. ## Description This method allows a precise addition to or modification of a property on an object. Normal property addition through assignment creates properties which show up during property enumeration ([`for...in`](../../statements/for...in) loop or [`Object.keys`](keys) method), whose values may be changed, and which may be [deleted](../../operators/delete). This method allows these extra details to be changed from their defaults. By default, values added using `Object.defineProperty()` are immutable and not enumerable. Property descriptors present in objects come in two main flavors: data descriptors and accessor descriptors. A _data descriptor_ is a property that has a value, which may or may not be writable. An _accessor descriptor_ is a property described by a getter-setter pair of functions. A descriptor must be one of these two flavors; it cannot be both. Both data and accessor descriptors are objects. They share the following optional keys (please note: the **defaults** mentioned here are in the case of defining properties using `Object.defineProperty()`): `configurable` `true` if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object. `false` `enumerable` `true` if and only if this property shows up during enumeration of the properties on the corresponding object. `false` A **data descriptor** also has the following optional keys: `value` The value associated with the property. Can be any valid JavaScript value (number, object, function, etc). **Defaults to [`undefined`](../undefined).** `writable` `true` if the value associated with the property may be changed with an [assignment operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#assignment_operators). `false` An **accessor descriptor** also has the following optional keys: `get` A function which serves as a getter for the property, or [`undefined`](../undefined) if there is no getter. When the property is accessed, this function is called without arguments and with `this` set to the object through which the property is accessed (this may not be the object on which the property is defined due to inheritance). The return value will be used as the value of the property. **Defaults to [`undefined`](../undefined).** `set` A function which serves as a setter for the property, or [`undefined`](../undefined) if there is no setter. When the property is assigned, this function is called with one argument (the value being assigned to the property) and with `this` set to the object through which the property is assigned. **Defaults to [`undefined`](../undefined).** If a descriptor has neither of `value`, `writable`, `get` and `set` keys, it is treated as a data descriptor. If a descriptor has both \[`value` or `writable`\] and \[`get` or `set`\] keys, an exception is thrown. Bear in mind that these attributes are not necessarily the descriptor's own properties. Inherited properties will be considered as well. In order to ensure these defaults are preserved, you might freeze the [`Object`](../object) upfront, specify all options explicitly, or point to [`null`](../null) with [`Object.create(null)`](create). // using __proto__ var obj = {}; var descriptor = Object.create(null); // no inherited properties descriptor.value = 'static'; // not enumerable, not configurable, not writable as defaults Object.defineProperty(obj, 'key', descriptor); // being explicit Object.defineProperty(obj, 'key', { enumerable: false, configurable: false, writable: false, value: 'static' }); // recycling same object function withValue(value) { var d = withValue.d || ( withValue.d = { enumerable: false, writable: false, configurable: false, value: value } ); // avoiding duplicate operation for assigning value if (d.value !== value) d.value = value; return d; } // ... and ... Object.defineProperty(obj, 'key', withValue('static')); // if freeze is available, prevents adding or // removing the object prototype properties // (value, get, set, enumerable, writable, configurable) (Object.freeze || Object)(Object.prototype); ## Examples ### Creating a property When the property specified doesn't exist in the object, `Object.defineProperty()` creates a new property as described. Fields may be omitted from the descriptor, and default values for those fields are inputted. var o = {}; // Creates a new object // Example of an object property added // with defineProperty with a data property descriptor Object.defineProperty(o, 'a', { value: 37, writable: true, enumerable: true, configurable: true }); // 'a' property exists in the o object and its value is 37 // Example of an object property added // with defineProperty with an accessor property descriptor var bValue = 38; Object.defineProperty(o, 'b', { // Using shorthand method names (ES2015 feature). // This is equivalent to: // get: function() { return bValue; }, // set: function(newValue) { bValue = newValue; }, get() { return bValue; }, set(newValue) { bValue = newValue; }, enumerable: true, configurable: true }); o.b; // 38 // 'b' property exists in the o object and its value is 38 // The value of o.b is now always identical to bValue, // unless o.b is redefined // You cannot try to mix both: Object.defineProperty(o, 'conflict', { value: 0x9f91102, get() { return 0xdeadbeef; } }); // throws a TypeError: value appears // only in data descriptors, // get appears only in accessor descriptors ### Modifying a property When the property already exists, `Object.defineProperty()` attempts to modify the property according to the values in the descriptor and the object's current configuration. If the old descriptor had its `configurable` attribute set to `false` the property is said to be "non-configurable”. It is not possible to change any attribute of a non-configurable accessor property. For data properties, it is possible to modify the value if the property is writable, and it is possible to change `writable` attribute from `true` to `false`. It is not possible to switch between data and accessor property types when the property is non-configurable. A [`TypeError`](../typeerror) is thrown when attempts are made to change non-configurable property attributes (except `value` and `writable`, if permitted) unless the current and new values are the same. #### Writable attribute When the `writable` property attribute is set to `false`, the property is said to be "non-writable”. It cannot be reassigned. var o = {}; // Creates a new object Object.defineProperty(o, 'a', { value: 37, writable: false }); console.log(o.a); // logs 37 o.a = 25; // No error thrown // (it would throw in strict mode, // even if the value had been the same) console.log(o.a); // logs 37. The assignment didn't work. // strict mode (function() { 'use strict'; var o = {}; Object.defineProperty(o, 'b', { value: 2, writable: false }); o.b = 3; // throws TypeError: "b" is read-only return o.b; // returns 2 without the line above }()); As seen in the example, trying to write into the non-writable property doesn't change it but doesn't throw an error either. #### Enumerable attribute The `enumerable` property attribute defines whether the property is picked by [`Object.assign()`](assign) or [spread](../../operators/spread_syntax) operator. For non-[`Global_Objects/Symbol`](../symbol) properties it also defines whether it shows up in a [`for...in`](../../statements/for...in) loop and [`Object.keys()`](keys) or not. var o = {}; Object.defineProperty(o, 'a', { value: 1, enumerable: true }); Object.defineProperty(o, 'b', { value: 2, enumerable: false }); Object.defineProperty(o, 'c', { value: 3 }); // enumerable defaults to false o.d = 4; // enumerable defaults to true // when creating a property by setting it Object.defineProperty(o, Symbol.for('e'), { value: 5, enumerable: true }); Object.defineProperty(o, Symbol.for('f'), { value: 6, enumerable: false }); for (var i in o) { console.log(i); } // logs 'a' and 'd' (in undefined order) Object.keys(o); // ['a', 'd'] o.propertyIsEnumerable('a'); // true o.propertyIsEnumerable('b'); // false o.propertyIsEnumerable('c'); // false o.propertyIsEnumerable('d'); // true o.propertyIsEnumerable(Symbol.for('e')); // true o.propertyIsEnumerable(Symbol.for('f')); // false var p = { ...o } p.a // 1 p.b // undefined p.c // undefined p.d // 4 p[Symbol.for('e')] // 5 p[Symbol.for('f')] // undefined #### Configurable attribute The `configurable` attribute controls at the same time whether the property can be deleted from the object and whether its attributes (other than `value` and `writable`) can be changed. var o = {}; Object.defineProperty(o, 'a', { get() { return 1; }, configurable: false }); Object.defineProperty(o, 'a', { configurable: true }); // throws a TypeError Object.defineProperty(o, 'a', { enumerable: true }); // throws a TypeError Object.defineProperty(o, 'a', { set() {} }); // throws a TypeError (set was undefined previously) Object.defineProperty(o, 'a', { get() { return 1; } }); // throws a TypeError // (even though the new get does exactly the same thing) Object.defineProperty(o, 'a', { value: 12 }); // throws a TypeError // ('value' can be changed when 'configurable' is false but not in this case due to 'get' accessor) console.log(o.a); // logs 1 delete o.a; // Nothing happens console.log(o.a); // logs 1 If the `configurable` attribute of `o.a` had been `true`, none of the errors would be thrown and the property would be deleted at the end. ### Adding properties and default values It is important to consider the way default values of attributes are applied. There is often a difference between using dot notation to assign a value and using `Object.defineProperty()`, as shown in the example below. var o = {}; o.a = 1; // is equivalent to: Object.defineProperty(o, 'a', { value: 1, writable: true, configurable: true, enumerable: true }); // On the other hand, Object.defineProperty(o, 'a', { value: 1 }); // is equivalent to: Object.defineProperty(o, 'a', { value: 1, writable: false, configurable: false, enumerable: false }); ### Custom Setters and Getters The example below shows how to implement a self-archiving object. When `temperature` property is set, the `archive` array gets a log entry. function Archiver() { var temperature = null; var archive = []; Object.defineProperty(this, 'temperature', { get() { console.log('get!'); return temperature; }, set(value) { temperature = value; archive.push({ val: temperature }); } }); this.getArchive = function() { return archive; }; } var arc = new Archiver(); arc.temperature; // 'get!' arc.temperature = 11; arc.temperature = 13; arc.getArchive(); // [{ val: 11 }, { val: 13 }] In this example, a getter always returns the same value. var pattern = { get() { return 'I always return this string, ' + 'whatever you have assigned'; }, set() { this.myname = 'this is my name string'; } }; function TestDefineSetAndGet() { Object.defineProperty(this, 'myproperty', pattern); } var instance = new TestDefineSetAndGet(); instance.myproperty = 'test'; console.log(instance.myproperty); // I always return this string, whatever you have assigned console.log(instance.myname); // this is my name string ### Inheritance of properties If an accessor property is inherited, its `get` and `set` methods will be called when the property is accessed and modified on descendant objects. If these methods use a variable to store the value, this value will be shared by all objects. function myclass() { } var value; Object.defineProperty(myclass.prototype, "x", { get() { return value; }, set(x) { value = x; } }); var a = new myclass(); var b = new myclass(); a.x = 1; console.log(b.x); // 1 This can be fixed by storing the value in another property. In `get` and `set` methods, `this` points to the object which is used to access or modify the property. function myclass() { } Object.defineProperty(myclass.prototype, "x", { get() { return this.stored_x; }, set(x) { this.stored_x = x; } }); var a = new myclass(); var b = new myclass(); a.x = 1; console.log(b.x); // undefined Unlike accessor properties, value properties are always set on the object itself, not on a prototype. However, if a non-writable value property is inherited, it still prevents from modifying the property on the object. function myclass() { } myclass.prototype.x = 1; Object.defineProperty(myclass.prototype, "y", { writable: false, value: 1 }); var a = new myclass(); a.x = 2; console.log(a.x); // 2 console.log(myclass.prototype.x); // 1 a.y = 2; // Ignored, throws in strict mode console.log(a.y); // 1 console.log(myclass.prototype.y); // 1 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-object.defineproperty
      `defineProperty` 5 12 4 9 8 In Internet Explorer 8, this was only supported on DOM objects and with some non-standard behaviors. This was later fixed in Internet Explorer 9. 11.6 5.1 Also supported in Safari 5, but not on DOM objects. 1 18 4 12 6 Also supported in Safari for iOS 4.2, but not on DOM objects. 1.0 ### Redefining the `length` property of an `Array` object It is possible to redefine the [`length`](../array/length) property of arrays, subject to the usual redefinition restrictions. (The [`length`](../array/length) property is initially non-configurable, non-enumerable, and writable. Thus on an unaltered array, it's possible to change the [`length`](../array/length) property's value or to make it non-writable. It is not allowed to change its enumerability or configurability, or if it is non-writable to change its value or writability.) However, not all browsers permit this redefinition. Firefox 4 through 22 will throw a [`TypeError`](../typeerror) on any attempt whatsoever (whether permitted or not) to redefine the [`length`](../array/length) property of an array. Versions of Chrome which implement `Object.defineProperty()` in some circumstances ignore a length value different from the array's current [`length`](../array/length) property. In some circumstances changing writability seems to silently not work (and not throw an exception). Also, relatedly, some array-mutating methods like [`Array.prototype.push`](../array/push) don't respect a non-writable length. Versions of Safari which implement `Object.defineProperty()` ignore a `length` value different from the array's current [`length`](../array/length) property, and attempts to change writability execute without error but do not actually change the property's writability. Only Internet Explorer 9 and later, and Firefox 23 and later, appear to fully and correctly implement redefinition of the [`length`](../array/length) property of arrays. For now, don't rely on redefining the [`length`](../array/length) property of an array to either work, or to work in a particular manner. And even when you _can_ rely on it, [there's really no good reason to do so](https://whereswalden.com/2013/08/05/new-in-firefox-23-the-length-property-of-an-array-can-be-made-non-writable-but-you-shouldnt-do-it/). ### Internet Explorer 8 specific notes Internet Explorer 8 implemented a `Object.defineProperty()` method that could [only be used on DOM objects](https://msdn.microsoft.com/en-us/library/dd229916%28VS.85%29.aspx). A few things need to be noted: - Trying to use `Object.defineProperty()` on native objects throws an error. - Property attributes must be set to some values. The `configurable`, `enumerable` and `writable` attributes should all be set to `true` for data descriptor and `true` for `configurable`, `false` for `enumerable` for accessor descriptor.(?) Any attempt to provide other value(?) will result in an error being thrown. - Reconfiguring a property requires first deleting the property. If the property isn't deleted, it stays as it was before the reconfiguration attempt. ### Chrome 37 (and below) specific notes Chrome 37 (and below) has a [bug](https://bugs.chromium.org/p/v8/issues/detail?id=3448) where an attempt to define a "prototype" property, on a function, with `writable: false` doesn't work as expected. ## See also - [Enumerability and ownership of properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) - [`Object.defineProperties()`](defineproperties) - [`Object.propertyIsEnumerable()`](propertyisenumerable) - [`Object.getOwnPropertyDescriptor()`](getownpropertydescriptor) - `Object.prototype.watch()` - `Object.prototype.unwatch()` - [`get`](../../functions/get) - [`set`](../../functions/set) - [`Object.create()`](create) - [`Reflect.defineProperty()`](../reflect/defineproperty) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty # delete operator The JavaScript `delete` removes a property from an object; if no more references to the same property are held, it is eventually released automatically. ## Syntax delete expression Where `expression` should evaluate to a [property](https://developer.mozilla.org/en-US/docs/Glossary/property/JavaScript) reference, e.g.: delete object.property delete object['property'] ### Parameters `object` The name of an object, or an expression evaluating to an object. `property` The property to delete. ### Return value `true` for all cases except when the property is an [`own`](../global_objects/object/hasownproperty) [`non-configurable`](../errors/cant_delete) property, in which case, `false` is returned in non-strict mode. ### Exceptions Throws [`TypeError`](../global_objects/typeerror) in [`strict mode`](../strict_mode) if the property is an own non-configurable property. ## Description Unlike what common belief suggests (perhaps due to other programming languages like [delete in C++](https://docs.microsoft.com/en-us/cpp/cpp/delete-operator-cpp?view=vs-2019)), the `delete` operator has **nothing** to do with directly freeing memory. Memory management is done indirectly via breaking references. See the [memory management](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management) page for more details. The `delete` operator removes a given property from an object. On successful deletion, it will return `true`, else `false` will be returned. However, it is important to consider the following scenarios: - If the property which you are trying to delete does not exist, `delete` will not have any effect and will return `true`. - If a property with the same name exists on the object's prototype chain, then, after deletion, the object will use the property from the prototype chain (in other words, `delete` only has an effect on own properties). - Any property declared with [`var`](../statements/var) cannot be deleted from the global scope or from a function's scope. - As such, `delete` cannot delete any functions in the global scope (whether this is part from a function definition or a function expression). - Functions which are part of an object (apart from the global scope) can be deleted with `delete`. - Any property declared with [`let`](../statements/let) or [`const`](../statements/const) cannot be deleted from the scope within which they were defined. - Non-configurable properties cannot be removed. This includes properties of built-in objects like [`Math`](../global_objects/math), [`Array`](../global_objects/array), [`Object`](../global_objects/object) and properties that are created as non-configurable with methods like [`Object.defineProperty()`](../global_objects/object/defineproperty). The following snippet gives a simple example: var Employee = { age: 28, name: 'abc', designation: 'developer' } console.log(delete Employee.name); // returns true console.log(delete Employee.age); // returns true // When trying to delete a property that does // not exist, true is returned console.log(delete Employee.salary); // returns true ### Non-configurable properties When a property is marked as non-configurable, `delete` won't have any effect, and will return `false`. In strict mode this will raise a `TypeError`. var Employee = {}; Object.defineProperty(Employee, 'name', {configurable: false}); console.log(delete Employee.name); // returns false [`var`](../statements/var), [`let`](../statements/let), and [`const`](../statements/const) create non-configurable properties that cannot be deleted with the `delete` operator: var nameOther = 'XYZ'; // We can access this global property using: Object.getOwnPropertyDescriptor(window, 'nameOther'); // output: Object {value: "XYZ", // writable: true, // enumerable: true, // configurable: false} // Since "nameOther" is added using with the // var keyword, it is marked as "non-configurable" delete nameOther; // return false In strict mode, this would have raised an exception. ### Strict vs. non-strict mode When in strict mode, if `delete` is used on a direct reference to a variable, a function argument or a function name, it will throw a [`SyntaxError`](../global_objects/syntaxerror)**.** Therefore, to avoid syntax errors in strict mode, you must use the `delete` operator in the form of `delete object.property` or `delete object['property']`. Object.defineProperty(globalThis, 'variable1', { value: 10, configurable: true, }); Object.defineProperty(globalThis, 'variable2', { value: 10, configurable: false, }); // SyntaxError in strict mode. console.log(delete variable1); // true // SyntaxError in strict mode. console.log(delete variable2); // false function func(param) { // SyntaxError in strict mode. console.log(delete param); // false } // SyntaxError in strict mode. console.log(delete func); // false ### Cross-browser notes Although ECMAScript makes iteration order of objects implementation-dependent, it may appear that all major browsers support an iteration order based on the earliest added property coming first (at least for properties not on the prototype). However, in the case of Internet Explorer, when one uses `delete` on a property, some confusing behavior results, preventing other browsers from using simple objects like object literals as ordered associative arrays. In Explorer, while the property _value_ is indeed set to `undefined`, if one later adds back a property with the same name, the property will be iterated in its _old_ position--not at the end of the iteration sequence as one might expect after having deleted the property and then added it back. If you want to use an ordered associative array in a cross-browser environment, use a [`Map`](../global_objects/map) object if available, or simulate this structure with two separate arrays (one for the keys and the other for the values), or build an array of single-property objects, etc. ## Examples // Creates the property adminName on the global scope. adminName = 'xyz'; // Creates the property empCount on the global scope. // Since we are using var, this is marked as non-configurable. The same is true of let and const. var empCount = 43; EmployeeDetails = { name: 'xyz', age: 5, designation: 'Developer' }; // adminName is a property of the global scope. // It can be deleted since it is created without var, // and is therefore configurable. delete adminName; // returns true // On the contrary, empCount is not configurable // since var was used. delete empCount; // returns false // delete can be used to remove properties from objects. delete EmployeeDetails.name; // returns true // Even when the property does not exist, delete returns "true". delete EmployeeDetails.salary; // returns true // delete does not affect built-in static properties. delete Math.PI; // returns false // EmployeeDetails is a property of the global scope. // Since it was defined without "var", it is marked configurable. delete EmployeeDetails; // returns true function f() { var z = 44; // delete doesn't affect local variable names delete z; // returns false } ### `delete` and the prototype chain In the following example, we delete an own property of an object while a property with the same name is available on the prototype chain: function Foo() { this.bar = 10; } Foo.prototype.bar = 42; var foo = new Foo(); // foo.bar is associated with the // own property. console.log(foo.bar); // 10 // Delete the own property within the // foo object. delete foo.bar; // returns true // foo.bar is still available in the // prototype chain. console.log(foo.bar); // 42 // Delete the property on the prototype. delete Foo.prototype.bar; // returns true // The "bar" property can no longer be // inherited from Foo since it has been // deleted. console.log(foo.bar); // undefined ### Deleting array elements When you delete an array element, the array `length` is not affected. This holds even if you delete the last element of the array. When the `delete` operator removes an array element, that element is no longer in the array. In the following example, `trees[3]` is removed with `delete`. var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; delete trees[3]; if (3 in trees) { // this is not executed } If you want an array element to exist but have an undefined value, use the `undefined` value instead of the `delete` operator. In the following example, `trees[3]` is assigned the value `undefined`, but the array element still exists: var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; trees[3] = undefined; if (3 in trees) { // this is executed } If instead, you want to remove an array element by changing the contents of the array, use the [`splice()`](../global_objects/array/splice) method. In the following example, `trees[3]` is removed from the array completely using [`splice()`](../global_objects/array/splice): var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; trees.splice(3,1); console.log(trees); // ["redwood", "bay", "cedar", "maple"] ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-delete-operator
      `delete` 1 12 1 4 9 1 1 18 4 10.1 1 1.0 ## See also - [In depth analysis on delete](http://perfectionkills.com/understanding-delete/) - [`Reflect.deleteProperty()`](../global_objects/reflect/deleteproperty) - [`Map.prototype.delete()`](../global_objects/map/delete) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete # SyntaxError: applying the 'delete' operator to an unqualified name is deprecated The JavaScript [strict mode](../strict_mode)-only exception "applying the 'delete' operator to an unqualified name is deprecated" occurs when variables are attempted to be deleted using the `delete` operator. ## Message SyntaxError: Calling delete on expression not allowed in strict mode (Edge) SyntaxError: applying the 'delete' operator to an unqualified name is deprecated (Firefox) SyntaxError: Delete of an unqualified identifier in strict mode. (Chrome) ## Error type [`SyntaxError`](../global_objects/syntaxerror) in [strict mode](../strict_mode) only. ## What went wrong? Normal variables in JavaScript can't be deleted using the `delete` operator. In strict mode, an attempt to delete a variable will throw an error and is not allowed. The `delete` operator can only delete properties on an object. Object properties are "qualified" if they are configurable. Unlike what common belief suggests, the `delete` operator has **nothing** to do with directly freeing memory. Memory management is done indirectly via breaking references, see the [memory management](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management) page and the `delete` operator page for more details. This error only happens in [strict mode code](../strict_mode). In non-strict code, the operation just returns `false`. ## Examples ### Freeing the contents of a variable Attempting to delete a plain variable, doesn't work in JavaScript and it throws an error in strict mode: 'use strict'; var x; // ... delete x; // SyntaxError: applying the 'delete' operator to an unqualified name // is deprecated To free the contents of a variable, you can set it to [`null`](../global_objects/null): 'use strict'; var x; // ... x = null; // x can be garbage collected ## See also - `delete` - [Memory management](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management) - [TypeError: property "x" is non-configurable and can't be deleted](cant_delete) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Delete_in_strict_mode # handler.deleteProperty() The `handler.deleteProperty()` method is a trap for the [`delete`](../../../operators/delete) operator. ## Syntax const p = new Proxy(target, { deleteProperty: function(target, property) { } }); ### Parameters The following parameters are passed to the `deleteProperty()` method. `this` is bound to the handler. `target` The target object. `property` The name or [`Symbol`](../../symbol) of the property to delete. ### Return value The `deleteProperty()` method must return a [`Boolean`](../../boolean) indicating whether or not the property has been successfully deleted. ## Description The `handler.deleteProperty()` method is a trap for the [`delete`](../../../operators/delete) operator. ### Interceptions This trap can intercept these operations: - Property deletion: `delete proxy[foo]` and `delete proxy.foo` - [`Reflect.deleteProperty()`](../../reflect/deleteproperty) ### Invariants If the following invariants are violated, the proxy will throw a [`TypeError`](../../typeerror): - A property cannot be deleted, if it exists as a non-configurable own property of the target object. ## Examples ### Trapping the delete operator The following code traps the [`delete`](../../../operators/delete) operator. const p = new Proxy({}, { deleteProperty: function(target, prop) { if (prop in target){ delete target[prop] console.log('property removed: ' + prop) return true } else { console.log('property not found: ' + prop) return false } } }) let result p.a = 10 console.log('a' in p) // true result = delete p.a // "property removed: a" console.log(result) // true console.log('a' in p) // false result = delete p.a // "property not found: a" console.log(result) // false ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-proxy-object-internal-methods-and-internal-slots-delete-p
      `deleteProperty` 49 12 18 No 36 10 49 49 18 36 10 5.0 ## See also - [`Proxy`](../../proxy) - [`handler`](../proxy) - [`delete`](../../../operators/delete) operator - [`Reflect.deleteProperty()`](../../reflect/deleteproperty) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/deleteProperty # ReferenceError: deprecated caller or arguments usage The JavaScript [strict mode](../strict_mode)-only exception "deprecated caller or arguments usage" occurs when the deprecated [`Function.caller`](../global_objects/function/caller) or [`Function.arguments`](../global_objects/function/arguments) properties are used. ## Message TypeError: 'arguments', 'callee' and 'caller' are restricted function properties and cannot be accessed in this context (Edge) Warning: ReferenceError: deprecated caller usage (Firefox) Warning: ReferenceError: deprecated arguments usage (Firefox) TypeError: 'callee' and 'caller' cannot be accessed in strict mode. (Safari) ## Error type A strict-mode-only warning that a [`ReferenceError`](../global_objects/referenceerror) occurred. JavaScript execution won't be halted. ## What went wrong? In [strict mode](../strict_mode), the [`Function.caller`](../global_objects/function/caller) or [`Function.arguments`](../global_objects/function/arguments) properties are used and shouldn't be. They are deprecated, because they leak the function caller, are non-standard, hard to optimize and potentially a performance-harmful feature. ## Examples ### Deprecated `function.caller` or `arguments.callee.caller` [`Function.caller`](../global_objects/function/caller) and `arguments.callee.caller` are deprecated (see the reference articles for more information). 'use strict'; function myFunc() { if (myFunc.caller == null) { return 'The function was called from the top!'; } else { return 'This function\'s caller was ' + myFunc.caller; } } myFunc(); // Warning: ReferenceError: deprecated caller usage // "The function was called from the top!" ### `Function.arguments` [`Function.arguments`](../global_objects/function/arguments) is deprecated (see the reference article for more information). 'use strict'; function f(n) { g(n - 1); } function g(n) { console.log('before: ' + g.arguments[0]); if (n > 0) { f(n); } console.log('after: ' + g.arguments[0]); } f(2); console.log('returned: ' + g.arguments); // Warning: ReferenceError: deprecated arguments usage ## See also - [Deprecated and obsolete features](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features) - [Strict mode](../strict_mode) - [`Function.arguments`](../global_objects/function/arguments) - [`Function.caller`](../global_objects/function/caller) and `arguments.callee.caller` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Deprecated_caller_or_arguments_usage # Warning: expression closures are deprecated The JavaScript warning "expression closures are deprecated" occurs when the non-standard [expression closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Expression_closures) syntax (shorthand function syntax) is used. ## Message Warning: expression closures are deprecated ## Error type Warning. JavaScript execution won't be halted. ## What went wrong? The non-standard [expression closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Expression_closures) syntax (shorthand function syntax) is deprecated and shouldn't be used anymore. This syntax will be removed entirely in [bug 1083458](https://bugzilla.mozilla.org/show_bug.cgi?id=1083458) and scripts using it will throw a [`SyntaxError`](../global_objects/syntaxerror) then. ## Examples ### Deprecated syntax Expression closures omit curly braces or return statements from function declarations or from method definitions in objects. var x = function() 1; var obj = { count: function() 1 }; ### Standard syntax To convert the non-standard expression closures syntax to standard ECMAScript syntax, you can add curly braces and return statements. var x = function() { return 1; } var obj = { count: function() { return 1; } }; ### Standard syntax using arrow functions Alternatively, you can use [arrow functions](../functions/arrow_functions): var x = () => 1; ### Standard syntax using shorthand method syntax Expression closures can also be found with getter and setter, like this: var obj = { get x() 1, set x(v) this.v = v }; With ES2015 [method definitions](../functions/method_definitions), this can be converted to: var obj = { get x() { return 1 }, set x(v) { this.v = v } }; ## See also - [Expression closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Expression_closures) - [Arrow functions](../functions/arrow_functions) - [Method definitions](../functions/method_definitions) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Deprecated_expression_closures # SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated The JavaScript [strict mode](../strict_mode)-only exception "0-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the "0o" prefix instead" occurs when deprecated octal literals and octal escape sequences are used. ## Message SyntaxError: Octal numeric literals and escape characters not allowed in strict mode (Edge) SyntaxError: "0"-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the "0o" prefix instead ## Error type [`SyntaxError`](../global_objects/syntaxerror) in [strict mode](../strict_mode) only. ## What went wrong? Octal literals and octal escape sequences are deprecated and will throw a [`SyntaxError`](../global_objects/syntaxerror) in strict mode. With ECMAScript 2015 and later, the standardized syntax uses a leading zero followed by a lowercase or uppercase Latin letter "O" (`0o` or `0O)`. ## Examples ### "0"-prefixed octal literals "use strict"; 03; // SyntaxError: "0"-prefixed octal literals and octal escape sequences // are deprecated ### Octal escape sequences "use strict"; "\251"; // SyntaxError: "0"-prefixed octal literals and octal escape sequences // are deprecated ### Valid octal numbers Use a leading zero followed by the letter "o" or "O": 0o3; For octal escape sequences, you can use hexadecimal escape sequences instead: '\xA9'; ## See also - [Lexical grammar](../lexical_grammar#octal) - [Warning: 08/09 is not a legal ECMA-262 octal constant](bad_octal) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Deprecated_octal # SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //\# instead The JavaScript warning "Using `//@` to indicate sourceURL pragmas is deprecated. Use `//#` instead" occurs when there is a deprecated source map syntax in a JavaScript source. ## Message Warning: SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //# instead Warning: SyntaxError: Using //@ to indicate sourceMappingURL pragmas is deprecated. Use //# instead ## Error type A warning that a [`SyntaxError`](../global_objects/syntaxerror) occurred. JavaScript execution won't be halted. ## What went wrong? There is a deprecated source map syntax in a JavaScript source. JavaScript sources are often combined and minified to make delivering them from the server more efficient. With [source maps](https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/), the debugger can map the code being executed to the original source files. The source map specification changed the syntax due to a conflict with IE whenever it was found in the page after `//@cc_on` was interpreted to turn on conditional compilation in the IE JScript engine. The [conditional compilation comment](https://msdn.microsoft.com/en-us/library/8ka90k2e%28v=vs.94%29.aspx) in IE is a little known feature, but it broke source maps with [jQuery](https://bugs.jquery.com/ticket/13274) and other libraries. ## Examples ### Deprecated syntax Syntax with the "@" sign is deprecated. //@ sourceMappingURL=http://example.com/path/to/your/sourcemap.map ### Standard syntax Use the "\#" sign instead. //# sourceMappingURL=http://example.com/path/to/your/sourcemap.map Or, alternatively, you can set a [`SourceMap`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/SourceMap) header to your JavaScript file to avoid having a comment at all: SourceMap: /path/to/file.js.map ## See also - [How to use a source map – Firefox Tools documentation](https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map) - [Introduction to source maps – HTML5 rocks](https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/) - [`SourceMap`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/SourceMap) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Deprecated_source_map_pragma # Warning: String.x is deprecated; use String.prototype.x instead The JavaScript warning about string generics occurs in Firefox versions prior to 68. String generics have been removed starting with Firefox 68. ## Message Warning: String.charAt is deprecated; use String.prototype.charAt instead Warning: String.charCodeAt is deprecated; use String.prototype.charCodeAt instead Warning: String.concat is deprecated; use String.prototype.concat instead Warning: String.contains is deprecated; use String.prototype.contains instead Warning: String.endsWith is deprecated; use String.prototype.endsWith instead Warning: String.includes is deprecated; use String.prototype.includes instead Warning: String.indexOf is deprecated; use String.prototype.indexOf instead Warning: String.lastIndexOf is deprecated; use String.prototype.lastIndexOf instead Warning: String.localeCompare is deprecated; use String.prototype.localeCompare instead Warning: String.match is deprecated; use String.prototype.match instead Warning: String.normalize is deprecated; use String.prototype.normalize instead Warning: String.replace is deprecated; use String.prototype.replace instead Warning: String.search is deprecated; use String.prototype.search instead Warning: String.slice is deprecated; use String.prototype.slice instead Warning: String.split is deprecated; use String.prototype.split instead Warning: String.startsWith is deprecated; use String.prototype.startsWith instead Warning: String.substr is deprecated; use String.prototype.substr instead Warning: String.substring is deprecated; use String.prototype.substring instead Warning: String.toLocaleLowerCase is deprecated; use String.prototype.toLocaleLowerCase instead Warning: String.toLocaleUpperCase is deprecated; use String.prototype.toLocaleUpperCase instead Warning: String.toLowerCase is deprecated; use String.prototype.toLowerCase instead Warning: String.toUpperCase is deprecated; use String.prototype.toUpperCase instead Warning: String.trim is deprecated; use String.prototype.trim instead Warning: String.trimLeft is deprecated; use String.prototype.trimLeft instead Warning: String.trimRight is deprecated; use String.prototype.trimRight instead ## Error type Warning. JavaScript execution won't be halted. ## What went wrong? The non-standard generic [`String`](../global_objects/string) methods are deprecated and have been removed in Firefox 68 and later. String generics provide `String` instance methods on the `String` object allowing `String` methods to be applied to any object. ## Examples ### Deprecated syntax var num = 15; String.replace(num, /5/, '2'); ### Standard syntax var num = 15; String(num).replace(/5/, '2'); ## Shim The following is a shim to provide support to non-supporting browsers: /*globals define*/ // Assumes all supplied String instance methods already present // (one may use shims for these if not available) (function() { 'use strict'; var i, // We could also build the array of methods with the following, but the // getOwnPropertyNames() method is non-shimable: // Object.getOwnPropertyNames(String).filter(function(methodName) { // return typeof String[methodName] === 'function'; // }); methods = [ 'contains', 'substring', 'toLowerCase', 'toUpperCase', 'charAt', 'charCodeAt', 'indexOf', 'lastIndexOf', 'startsWith', 'endsWith', 'trim', 'trimLeft', 'trimRight', 'toLocaleLowerCase', 'normalize', 'toLocaleUpperCase', 'localeCompare', 'match', 'search', 'slice', 'replace', 'split', 'substr', 'concat', 'localeCompare' ], methodCount = methods.length, assignStringGeneric = function(methodName) { var method = String.prototype[methodName]; String[methodName] = function(arg1) { return method.apply(arg1, Array.prototype.slice.call(arguments, 1)); }; }; for (i = 0; i < methodCount; i++) { assignStringGeneric(methods[i]); } }()); ## See also - [`String`](../global_objects/string) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Deprecated_String_generics # Warning: Date.prototype.toLocaleFormat is deprecated The JavaScript warning "Date.prototype.toLocaleFormat is deprecated; consider using Intl.DateTimeFormat instead" occurs when the non-standard `Date.prototype.toLocaleFormat` method is used. ## Message Warning: Date.prototype.toLocaleFormat is deprecated; consider using Intl.DateTimeFormat instead ## Error type Warning. JavaScript execution won't be halted. ## What went wrong? The non-standard `Date.prototype.toLocaleFormat` method is deprecated and shouldn't be used anymore. It uses a format string in the same format expected by the `strftime()` function in C. **The function is no longer available in Firefox 58+**. ## Examples ### Deprecated syntax The `Date.prototype.toLocaleFormat` method is deprecated and will be removed (no cross-browser support, available in Firefox only). var today = new Date(); var date = today.toLocaleFormat('%A, %e. %B %Y'); console.log(date); // In German locale // "Freitag, 10. März 2017" ### Alternative standard syntax using the ECMAScript Intl API The ECMA-402 (ECMAScript Intl API) standard specifies standard objects and methods that enable language sensitive date and time formatting (available in Chrome 24+, Firefox 29+, IE11+, Safari10+). You can now either use the [`Date.prototype.toLocaleDateString`](../global_objects/date/tolocaledatestring) method if you just want to format one date. var today = new Date(); var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; var date = today.toLocaleDateString('de-DE', options); console.log(date); // "Freitag, 10. März 2017" Or, you can make use of the [`Intl.DateTimeFormat`](../global_objects/intl/datetimeformat) object, which allows you to cache an object with most of the computations done so that formatting is fast. This is useful if you have a loop of dates to format. var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; var dateFormatter = new Intl.DateTimeFormat('de-DE', options) var dates = [Date.UTC(2012, 11, 20, 3, 0, 0), Date.UTC(2014, 04, 12, 8, 0, 0)]; dates.forEach(date => console.log(dateFormatter.format(date))); // "Donnerstag, 20. Dezember 2012" // "Montag, 12. Mai 2014" ### Alternative standard syntax using Date methods The [`Date`](../global_objects/date) object offers several methods to build a custom date string. (new Date()).toLocaleFormat("%Y%m%d"); // "20170310" Can be converted to: let now = new Date(); let date = now.getFullYear() * 10000 + (now.getMonth() + 1) * 100 + now.getDate(); console.log(date); // "20170310" ## See also - `Date.prototype.toLocaleFormat` - [`Date.prototype.toLocaleDateString`](../global_objects/date/tolocaledatestring) - [`Intl.DateTimeFormat`](../global_objects/intl/datetimeformat) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Deprecated_toLocaleFormat # Symbol.prototype.description The read-only `description` property is a string returning the optional description of [`Symbol`](../symbol) objects. ## Description [`Symbol`](../symbol) objects can be created with an optional description which can be used for debugging but not to access the symbol itself. The `Symbol.prototype.description` property can be used to read that description. It is different to `Symbol.prototype.toString()` as it does not contain the enclosing "`Symbol()`" string. See the examples. ## Examples ### Using description Symbol('desc').toString(); // "Symbol(desc)" Symbol('desc').description; // "desc" Symbol('').description; // "" Symbol().description; // undefined // well-known symbols Symbol.iterator.toString(); // "Symbol(Symbol.iterator)" Symbol.iterator.description; // "Symbol.iterator" // global symbols Symbol.for('foo').toString(); // "Symbol(foo)" Symbol.for('foo').description; // "foo" ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-symbol.prototype.description
      `description` 70 79 63 No 57 12.1 12 No support for an undefined description. 70 70 63 49 12.2 12 No support for an undefined description. 10.0 ## See also - [`Symbol.prototype.toString()`](tostring) - Polyfill: © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/description # Destructuring assignment The **destructuring assignment** syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables. ## Syntax let a, b, rest; [a, b] = [10, 20]; console.log(a); // 10 console.log(b); // 20 [a, b, ...rest] = [10, 20, 30, 40, 50]; console.log(a); // 10 console.log(b); // 20 console.log(rest); // [30, 40, 50] ({ a, b } = { a: 10, b: 20 }); console.log(a); // 10 console.log(b); // 20 // Stage 4(finished) proposal ({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}); console.log(a); // 10 console.log(b); // 20 console.log(rest); // {c: 30, d: 40} ## Description The object and array literal expressions provide an easy way to create _ad hoc_ packages of data. const x = [1, 2, 3, 4, 5]; The destructuring assignment uses similar syntax, but on the left-hand side of the assignment to define what values to unpack from the sourced variable. const x = [1, 2, 3, 4, 5]; const [y, z] = x; console.log(y); // 1 console.log(z); // 2 Similarly, you can destructure arrays on the left-hand side of the assignment const [firstElement, secondElement] = list; // is equivalent to: // const firstElement = list[0]; // const secondElement = list[1]; This capability is similar to features present in languages such as Perl and Python. ## Examples ### Array destructuring #### Basic variable assignment const foo = ['one', 'two', 'three']; const [red, yellow, green] = foo; console.log(red); // "one" console.log(yellow); // "two" console.log(green); // "three" #### Assignment separate from declaration A variable can be assigned its value via destructuring, separate from the variable's declaration. let a, b; [a, b] = [1, 2]; console.log(a); // 1 console.log(b); // 2 #### Default values A variable can be assigned a default, in the case that the value unpacked from the array is `undefined`. let a, b; [a=5, b=7] = [1]; console.log(a); // 1 console.log(b); // 7 #### Swapping variables Two variables values can be swapped in one destructuring expression. Without destructuring assignment, swapping two values requires a temporary variable (or, in some low-level languages, the [XOR-swap trick](https://en.wikipedia.org/wiki/XOR_swap_algorithm)). let a = 1; let b = 3; [a, b] = [b, a]; console.log(a); // 3 console.log(b); // 1 const arr = [1,2,3]; [arr[2], arr[1]] = [arr[1], arr[2]]; console.log(arr); // [1,3,2] #### Parsing an array returned from a function It's always been possible to return an array from a function. Destructuring can make working with an array return value more concise. In this example, `f()` returns the values `[1, 2]` as its output, which can be parsed in a single line with destructuring. function f() { return [1, 2]; } let a, b; [a, b] = f(); console.log(a); // 1 console.log(b); // 2 #### Ignoring some returned values You can ignore return values that you're not interested in: function f() { return [1, 2, 3]; } const [a, , b] = f(); console.log(a); // 1 console.log(b); // 3 const [c] = f(); console.log(c); // 1 You can also ignore all returned values: [,,] = f(); #### Assigning the rest of an array to a variable When destructuring an array, you can unpack and assign the remaining part of it to a variable using the rest pattern: const [a, ...b] = [1, 2, 3]; console.log(a); // 1 console.log(b); // [2, 3] Be aware that a [`SyntaxError`](../global_objects/syntaxerror) will be thrown if a trailing comma is used on the right-hand side of a rest element: const [a, ...b,] = [1, 2, 3]; // SyntaxError: rest element may not have a trailing comma // Always consider using rest operator as the last element #### Unpacking values from a regular expression match When the regular expression ` exec()` method finds a match, it returns an array containing first the entire matched portion of the string and then the portions of the string that matched each parenthesized group in the regular expression. Destructuring assignment allows you to unpack the parts out of this array easily, ignoring the full match if it is not needed. function parseProtocol(url) { const parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url); if (!parsedURL) { return false; } console.log(parsedURL); // ["https://developer.mozilla.org/en-US/docs/Web/JavaScript", "https", "developer.mozilla.org", "en-US/docs/Web/JavaScript"] const [, protocol, fullhost, fullpath] = parsedURL; return protocol; } console.log(parseProtocol('https://developer.mozilla.org/en-US/docs/Web/JavaScript')); // "https" ### Object destructuring #### Basic assignment const user = { id: 42, is_verified: true }; const {id, is_verified} = user; console.log(id); // 42 console.log(is_verified); // true #### Assignment without declaration A variable can be assigned its value with destructuring separate from its declaration. let a, b; ({a, b} = {a: 1, b: 2}); **Note:** The parentheses `( ... )` around the assignment statement are required when using object literal destructuring assignment without a declaration. `{a, b} = {a: 1, b: 2}` is not valid stand-alone syntax, as the `{a, b}` on the left-hand side is considered a block and not an object literal. However, `({a, b} = {a: 1, b: 2})` is valid, as is `const {a, b} = {a: 1, b: 2}` Your `( ... )` expression needs to be preceded by a semicolon or it may be used to execute a function on the previous line. #### Assigning to new variable names A property can be unpacked from an object and assigned to a variable with a different name than the object property. const o = {p: 42, q: true}; const {p: foo, q: bar} = o; console.log(foo); // 42 console.log(bar); // true Here, for example, `const {p: foo} = o` takes from the object `o` the property named `p` and assigns it to a local variable named `foo`. #### Default values A variable can be assigned a default, in the case that the value unpacked from the object is `undefined`. const {a = 10, b = 5} = {a: 3}; console.log(a); // 3 console.log(b); // 5 #### Assigning to new variables names and providing default values A property can be both - Unpacked from an object and assigned to a variable with a different name. - Assigned a default value in case the unpacked value is `undefined`. const {a: aa = 10, b: bb = 5} = {a: 3}; console.log(aa); // 3 console.log(bb); // 5 #### Unpacking fields from objects passed as a function parameter const user = { id: 42, displayName: 'jdoe', fullName: { firstName: 'John', lastName: 'Doe' } }; function userId({id}) { return id; } function whois({displayName, fullName: {firstName: name}}) { return `${displayName} is ${name}`; } console.log(userId(user)); // 42 console.log(whois(user)); // "jdoe is John" This unpacks the `id`, `displayName` and `firstName` from the user object and prints them. #### Setting a function parameter's default value function drawChart({size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}) { console.log(size, coords, radius); // do some chart drawing } drawChart({ coords: {x: 18, y: 30}, radius: 30 }); **Note:** In the function signature for `drawChart` above, the destructured left-hand side is assigned to an empty object literal on the right-hand side: `{size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}`. You could have also written the function without the right-hand side assignment. However, if you leave out the right-hand side assignment, the function will look for at least one argument to be supplied when invoked, whereas in its current form, you can call `drawChart()` without supplying any parameters. The current design is useful if you want to be able to call the function without supplying any parameters, the other can be useful when you want to ensure an object is passed to the function. #### Nested object and array destructuring const metadata = { title: 'Scratchpad', translations: [ { locale: 'de', localization_tags: [], last_edit: '2014-04-14T08:43:37', url: '/de/docs/Tools/Scratchpad', title: 'JavaScript-Umgebung' } ], url: '/en-US/docs/Tools/Scratchpad' }; let { title: englishTitle, // rename translations: [ { title: localeTitle, // rename }, ], } = metadata; console.log(englishTitle); // "Scratchpad" console.log(localeTitle); // "JavaScript-Umgebung" #### For of iteration and destructuring const people = [ { name: 'Mike Smith', family: { mother: 'Jane Smith', father: 'Harry Smith', sister: 'Samantha Smith' }, age: 35 }, { name: 'Tom Jones', family: { mother: 'Norah Jones', father: 'Richard Jones', brother: 'Howard Jones' }, age: 25 } ]; for (const {name: n, family: {father: f}} of people) { console.log('Name: ' + n + ', Father: ' + f); } // "Name: Mike Smith, Father: Harry Smith" // "Name: Tom Jones, Father: Richard Jones" #### Computed object property names and destructuring Computed property names, like on [object literals](object_initializer#computed_property_names), can be used with destructuring. let key = 'z'; let {[key]: foo} = {z: 'bar'}; console.log(foo); // "bar" #### Rest in Object Destructuring The [Rest/Spread Properties for ECMAScript](https://github.com/tc39/proposal-object-rest-spread) proposal (stage 4) adds the [rest](../functions/rest_parameters) syntax to destructuring. Rest properties collect the remaining own enumerable property keys that are not already picked off by the destructuring pattern. let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40} a; // 10 b; // 20 rest; // { c: 30, d: 40 } #### Invalid JavaScript identifier as a property name Destructuring can be used with property names that are not valid JavaScript [identifiers](https://developer.mozilla.org/en-US/docs/Glossary/Identifier) by providing an alternative identifier that is valid. const foo = { 'fizz-buzz': true }; const { 'fizz-buzz': fizzBuzz } = foo; console.log(fizzBuzz); // "true" #### Combined Array and Object Destructuring Array and Object destructuring can be combined. Say you want the third element in the array `props` below, and then you want the `name` property in the object, you can do the following: const props = [ { id: 1, name: 'Fizz'}, { id: 2, name: 'Buzz'}, { id: 3, name: 'FizzBuzz'} ]; const [,, { name }] = props; console.log(name); // "FizzBuzz" #### The prototype chain is looked up when the object is deconstructed When deconstructing an object, if a property is not accessed in itself, it will continue to look up along the prototype chain. let obj = {self: '123'}; obj.__proto__.prot = '456'; const {self, prot} = obj; // self "123" // prot "456" (Access to the prototype chain) ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-destructuring-assignment
      `Destructuring_assignment` 49 14 41 Firefox provided a non-standard destructuring implementation from Firefox 2 to 40. No 36 8 49 49 41 Firefox provided a non-standard destructuring implementation from Firefox 2 to 40. 36 8 5.0 `computed_property_names` 49 14 41 No 36 10 49 49 41 36 10 5.0 `rest_in_arrays` 49 16 14 41 No 36 9.1 49 49 41 36 9.3 5.0 `rest_in_objects` 60 79 55 No 47 11.1 60 60 55 44 11.3 8.0 ## See also - [Assignment operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#Assignment_operators) - ["ES6 in Depth: Destructuring" on hacks.mozilla.org](https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment # Function.displayName **Non-standard** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future. The `function.displayName` property returns the display name of the function. ## Examples ### Setting a displayName It is usually preferred by consoles and profilers over [`func.name`](name) to display the name of a function. By entering the following in a console, it should display as something like "`function My Function()`": var a = function() {}; a.displayName = 'My Function'; a; // "function My Function()" When defined, the `displayName` property returns the display name of a function: function doSomething() {} console.log(doSomething.displayName); // "undefined" var popup = function(content) { console.log(content); }; popup.displayName = 'Show Popup'; console.log(popup.displayName); // "Show Popup" ### Defining a displayName in function expressions You can define a function with a display name in a [function expression](../../functions): var object = { someMethod: function() {} }; object.someMethod.displayName = 'someMethod'; console.log(object.someMethod.displayName); // logs "someMethod" try { someMethod } catch(e) { console.log(e); } // ReferenceError: someMethod is not defined ### Changing displayName dynamically You can dynamically change the `displayName` of a function: var object = { // anonymous someMethod: function(value) { arguments.callee.displayName = 'someMethod (' + value + ')'; } }; console.log(object.someMethod.displayName); // "undefined" object.someMethod('123') console.log(object.someMethod.displayName); // "someMethod (123)" ## Specifications Not part of any standard. `displayName` No No 13 No No No No No 14 No No No ## See also - [`Function.name`](name) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/displayName # Intl.DisplayNames The `Intl.DisplayNames` object enables the consistent translation of language, region and script display names. ## Constructor [`Intl.DisplayNames()`](displaynames/displaynames) Creates a new `Intl.DisplayNames` object. ## Static methods [`Intl.DisplayNames.supportedLocalesOf()`](displaynames/supportedlocalesof) Returns an array containing those of the provided locales that are supported without having to fall back to the runtime's default locale. ## Instance methods [`Intl.DisplayNames.prototype.of()`](displaynames/of) This method receives a `code` and returns a string based on the locale and options provided when instantiating `Intl.DisplayNames`. [`Intl.DisplayNames.prototype.resolvedOptions()`](displaynames/resolvedoptions) Returns a new object with properties reflecting the locale and formatting options computed during initialization of the object. ## Examples ### Region Code Display Names To create an `Intl.DisplayNames` for a locale and get the display name for a region code. // Get display names of region in English let regionNames = new Intl.DisplayNames(['en'], {type: 'region'}); regionNames.of('419'); // "Latin America" regionNames.of('BZ'); // "Belize" regionNames.of('US'); // "United States" regionNames.of('BA'); // "Bosnia & Herzegovina" regionNames.of('MM'); // "Myanmar (Burma)" // Get display names of region in Traditional Chinese regionNames = new Intl.DisplayNames(['zh-Hant'], {type: 'region'}); regionNames.of('419'; // "拉丁美洲" regionNames.of('BZ'); // "貝里斯" regionNames.of('US'); // "美國" regionNames.of('BA'); // "波士尼亞與赫塞哥維納" regionNames.of('MM'); // "緬甸" ### Language Display Names To create an `Intl.DisplayNames` for a locale and get the display name for a language-script-region sequence. // Get display names of language in English let languageNames = new Intl.DisplayNames(['en'], {type: 'language'}); languageNames.of('fr'); // "French" languageNames.of('de'); // "German" languageNames.of('fr-CA'); // "Canadian French" languageNames.of('zh-Hant'); // "Traditional Chinese" languageNames.of('en-US'); // "American English" languageNames.of('zh-TW'); // "Chinese (Taiwan)"] // Get display names of language in Traditional Chinese languageNames = new Intl.DisplayNames(['zh-Hant'], {type: 'language'}); languageNames.of('fr'); // "法文" languageNames.of('zh'); // "中文" languageNames.of('de'); // "德文" ### Script Code Display Names To create an `Intl.DisplayNames` for a locale and get the display name for a script code. // Get display names of script in English let scriptNames = new Intl.DisplayNames(['en'], {type: 'script'}); // Get script names scriptNames.of('Latn'); // "Latin" scriptNames.of('Arab'); // "Arabic" scriptNames.of('Kana'); // "Katakana" // Get display names of script in Traditional Chinese scriptNames = new Intl.DisplayNames(['zh-Hant'], {type: 'script'}); scriptNames.of('Latn'); // "拉丁文" scriptNames.of('Arab'); // "阿拉伯文" scriptNames.of('Kana'); // "片假名" ### Currency Code Display Names To create an `Intl.DisplayNames` for a locale and get the display name for currency code. // Get display names of currency code in English let currencyNames = new Intl.DisplayNames(['en'], {type: 'currency'}); // Get currency names currencyNames.of('USD'); // "US Dollar" currencyNames.of('EUR'); // "Euro" currencyNames.of('TWD'); // "New Taiwan Dollar" currencyNames.of('CNY'); // "Chinese Yuan" // Get display names of currency code in Traditional Chinese currencyNames = new Intl.DisplayNames(['zh-Hant'], {type: 'currency'}); currencyNames.of('USD'); // "美元" currencyNames.of('EUR'); // "歐元" currencyNames.of('TWD'); // "新台幣" currencyNames.of('CNY'); // "人民幣" ## Specifications
      Specification
      ECMAScript Internationalization API Specification (ECMAScript Internationalization API)
      #intl-displaynames-objects
      `DisplayNames` 81 81 86 No 68 14.1 81 81 86 58 14.5 No `DisplayNames` 81 81 86 No 68 14.1 81 81 86 58 14.5 No `of` 81 81 86 No 68 14.1 81 81 86 58 14.5 No `resolvedOptions` 81 81 86 No 68 14.1 81 81 86 58 14.5 No `supportedLocalesOf` 81 81 86 No 68 14.1 81 81 86 58 14.5 No ## See also - [`Intl`](../intl) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames # Division (/) The division operator (`/`) produces the quotient of its operands where the left operand is the dividend and the right operand is the divisor. ## Syntax Operator: x / y ## Examples ### Basic division 1 / 2 // 0.5 Math.floor(3 / 2) // 1 1.0 / 2.0 // 0.5 ### Division by zero 2.0 / 0 // Infinity 2.0 / 0.0 // Infinity, because 0.0 === 0 2.0 / -0.0 // -Infinity ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Division operator' in that specification.
      `Division` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Addition operator](addition) - [Subtraction operator](subtraction) - [Multiplication operator](multiplication) - [Remainder operator](remainder) - [Exponentiation operator](exponentiation) - [Increment operator](increment) - [Decrement operator](decrement) - [Unary negation operator](unary_negation) - [Unary plus operator](unary_plus) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division # do...while The `do...while` creates a loop that executes a specified statement until the test condition evaluates to false. The condition is evaluated after executing the statement, resulting in the specified statement executing at least once. ## Syntax do statement while (condition); `statement` A statement that is executed at least once and is re-executed each time the condition evaluates to true. To execute multiple statements within the loop, use a [block](block) statement (`{ ... }`) to group those statements. `condition` An expression evaluated after each pass through the loop. If `condition` evaluates to true, the `statement` is re-executed. When `condition` evaluates to false, control passes to the statement following the `do...while`. ## Examples ### Using `do...while` In the following example, the `do...while` loop iterates at least once and reiterates until `i` is no longer less than 5. var result = ''; var i = 0; do { i += 1; result += i + ' '; } while (i > 0 && i < 5); // Despite i == 0 this will still loop as it starts off without the test console.log(result); ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-do-while-statement
      `do...while` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 ## See also - [`while`](while) - [`for`](for) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/do...while # RegExp.prototype.dotAll The `dotAll` property indicates whether or not the "`s`" flag is used with the regular expression. `dotAll` is a read-only property of an individual regular expression instance. Property attributes of `RegExp.prototype.dotAll` Writable no Enumerable no Configurable yes ## Description The value of `dotAll` is a [`Boolean`](../boolean) and `true` if the "`s`" flag was used; otherwise, `false`. The "`s`" flag indicates that the dot special character ("`.`") should additionally match the following line terminator ("newline") characters in a string, which it would not match otherwise: - U+000A LINE FEED (LF) ("`\n`") - U+000D CARRIAGE RETURN (CR) ("`\r`") - U+2028 LINE SEPARATOR - U+2029 PARAGRAPH SEPARATOR This effectively means the dot will match any character on the Unicode Basic Multilingual Plane (BMP). To allow it to match astral characters, the "`u`" (unicode) flag should be used. Using both flags in conjunction allows the dot to match any Unicode character, without exceptions. You cannot change this property directly. ## Examples ### Using `dotAll` var str1 = 'bar\nexample foo example'; var regex1 = new RegExp('bar.example','s'); console.log(regex1.dotAll); // Output: true console.log(str1.replace(regex1,'')); // Output: foo example var str2 = 'bar\nexample foo example'; var regex2 = new RegExp('bar.example'); console.log(regex2.dotAll); // Output: false console.log(str2.replace(regex2,'')); // Output: bar // example foo example ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-get-regexp.prototype.dotAll
      `dotAll` 62 79 78 No 49 12 62 62 79 46 12 8.0 ## See also - [`RegExp.lastIndex`](lastindex) - [`RegExp.prototype.global`](global) - [`RegExp.prototype.hasIndices`](hasindices) - [`RegExp.prototype.ignoreCase`](ignorecase) - [`RegExp.prototype.multiline`](multiline) - [`RegExp.prototype.source`](source) - [`RegExp.prototype.sticky`](sticky) - [`RegExp.prototype.unicode`](unicode) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/dotAll # Math.E The `Math.E` property represents Euler's number, the base of natural logarithms, e, which is approximately 2.718. ` M``a``t``h``.``E ` = *e* ≈ 2.718 Property attributes of `Math.E` Writable no Enumerable no Configurable no ## Description Because `E` is a static property of `Math`, you always use it as `Math.E`, rather than as a property of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.E The following function returns e: function getNapier() { return Math.E; } getNapier(); // 2.718281828459045 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.e
      `E` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`Math.exp()`](exp) - [`Math.log()`](log) - [`Math.log1p()`](log1p) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/E # empty An **empty statement** is used to provide no statement, although the JavaScript syntax would expect one. ## Syntax ; ## Description The empty statement is a semicolon (`;`) indicating that no statement will be executed, even if JavaScript syntax requires one. The opposite behavior, where you want multiple statements, but JavaScript only allows a single one, is possible using a [block statement](block), which combines several statements into a single one. ## Examples ### Empty loop body The empty statement is sometimes used with loop statements. See the following example with an empty loop body: let arr = [1, 2, 3]; // Assign all array values to 0 for (let i = 0; i < arr.length; arr[i++] = 0) /* empty statement */ ; console.log(arr); // [0, 0, 0] ### Unintentional usage It is a good idea to comment _intentional_ use of the empty statement, as it is not really obvious to distinguish from a normal semicolon. In the following example, the usage is probably not intentional: if (condition); // Caution, this "if" does nothing! killTheUniverse() // So this always gets executed!!! In the next example, an [`if...else`](if...else) statement without curly braces (`{}`) is used. If `three` is `true`, nothing will happen, `four` does not matter, and also the `launchRocket()` function in the `else` case will not be executed. if (one) doOne(); else if (two) doTwo(); else if (three) ; // nothing here else if (four) doFour(); else launchRocket(); ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-empty-statement
      `Empty` 3 12 1 3 3 5 1 18 4 10.1 4.2 1.0 ## See also - [`Block statement`](block) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/Empty # encodeURI() The `encodeURI()` function encodes a [URI](https://developer.mozilla.org/en-US/docs/Glossary/URI) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the [UTF-8](https://developer.mozilla.org/en-US/docs/Glossary/UTF-8) encoding of the character (will only be four escape sequences for characters composed of two "surrogate" characters). ## Syntax encodeURI(URI) ### Parameters `URI` A complete URI. ### Return value A new string representing the provided string encoded as a URI. ## Description The `encodeURI()` function does not encode characters that have special meaning (reserved characters) for a URI. The following example shows all the parts that a URI "scheme" can possibly contain. Note how certain characters are used to signify special meaning: http://username:password@www.example.com:80/path/to/file.php?foo=316&bar=this+has+spaces#anchor Hence `encodeURI()` **does not** encode characters that are necessary to formulate a complete URI. Also, `encodeURI()` **does not** encode a few additional characters, known as "unreserved marks", which do not have a reserved purpose but are allowed in a URI "as is". (See [RFC2396)](https://www.ietf.org/rfc/rfc2396.txt) `encodeURI()` escapes all characters **except**: Not Escaped: A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) # ## Examples ### encodeURI vs encodeURIComponent `encodeURI()` differs from [`encodeURIComponent()`](encodeuricomponent) as follows: var set1 = ";,/?:@&=+$#"; // Reserved Characters var set2 = "-_.!~*'()"; // Unreserved Marks var set3 = "ABC abc 123"; // Alphanumeric Characters + Space console.log(encodeURI(set1)); // ;,/?:@&=+$# console.log(encodeURI(set2)); // -_.!~*'() console.log(encodeURI(set3)); // ABC%20abc%20123 (the space gets encoded as %20) console.log(encodeURIComponent(set1)); // %3B%2C%2F%3F%3A%40%26%3D%2B%24%23 console.log(encodeURIComponent(set2)); // -_.!~*'() console.log(encodeURIComponent(set3)); // ABC%20abc%20123 (the space gets encoded as %20) Note that `encodeURI()` by itself _cannot_ form proper HTTP [`GET`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET) and [`POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) requests, such as for [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest), because "`&`", "`+`", and "`=`" are not encoded, which are treated as special characters in `GET` and `POST` requests. `encodeURIComponent()`, however, does encode these characters. ### Encoding a lone high surrogate throws An [`URIError`](urierror) will be thrown if one attempts to encode a surrogate which is not part of a high-low pair, e.g., // high-low pair ok console.log(encodeURI('\uD800\uDFFF')); // lone high surrogate throws "URIError: malformed URI sequence" console.log(encodeURI('\uD800')); // lone low surrogate throws "URIError: malformed URI sequence" console.log(encodeURI('\uDFFF')); ### Encoding for IPv6 If one wishes to follow the more recent [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986) for URLs, which makes square brackets reserved (for [IPv6](https://developer.mozilla.org/en-US/docs/Glossary/IPv6)) and thus not encoded when forming something which could be part of a URL (such as a host), the following code snippet may help: function fixedEncodeURI(str) { return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']'); } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-encodeuri-uri
      `encodeURI` 1 12 1 5.5 7 1.1 1 18 4 10.1 1 1.0 ## See also - [`decodeURI()`](decodeuri) - [`encodeURIComponent()`](encodeuricomponent) - [`decodeURIComponent()`](decodeuricomponent) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI # encodeURIComponent() The `encodeURIComponent()` function encodes a [URI](https://developer.mozilla.org/en-US/docs/Glossary/URI) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the [UTF-8](https://developer.mozilla.org/en-US/docs/Glossary/UTF-8) encoding of the character (will only be four escape sequences for characters composed of two "surrogate" characters). ## Syntax encodeURIComponent(str); ### Parameters `str` String. A component of a URI. ### Return value A new string representing the provided string encoded as a URI component. ## Description `encodeURIComponent()` escapes all characters **except**: Not Escaped: A-Z a-z 0-9 - _ . ! ~ * ' ( ) `encodeURIComponent()` differs from `encodeURI` as follows: var set1 = ";,/?:@&=+$"; // Reserved Characters var set2 = "-_.!~*'()"; // Unescaped Characters var set3 = "#"; // Number Sign var set4 = "ABC abc 123"; // Alphanumeric Characters + Space console.log(encodeURI(set1)); // ;,/?:@&=+$ console.log(encodeURI(set2)); // -_.!~*'() console.log(encodeURI(set3)); // # console.log(encodeURI(set4)); // ABC%20abc%20123 (the space gets encoded as %20) console.log(encodeURIComponent(set1)); // %3B%2C%2F%3F%3A%40%26%3D%2B%24 console.log(encodeURIComponent(set2)); // -_.!~*'() console.log(encodeURIComponent(set3)); // %23 console.log(encodeURIComponent(set4)); // ABC%20abc%20123 (the space gets encoded as %20) Note that a [`URIError`](urierror) will be thrown if one attempts to encode a surrogate which is not part of a high-low pair, e.g., // high-low pair ok console.log(encodeURIComponent('\uD800\uDFFF')); // lone high surrogate throws "URIError: malformed URI sequence" console.log(encodeURIComponent('\uD800')); // lone low surrogate throws "URIError: malformed URI sequence" console.log(encodeURIComponent('\uDFFF')); Use `encodeURIComponent()` on user-entered fields from forms [`POST`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST)'d to the server. This will encode `&` symbols that may inadvertently be generated during data entry for special HTML entities or other characters that require encoding/decoding. For example, if a user writes `Jack & Jill`, the text may get encoded as `Jack & Jill`. Without `encodeURIComponent()` the ampersand could be interpretted on the server as the start of a new field and jeopardize the integrity of the data. For [`application/x-www-form-urlencoded`](https://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#application/x-www-form-urlencoded-encoding-algorithm), spaces are to be replaced by `+`, so one may wish to follow a `encodeURIComponent()` replacement with an additional replacement of `%20` with `+`. To be more stringent in adhering to [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) (which reserves !, ', (, ), and \*), even though these characters have no formalized URI delimiting uses, the following can be safely used: function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); }); } ## Examples ### Encoding for Content-Disposition and Link headers The following example provides the special encoding required within UTF-8 [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) and [`Link`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link) server response header parameters (e.g., UTF-8 filenames): var fileName = 'my file(2).txt'; var header = "Content-Disposition: attachment; filename*=UTF-8''" + encodeRFC5987ValueChars(fileName); console.log(header); // logs "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt" function encodeRFC5987ValueChars(str) { return encodeURIComponent(str). // Note that although RFC3986 reserves "!", RFC5987 does not, // so we do not need to escape it replace(/['()]/g, escape). // i.e., %27 %28 %29 replace(/\*/g, '%2A'). // The following are not required for percent-encoding per RFC5987, // so we can allow for a little better readability over the wire: |`^ replace(/%(?:7C|60|5E)/g, unescape); } // here is an alternative to the above function function encodeRFC5987ValueChars2(str) { return encodeURIComponent(str). // Note that although RFC3986 reserves "!", RFC5987 does not, // so we do not need to escape it replace(/['()*]/g, c => "%" + c.charCodeAt(0).toString(16)). // i.e., %27 %28 %29 %2a (Note that valid encoding of "*" is %2A // which necessitates calling toUpperCase() to properly encode) // The following are not required for percent-encoding per RFC5987, // so we can allow for a little better readability over the wire: |`^ replace(/%(7C|60|5E)/g, (str, hex) => String.fromCharCode(parseInt(hex, 16))); } ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'encodeURIComponent' in that specification.
      `encodeURIComponent` 1 12 1 5.5 7 1.1 1 18 4 10.1 1 1.0 ## See also - [`decodeURI`](decodeuri) - [`encodeURI`](encodeuri) - [`decodeURIComponent`](decodeuricomponent) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent # String.prototype.endsWith() The `endsWith()` method determines whether a string ends with the characters of a specified string, returning `true` or `false` as appropriate. ## Syntax endsWith(searchString) endsWith(searchString, length) ### Parameters `searchString` The characters to be searched for at the end of `str`. `length` Optional If provided, it is used as the length of `str`. Defaults to `str.length`. ### Return value `true` if the given characters are found at the end of the string; otherwise, `false`. ## Description This method lets you determine whether or not a string ends with another string. This method is case-sensitive. ## Examples ### Using endsWith() let str = 'To be, or not to be, that is the question.' console.log(str.endsWith('question.')) // true console.log(str.endsWith('to be')) // false console.log(str.endsWith('to be', 19)) // true ## Polyfill This method has been added to the ECMAScript 6 specification and may not be available in all JavaScript implementations yet. However, you can polyfill `String.prototype.endsWith()` with the following snippet: if (!String.prototype.endsWith) { String.prototype.endsWith = function(search, this_len) { if (this_len === undefined || this_len > this.length) { this_len = this.length; } return this.substring(this_len - search.length, this_len) === search; }; } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-string.prototype.endswith
      `endsWith` 41 12 17 No 28 9 ≤37 36 17 24 9 3.0 ## See also - [`String.prototype.startsWith()`](startswith) - [`String.prototype.includes()`](includes) - [`String.prototype.indexOf()`](indexof) - [`String.prototype.lastIndexOf()`](lastindexof) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith # Object.entries() The `Object.entries()` method returns an array of a given object's own enumerable string-keyed property `[key, value]` pairs, in the same order as that provided by a [`for...in`](../../statements/for...in) loop. (The only important difference is that a `for...in` loop enumerates properties in the prototype chain as well). The order of the array returned by `Object.entries()` does not depend on how an object is defined. If there is a need for certain ordering, then the array should be sorted first, like `Object.entries(obj).sort((a, b) => b[0].localeCompare(a[0]));`. ## Syntax Object.entries(obj) ### Parameters `obj` The object whose own enumerable string-keyed property `[key, value]` pairs are to be returned. ### Return value An array of the given object's own enumerable string-keyed property `[key, value]` pairs. ## Description `Object.entries()` returns an array whose elements are arrays corresponding to the enumerable string-keyed property `[key, value]` pairs found directly upon `object`. The ordering of the properties is the same as that given by looping over the property values of the object manually. ## Polyfill To add compatible `Object.entries()` support in older environments that do not natively support it, you can use any of the following: - a demonstration implementation of `Object.entries` in the [tc39/proposal-object-values-entries](https://github.com/tc39/proposal-object-values-entries) (if you don't need any support for IE); - a polyfill in the [es-shims/Object.entries](https://github.com/es-shims/Object.entries) repositories; - or, you can use the simple, ready-to-deploy polyfill listed below: if (!Object.entries) { Object.entries = function( obj ){ var ownProps = Object.keys( obj ), i = ownProps.length, resArray = new Array(i); // preallocate the Array while (i--) resArray[i] = [ownProps[i], obj[ownProps[i]]]; return resArray; }; } For the above polyfill code snippet, if you need support for IE<9, then you will also need an `Object.keys()` polyfill (such as the one found on the [`Object.keys`](keys) page). ## Examples const obj = { foo: 'bar', baz: 42 }; console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ] // array like object const obj = { 0: 'a', 1: 'b', 2: 'c' }; console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ] // array like object with random key ordering const anObj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ] // getFoo is property which isn't enumerable const myObj = Object.create({}, { getFoo: { value() { return this.foo; } } }); myObj.foo = 'bar'; console.log(Object.entries(myObj)); // [ ['foo', 'bar'] ] // non-object argument will be coerced to an object console.log(Object.entries('foo')); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ] // returns an empty array for any primitive type except for strings (see the above example), since primitives have no own properties console.log(Object.entries(100)); // [ ] // iterate through key-value gracefully const obj = { a: 5, b: 7, c: 9 }; for (const [key, value] of Object.entries(obj)) { console.log(`${key}${value}`); // "a 5", "b 7", "c 9" } // Or, using array extras Object.entries(obj).forEach(([key, value]) => { console.log(`${key}${value}`); // "a 5", "b 7", "c 9" }); ### Converting an `Object` to a `Map` The [`new Map()`](../map) constructor accepts an iterable of `entries`. With `Object.entries`, you can easily convert from [`Object`](../object) to [`Map`](../map): const obj = { foo: 'bar', baz: 42 }; const map = new Map(Object.entries(obj)); console.log(map); // Map(2) {"foo" => "bar", "baz" => 42} ### Iterating through an `Object` Using [Array Destructuring](../../operators/destructuring_assignment#array_destructuring), you can iterate through objects easily. const obj = { foo: 'bar', baz: 42 }; Object.entries(obj).forEach(([key, value]) => console.log(`${key}: ${value}`)); // "foo: bar", "baz: 42" ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Object.entries' in that specification.
      `entries` 54 14 47 No 41 10.1 54 54 47 41 10.3 6.0 ## See also - [Enumerability and ownership of properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) - [`Object.keys()`](keys) - [`Object.values()`](values) - [`Object.prototype.propertyIsEnumerable()`](propertyisenumerable) - [`Object.create()`](create) - [`Object.fromEntries()`](fromentries) - [`Object.getOwnPropertyNames()`](getownpropertynames) - [`Map.prototype.entries()`](../map/entries) - [`Map.prototype.keys()`](../map/keys) - [`Map.prototype.values()`](../map/values) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries # Number.EPSILON The `Number.EPSILON` property represents the difference between 1 and the smallest floating point number greater than 1. You do not have to create a [`Number`](../number) object to access this static property (use `Number.EPSILON`). Property attributes of `Number.EPSILON` Writable no Enumerable no Configurable no ## Description The `EPSILON` property has a value of approximately `2.2204460492503130808472633361816E-16`, or `2-52`. ## Examples ### Testing equality x = 0.2; y = 0.3; z = 0.1; equal = (Math.abs(x - y + z) < Number.EPSILON); ## Polyfill if (Number.EPSILON === undefined) { Number.EPSILON = Math.pow(2, -52); } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-number.epsilon
      `EPSILON` 34 12 25 No 21 9 ≤37 34 25 21 9 2.0 ## See also - The [`Number`](../number) object it belongs to © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON # SyntaxError: test for equality (==) mistyped as assignment (=)? The JavaScript warning "test for equality (==) mistyped as assignment (=)?" occurs when there was an assignment (`=`) when you would normally expect a test for equality (`==`). ## Message Warning: SyntaxError: test for equality (==) mistyped as assignment (=)? ## Error type (Firefox only) [`SyntaxError`](../global_objects/syntaxerror) warning which is reported only if `javascript.options.strict` preference is set to `true`. ## What went wrong? There was an assignment (`=`) when you would normally expect a test for equality (`==`). To help debugging, JavaScript (with strict warnings enabled) warns about this pattern. ## Examples ### Assignment within conditional expressions It is advisable to not use simple assignments in a conditional expression (such as `if...else`), because the assignment can be confused with equality when glancing over the code. For example, do not use the following code: if (x = y) { // do the right thing } If you need to use an assignment in a conditional expression, a common practice is to put additional parentheses around the assignment. For example: if ((x = y)) { // do the right thing } Otherwise, you probably meant to use a comparison operator (e.g. `==` or `===`): if (x == y) { // do the right thing } ## See also - `if...else` - [Comparison operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Equal_as_assign # Equality (==) The equality operator (`==`) checks whether its two operands are equal, returning a Boolean result. Unlike the [strict equality](strict_equality) operator, it attempts to convert and compare operands that are of different types. ## Syntax x == y ## Description The equality operators (`==` and `!=`) use the [Abstract Equality Comparison Algorithm](https://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3) to compare two operands. This can be roughly summarised as follows: - If the operands are both objects, return `true` only if both operands reference the same object. - If one operand is `null` and the other is `undefined`, return `true`. - If the operands are of different types, try to convert them to the same type before comparing: - When comparing a number to a string, try to convert the string to a numeric value. - If one of the operands is `Boolean`, convert the Boolean operand to 1 if it is `true` and +0 if it is `false`. - If one of the operands is an object and the other is a number or a string, try to convert the object to a primitive using the object's `valueOf()` and `toString()` methods. - If the operands have the same type, they are compared as follows: - `String`: return `true` only if both operands have the same characters in the same order. - `Number`: return `true` only if both operands have the same value. `+0` and `-0` are treated as the same value. If either operand is `NaN`, return `false`. - `Boolean`: return `true` only if operands are both `true` or both `false`. The most notable difference between this operator and the [strict equality](strict_equality) (`===`) operator is that the strict equality operator does not attempt type conversion. Instead, the strict equality operator always considers operands of different types to be different. ## Examples ### Comparison with no type conversion 1 == 1; // true "hello" == "hello"; // true ### Comparison with type conversion "1" == 1; // true 1 == "1"; // true 0 == false; // true 0 == null; // false 0 == undefined; // false 0 == !!null; // true, look at Logical NOT operator 0 == !!undefined; // true, look at Logical NOT operator null == undefined; // true const number1 = new Number(3); const number2 = new Number(3); number1 == 3; // true number1 == number2; // false ### Comparison of objects const object1 = {"key": "value"} const object2 = {"key": "value"}; object1 == object2 // false object2 == object2 // true ### Comparing strings and String objects Note that strings constructed using `new String()` are objects. If you compare one of these with a string literal, the `String` object will be converted to a string literal and the contents will be compared. However, if both operands are `String` objects, then they are compared as objects and must reference the same object for comparison to succeed: const string1 = "hello"; const string2 = String("hello"); const string3 = new String("hello"); const string4 = new String("hello"); console.log(string1 == string2); // true console.log(string1 == string3); // true console.log(string2 == string3); // true console.log(string3 == string4); // false console.log(string4 == string4); // true ### Comparing Dates and strings const d = new Date('December 17, 1995 03:24:00'); const s = d.toString(); // for example: "Sun Dec 17 1995 03:24:00 GMT-0800 (Pacific Standard Time)" console.log(d == s); //true ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-equality-operators
      `Equality` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Inequality operator](inequality) - [Strict equality operator](strict_equality) - [Strict inequality operator](strict_inequality) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Equality # Error `Error` objects are thrown when runtime errors occur. The `Error` object can also be used as a base object for user-defined exceptions. See below for standard built-in error types. ## Description Runtime errors result in new `Error` objects being created and thrown. ### Error types Besides the generic `Error` constructor, there are other core error constructors in JavaScript. For client-side exceptions, see [Exception handling statements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#exception_handling_statements). [`EvalError`](evalerror) Creates an instance representing an error that occurs regarding the global function [`eval()`](eval). [`RangeError`](rangeerror) Creates an instance representing an error that occurs when a numeric variable or parameter is outside of its valid range. [`ReferenceError`](referenceerror) Creates an instance representing an error that occurs when de-referencing an invalid reference. [`SyntaxError`](syntaxerror) Creates an instance representing a syntax error. [`TypeError`](typeerror) Creates an instance representing an error that occurs when a variable or parameter is not of a valid type. [`URIError`](urierror) Creates an instance representing an error that occurs when [`encodeURI()`](encodeuri) or [`decodeURI()`](decodeuri) are passed invalid parameters. [`AggregateError`](aggregateerror) Creates an instance representing several errors wrapped in a single error when multiple errors need to be reported by an operation, for example by [`Promise.any()`](promise/any). [`InternalError`](internalerror) This API has not been standardized. Creates an instance representing an error that occurs when an internal error in the JavaScript engine is thrown. E.g. "too much recursion". ## Constructor [`Error()`](error/error) Creates a new `Error` object. ## Static methods `Error.captureStackTrace()` A non-standard **V8** function that creates the [`stack`](error/stack) property on an Error instance. ## Instance properties [`Error.prototype.message`](error/message) Error message. [`Error.prototype.name`](error/name) Error name. `Error.prototype.description` A non-standard Microsoft property for the error description. Similar to [`message`](error/message). `Error.prototype.number` A non-standard Microsoft property for an error number. [`Error.prototype.fileName`](error/filename) A non-standard Mozilla property for the path to the file that raised this error. [`Error.prototype.lineNumber`](error/linenumber) A non-standard Mozilla property for the line number in the file that raised this error. [`Error.prototype.columnNumber`](error/columnnumber) A non-standard Mozilla property for the column number in the line that raised this error. [`Error.prototype.stack`](error/stack) A non-standard Mozilla property for a stack trace. ## Instance methods [`Error.prototype.toString()`](error/tostring) Returns a string representing the specified object. Overrides the [`Object.prototype.toString()`](object/tostring) method. ## Examples ### Throwing a generic error Usually you create an `Error` object with the intention of raising it using the [`throw`](../statements/throw) keyword. You can handle the error using the [`try...catch`](../statements/try...catch) construct: try { throw new Error('Whoops!') } catch (e) { console.error(e.name + ': ' + e.message) } ### Handling a specific error You can choose to handle only specific error types by testing the error type with the error's [`constructor`](object/constructor) property or, if you're writing for modern JavaScript engines, [`instanceof`](../operators/instanceof) keyword: try { foo.bar() } catch (e) { if (e instanceof EvalError) { console.error(e.name + ': ' + e.message) } else if (e instanceof RangeError) { console.error(e.name + ': ' + e.message) } // ... etc } ### Custom Error Types You might want to define your own error types deriving from `Error` to be able to `throw new MyError()` and use `instanceof MyError` to check the kind of error in the exception handler. This results in cleaner and more consistent error handling code. See ["What's a good way to extend Error in JavaScript?"](https://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript) on StackOverflow for an in-depth discussion. #### ES6 Custom Error Class **Warning:** Versions of Babel prior to 7 can handle `CustomError` class methods, but only when they are declared with [Object.defineProperty()](object/defineproperty). Otherwise, old versions of Babel and other transpilers will not correctly handle the following code without [additional configuration](https://github.com/loganfsmyth/babel-plugin-transform-builtin-extend). **Note:** Some browsers include the `CustomError` constructor in the stack trace when using ES2015 classes. class CustomError extends Error { constructor(foo = 'bar', ...params) { // Pass remaining arguments (including vendor specific ones) to parent constructor super(...params) // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(this, CustomError) } this.name = 'CustomError' // Custom debugging information this.foo = foo this.date = new Date() } } try { throw new CustomError('baz', 'bazMessage') } catch(e) { console.error(e.name) //CustomError console.error(e.foo) //baz console.error(e.message) //bazMessage console.error(e.stack) //stacktrace } #### ES5 Custom Error Object **Warning:** All browsers include the `CustomError` constructor in the stack trace when using a prototypal declaration. function CustomError(foo, message, fileName, lineNumber) { var instance = new Error(message, fileName, lineNumber); instance.name = 'CustomError'; instance.foo = foo; Object.setPrototypeOf(instance, Object.getPrototypeOf(this)); if (Error.captureStackTrace) { Error.captureStackTrace(instance, CustomError); } return instance; } CustomError.prototype = Object.create(Error.prototype, { constructor: { value: Error, enumerable: false, writable: true, configurable: true } }); if (Object.setPrototypeOf){ Object.setPrototypeOf(CustomError, Error); } else { CustomError.__proto__ = Error; } try { throw new CustomError('baz', 'bazMessage'); } catch(e){ console.error(e.name); //CustomError console.error(e.foo); //baz console.error(e.message); //bazMessage } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-error-objects
      `Error` 1 12 1 6 4 1 1 18 4 10.1 1 1.0 `Error` 1 12 1 6 4 1 1 18 4 10.1 1 1.0 `columnNumber` No No 1 No No No No No 4 No No No `fileName` No No 1 No No No No No 4 No No No `lineNumber` No No 1 No No No No No 4 No No No `message` 1 12 1 6 5 1 1 18 4 10.1 1 1.0 `name` 1 12 1 6 4 1 1 18 4 10.1 1 1.0 `stack` 3 12 1 10 10.5 6 ≤37 18 4 11 6 1.0 `toSource` No No 1-74 Starting in Firefox 74, `toSource()` is no longer available for use by web content. It is still allowed for internal and privileged code. No No No No No 4 No No No `toString` 1 12 1 6 4 1 1 18 4 10.1 1 1.0 ## See also - [`throw`](../statements/throw) - [`try...catch`](../statements/try...catch) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error # JavaScript error reference Below, you'll find a list of errors which are thrown by JavaScript. These errors can be a helpful debugging aid, but the reported problem isn't always immediately clear. The pages below will provide additional details about these errors. Each error is an object based upon the [`Error`](global_objects/error) object, and has a `name` and a `message`. Errors displayed in the Web console may include a link to the corresponding page below to help you quickly comprehend the problem in your code. For a beginner's introductory tutorial on fixing JavaScript errors, see [What went wrong? Troubleshooting JavaScript](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong). ## List of errors In this list, each page is listed by name (the type of error) and message (a more detailed human-readable error message). Together, these two properties provide a starting point toward understanding and resolving the error. For more information, follow the links below! - [Error: Permission denied to access property "x"](errors/property_access_denied) - [InternalError: too much recursion](errors/too_much_recursion) - [RangeError: argument is not a valid code point](errors/not_a_codepoint) - [RangeError: invalid array length](errors/invalid_array_length) - [RangeError: invalid date](errors/invalid_date) - [RangeError: precision is out of range](errors/precision_range) - [RangeError: radix must be an integer](errors/bad_radix) - [RangeError: repeat count must be less than infinity](errors/resulting_string_too_large) - [RangeError: repeat count must be non-negative](errors/negative_repetition_count) - [ReferenceError: "x" is not defined](errors/not_defined) - [ReferenceError: assignment to undeclared variable "x"](errors/undeclared_var) - [ReferenceError: can't access lexical declaration\`X' before initialization](errors/cant_access_lexical_declaration_before_init) - [ReferenceError: deprecated caller or arguments usage](errors/deprecated_caller_or_arguments_usage) - [ReferenceError: invalid assignment left-hand side](errors/invalid_assignment_left-hand_side) - [ReferenceError: reference to undefined property "x"](errors/undefined_prop) - [SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated](errors/deprecated_octal) - [SyntaxError: "use strict" not allowed in function with non-simple parameters](errors/strict_non_simple_params) - [SyntaxError: "x" is a reserved identifier](errors/reserved_identifier) - [SyntaxError: JSON.parse: bad parsing](errors/json_bad_parse) - [SyntaxError: Malformed formal parameter](errors/malformed_formal_parameter) - [SyntaxError: Unexpected '\#' used outside of class body](errors/hash_outside_class) - [SyntaxError: Unexpected token](errors/unexpected_token) - [SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //\# instead](errors/deprecated_source_map_pragma) - [SyntaxError: a declaration in the head of a for-of loop can't have an initializer](errors/invalid_for-of_initializer) - [SyntaxError: applying the 'delete' operator to an unqualified name is deprecated](errors/delete_in_strict_mode) - [SyntaxError: for-in loop head declarations may not have initializers](errors/invalid_for-in_initializer) - [SyntaxError: function statement requires a name](errors/unnamed_function_statement) - [SyntaxError: identifier starts immediately after numeric literal](errors/identifier_after_number) - [SyntaxError: illegal character](errors/illegal_character) - [SyntaxError: invalid regular expression flag "x"](errors/bad_regexp_flag) - [SyntaxError: missing ) after argument list](errors/missing_parenthesis_after_argument_list) - [SyntaxError: missing ) after condition](errors/missing_parenthesis_after_condition) - [SyntaxError: missing : after property id](errors/missing_colon_after_property_id) - [SyntaxError: missing ; before statement](errors/missing_semicolon_before_statement) - [SyntaxError: missing = in const declaration](errors/missing_initializer_in_const) - [SyntaxError: missing \] after element list](errors/missing_bracket_after_list) - [SyntaxError: missing formal parameter](errors/missing_formal_parameter) - [SyntaxError: missing name after . operator](errors/missing_name_after_dot_operator) - [SyntaxError: missing variable name](errors/no_variable_name) - [SyntaxError: missing } after function body](errors/missing_curly_after_function_body) - [SyntaxError: missing } after property list](errors/missing_curly_after_property_list) - [SyntaxError: redeclaration of formal parameter "x"](errors/redeclared_parameter) - [SyntaxError: return not in function](errors/bad_return_or_yield) - [SyntaxError: test for equality (==) mistyped as assignment (=)?](errors/equal_as_assign) - [SyntaxError: unterminated string literal](errors/unterminated_string_literal) - [TypeError: "x" has no properties](errors/no_properties) - [TypeError: "x" is (not) "y"](errors/unexpected_type) - [TypeError: "x" is not a constructor](errors/not_a_constructor) - [TypeError: "x" is not a function](errors/not_a_function) - [TypeError: "x" is not a non-null object](errors/no_non-null_object) - [TypeError: "x" is read-only](errors/read-only) - [TypeError: 'x' is not iterable](errors/is_not_iterable) - [TypeError: More arguments needed](errors/more_arguments_needed) - [TypeError: Reduce of empty array with no initial value](errors/reduce_of_empty_array_with_no_initial_value) - [TypeError: X.prototype.y called on incompatible type](errors/called_on_incompatible_type) - [TypeError: can't access dead object](errors/dead_object) - [TypeError: can't access property "x" of "y"](errors/cant_access_property) - [TypeError: can't assign to property "x" on "y": not an object](errors/cant_assign_to_property) - [TypeError: can't define property "x": "obj" is not extensible](errors/cant_define_property_object_not_extensible) - [TypeError: can't delete non-configurable array element](errors/non_configurable_array_element) - [TypeError: can't redefine non-configurable property "x"](errors/cant_redefine_property) - [TypeError: cannot use 'in' operator to search for 'x' in 'y'](errors/in_operator_no_object) - [TypeError: cyclic object value](errors/cyclic_object_value) - [TypeError: invalid 'instanceof' operand 'x'](errors/invalid_right_hand_side_instanceof_operand) - [TypeError: invalid Array.prototype.sort argument](errors/array_sort_argument) - [TypeError: invalid arguments](errors/typed_array_invalid_arguments) - [TypeError: invalid assignment to const "x"](errors/invalid_const_assignment) - [TypeError: property "x" is non-configurable and can't be deleted](errors/cant_delete) - [TypeError: setting getter-only property "x"](errors/getter_only) - [TypeError: variable "x" redeclares argument](errors/var_hides_argument) - [URIError: malformed URI sequence](errors/malformed_uri) - [Warning: 08/09 is not a legal ECMA-262 octal constant](errors/bad_octal) - [Warning: -file- is being assigned a //\# sourceMappingURL, but already has one](errors/already_has_pragma) - [Warning: Date.prototype.toLocaleFormat is deprecated](errors/deprecated_tolocaleformat) - [Warning: JavaScript 1.6's for-each-in loops are deprecated](errors/for-each-in_loops_are_deprecated) - [Warning: String.x is deprecated; use String.prototype.x instead](errors/deprecated_string_generics) - [Warning: expression closures are deprecated](errors/deprecated_expression_closures) - [Warning: unreachable code after return statement](errors/stmt_after_return) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors # 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()!](#never_use_eval!), below. The `eval()` function evaluates JavaScript code represented as a string. ## Syntax eval(string) ### Parameters `string` A string representing a JavaScript expression, statement, or sequence of statements. The expression can include variables and properties of existing objects. ### Return value The completion value of evaluating the given code. If the completion value is empty, [`undefined`](undefined) is returned. ## Description `eval()` is a function property of the global object. The argument of the `eval()` function is a string. If the string represents an expression, `eval()` evaluates the expression. If the argument represents one or more JavaScript statements, `eval()` evaluates the statements. Do not call `eval()` to evaluate an arithmetic expression; JavaScript evaluates arithmetic expressions automatically. If you construct an arithmetic expression as a string, you can use `eval()` to evaluate it at a later time. For example, suppose you have a variable `x`. You can postpone evaluation of an expression involving `x` by assigning the string value of the expression, say "`3 * x + 2`", to a variable, and then calling `eval()` at a later point in your script. If the argument of `eval()` is not a string, `eval()` returns the argument unchanged. In the following example, the `String` constructor is specified and `eval()` returns a `String` object rather than evaluating the string. eval(new String('2 + 2')); // returns a String object containing "2 + 2" eval('2 + 2'); // returns 4 You can work around this limitation in a generic fashion by using `toString()`. var expression = new String('2 + 2'); eval(expression.toString()); // returns 4 If you use the `eval` function _indirectly,_ by invoking it via a reference other than `eval`, [as of ECMAScript 5](https://www.ecma-international.org/ecma-262/5.1/#sec-10.4.2) it works in the global scope rather than the local scope. This means, for instance, that function declarations create global functions, and that the code being evaluated doesn't have access to local variables within the scope where it's being called. function test() { var x = 2, y = 4; // Direct call, uses local scope console.log(eval('x + y')); // Result is 6 // Indirect call using the comma operator to return eval console.log((0, eval)('x + y')); // Uses global scope, throws because x is undefined // Indirect call using a variable to store and return eval var geval = eval; console.log(geval('x + y')); // Uses global scope, throws because x is undefined } ## Never use eval()! `eval()` is a dangerous function, which 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, a third-party code can see the scope in which `eval()` was invoked, which can lead to possible attacks in ways to which the similar [`Function`](function) is not susceptible. `eval()` is also slower than the alternatives, since it has to invoke the JavaScript interpreter, while many other constructs are optimized by modern JS engines. Additionally, 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. Fortunately, there's a very good alternative to `eval()`: using [`window.Function()`](function). See this example of how to convert code using a dangerous `eval()` to using `Function()`, see below. Bad code with `eval()`: function looseJsonParse(obj){ return eval("(" + obj + ")"); } console.log(looseJsonParse( "{a:(4-1), b:function(){}, c:new Date()}" )) Better code without `eval()`: function looseJsonParse(obj){ return Function('"use strict";return (' + obj + ')')(); } console.log(looseJsonParse( "{a:(4-1), b:function(){}, c:new Date()}" )) Comparing the two code snippets above, the two code snippets might seem to work the same way, but think again: the `eval()` one is a great deal slower. Notice `c: new Date()` in the evaluated object. In the function without the `eval()`, the object is being evaluated in the global scope, so it is safe for the browser to assume that `Date` refers to `window.Date()` instead of a local variable called `Date`. But, in the code using `eval()`, the browser cannot assume this since what if your code looked like the following: function Date(n){ return ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"][n%7 || 0]; } function looseJsonParse(obj){ 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()`. This is incredibly inefficient compared to `Function()`. In a related circumstance, what if you actually wanted your `Date()` function to be able to be called from the code inside `Function()`. Should you just take the easy way out and fall back to `eval()`? No! Never. Instead try the approach below. function Date(n){ return ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"][n%7 || 0]; } function runCodeWithDateFunction(obj){ return Function('"use strict";return (' + obj + ')')()( Date ); } console.log(runCodeWithDateFunction( "function(Date){ return Date(5) }" )) The code above may seem inefficiently slow because of the triple nested function, but let's analyze the benefits of the above efficient method: - It allows the code in the string passed to `runCodeWithDateFunction()` to be minified. - Function call overhead is minimal, making the far smaller code size well worth the benefit - `Function()` more easily allows your code to utilize the performance buttering `"use strict";` - The code does not use `eval()`, making it orders of magnitude faster than otherwise. Lastly, let's examine minification. With using `Function()` as shown above, you can minify the code string passed to `runCodeWithDateFunction()` far more efficiently because the function arguments names can be minified too as seen in the minified code below. console.log(Function('"use strict";return(function(a){return a(5)})')()(function(a){ return"Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" ")[a%7||0]})); There are also additional safer (and faster!) alternatives to `eval()` or `Function()` for common use-cases. ### Accessing member properties You should not use `eval()` to convert property names into properties. 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()`: var obj = { a: 20, b: 30 }; var propName = getPropName(); // returns "a" or "b" eval( 'var result = obj.' + propName ); However, `eval()` is not necessary here. In fact, its use here is discouraged. Instead, use the [property accessors](../operators/property_accessors), which are much faster and safer: var obj = { a: 20, b: 30 }; var propName = getPropName(); // returns "a" or "b" var 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: var obj = {a: {b: {c: 0}}}; var propPath = getPropPath(); // returns e.g. "a.b.c" eval( 'var result = obj.' + propPath ); Avoiding `eval()` here could be done by splitting the property path and looping through the different properties: function getDescendantProp(obj, desc) { var arr = desc.split('.'); while (arr.length) { obj = obj[arr.shift()]; } return obj; } var obj = {a: {b: {c: 0}}}; var propPath = getPropPath(); // returns e.g. "a.b.c" var result = getDescendantProp(obj, propPath); Setting a property that way works similarly: function setDescendantProp(obj, desc, value) { var arr = desc.split('.'); while (arr.length > 1) { obj = obj[arr.shift()]; } return obj[arr[0]] = value; } var obj = {a: {b: {c: 0}}}; var propPath = getPropPath(); // returns e.g. "a.b.c" var result = setDescendantProp(obj, propPath, 1); // obj.a.b.c will now be 1 ### Use functions instead of evaluating snippets of code JavaScript has [first-class functions](https://en.wikipedia.org/wiki/First-class_function), 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: // instead of setTimeout(" ... ", 1000) use: setTimeout(function() { ... }, 1000); // instead of elt.setAttribute("onclick", "...") use: elt.addEventListener('click', function() { ... } , false); [Closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) are also helpful as a way to create parameterized functions without concatenating strings. ### Parsing JSON (converting strings to JavaScript objects) 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](https://developer.mozilla.org/en-US/docs/Glossary/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. ### Pass data instead of code For example, an extension designed to scrape contents of web-pages could have the scraping rules defined in [XPath](https://developer.mozilla.org/en-US/docs/Web/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`". var x = 2; var y = 39; var z = '42'; eval('x + y + 1'); // returns 42 eval(z); // returns 42 ### Using `eval` to evaluate a string of JavaScript statements The following example uses `eval()` to evaluate the string `str`. This string consists of JavaScript statements that assigns `z` a value of 42 if `x` is five, and assigns 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`. var x = 5; var str = "if (x == 5) {console.log('z is 42'); z = 42;} else z = 0;"; console.log('z is ', eval(str)); If you define multiple values then the last value is returned. var x = 5; var 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 ### Last expression is evaluated `eval()` returns the value of the last expression evaluated. var str = 'if ( a ) { 1 + 1; } else { 1 + 2; }'; var a = true; var b = eval(str); // returns 2 console.log('b is : ' + b); a = false; b = eval(str); // returns 3 console.log('b is : ' + b); ### `eval` as a string defining function requires "(" and ")" as prefix and suffix var fctStr1 = 'function a() {}' var fctStr2 = '(function a() {})' var fct1 = eval(fctStr1) // return undefined var fct2 = eval(fctStr2) // return a function ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-eval-x
      `eval` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`uneval()`](uneval) - [Property accessors](../operators/property_accessors) - [WebExtensions: Using eval in content scripts]() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval # EvalError The `EvalError` object indicates an error regarding the global [`eval()`](eval) function. This exception is not thrown by JavaScript anymore, however the `EvalError` object remains for compatibility. ## Constructor [`EvalError()`](evalerror/evalerror) Creates a new `EvalError` object. ## Instance properties [`EvalError.prototype.message`](error/message) Error message. Although ECMA-262 specifies that [`EvalError`](evalerror) should provide its own `message` property, in [SpiderMonkey](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey), it inherits [`Error.prototype.message`](error/message). [`EvalError.prototype.name`](error/name) Error name. Inherited from [`Error`](error). [`EvalError.prototype.fileName`](error/filename) Path to file that raised this error. Inherited from [`Error`](error). [`EvalError.prototype.lineNumber`](error/linenumber) Line number in file that raised this error. Inherited from [`Error`](error). [`EvalError.prototype.columnNumber`](error/columnnumber) Column number in line that raised this error. Inherited from [`Error`](error). [`EvalError.prototype.stack`](error/stack) Stack trace. Inherited from [`Error`](error). ## Examples `EvalError` is not used in the current ECMAScript specification and will thus not be thrown by the runtime. However, the object itself remains for backwards compatibility with earlier versions of the specification. ### Creating an EvalError try { throw new EvalError('Hello', 'someFile.js', 10); } catch (e) { console.log(e instanceof EvalError); // true console.log(e.message); // "Hello" console.log(e.name); // "EvalError" console.log(e.fileName); // "someFile.js" console.log(e.lineNumber); // 10 console.log(e.columnNumber); // 0 console.log(e.stack); // "@Scratchpad/2:2:9\n" } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-native-error-types-used-in-this-standard-evalerror
      `EvalError` 1 12 1 5.5 5 1 1 18 4 10.1 1 1.0 `EvalError` 1 12 1 5.5 5 1 1 18 4 10.1 1 1.0 ## See also - [`Error`](error) - [`eval()`](eval) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError # Array.prototype.every() The `every()` method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value. ## Syntax // Arrow function every((element) => { ... } ) every((element, index) => { ... } ) every((element, index, array) => { ... } ) // Callback function every(callbackFn) every(callbackFn, thisArg) // Inline callback function every(function callbackFn(element) { ... }) every(function callbackFn(element, index) { ... }) every(function callbackFn(element, index, array){ ... }) every(function callbackFn(element, index, array) { ... }, thisArg) ### Parameters `callbackFn` A function to test for each element, taking three arguments: `element` The current element being processed in the array. `index` Optional The index of the current element being processed in the array. `array` Optional The array `every` was called upon. `thisArg` Optional A value to use as `this` when executing `callbackFn`. ### Return value `true` if the `callbackFn` function returns a [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) value for every array element. Otherwise, `false`. ## Description The `every` method executes the provided `callbackFn` function once for each element present in the array until it finds the one where `callbackFn` returns a [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) value. If such an element is found, the `every` method immediately returns `false`. Otherwise, if `callbackFn` returns a [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) value for all elements, `every` returns `true`. **Note:** Calling this method on an empty array will return `true` for any condition! `callbackFn` is invoked only for array indexes which have assigned values. It is not invoked for indexes which have been deleted, or which have never been assigned values. `callbackFn` is invoked with three arguments: the value of the element, the index of the element, and the Array object being traversed. If a `thisArg` parameter is provided to `every`, it will be used as callback's `this` value. Otherwise, the value `undefined` will be used as its `this` value. The `this` value ultimately observable by `callback` is determined according to [the usual rules for determining the `this` seen by a function](../../operators/this). `every` does not mutate the array on which it is called. The range of elements processed by `every` is set before the first invocation of `callbackFn`. Therefore, `callbackFn` will not run on elements that are appended to the array after the call to `every` begins. If existing elements of the array are changed, their value as passed to `callbackFn` will be the value at the time `every` visits them. Elements that are deleted are not visited. `every` acts like the "for all" quantifier in mathematics. In particular, for an empty array, it returns `true`. (It is [vacuously true](https://en.wikipedia.org/wiki/Vacuous_truth) that all elements of the [empty set](https://en.wikipedia.org/wiki/Empty_set#Properties) satisfy any given condition.) ## Polyfill `every` was added to the ECMA-262 standard in the 5th edition, and it may not be present in other implementations of the standard. You can work around this by inserting the following code at the beginning of your scripts, allowing use of `every` in implementations which do not natively support it. This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming `Object` and `TypeError` have their original values, and that `callbackfn.call` evaluates to the original value of [`Function.prototype.call`](../function/call). if (!Array.prototype.every) { Array.prototype.every = function(callbackfn, thisArg) { 'use strict'; var T, k; if (this == null) { throw new TypeError('this is null or not defined'); } // 1. Let O be the result of calling ToObject passing the this // value as the argument. var O = Object(this); // 2. Let lenValue be the result of calling the Get internal method // of O with the argument "length". // 3. Let len be ToUint32(lenValue). var len = O.length >>> 0; // 4. If IsCallable(callbackfn) is false, throw a TypeError exception. if (typeof callbackfn !== 'function' && Object.prototype.toString.call(callbackfn) !== '[object Function]') { throw new TypeError(); } // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. if (arguments.length > 1) { T = thisArg; } // 6. Let k be 0. k = 0; // 7. Repeat, while k < len while (k < len) { var kValue; // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the HasProperty internal // method of O with argument Pk. // This step can be combined with c // c. If kPresent is true, then if (k in O) { var testResult; // i. Let kValue be the result of calling the Get internal method // of O with argument Pk. kValue = O[k]; // ii. Let testResult be the result of calling the Call internal method // of callbackfn with T as the this value if T is not undefined // else is the result of calling callbackfn // and argument list containing kValue, k, and O. if(T) testResult = callbackfn.call(T, kValue, k, O); else testResult = callbackfn(kValue,k,O) // iii. If ToBoolean(testResult) is false, return false. if (!testResult) { return false; } } k++; } return true; }; } ## Examples ### Testing size of all array elements The following example tests whether all elements in the array are bigger than 10. function isBigEnough(element, index, array) { return element >= 10; } [12, 5, 8, 130, 44].every(isBigEnough); // false [12, 54, 18, 130, 44].every(isBigEnough); // true ### Using arrow functions [Arrow functions](../../functions/arrow_functions) provide a shorter syntax for the same test. [12, 5, 8, 130, 44].every(x => x >= 10); // false [12, 54, 18, 130, 44].every(x => x >= 10); // true ### Affecting Initial Array (modifying, appending, and deleting) The following examples tests the behavior of the `every` method when the array is modified. // --------------- // Modifying items // --------------- let arr = [1, 2, 3, 4]; arr.every( (elem, index, arr) => { arr[index+1] -= 1 console.log(`[${arr}][${index}] -> ${elem}`) return elem < 2 }) // Loop runs for 3 iterations, but would // have run 2 iterations without any modification // // 1st iteration: [1,1,3,4][0] -> 1 // 2nd iteration: [1,1,2,4][1] -> 1 // 3rd iteration: [1,1,2,3][2] -> 2 // --------------- // Appending items // --------------- arr = [1, 2, 3]; arr.every( (elem, index, arr) => { arr.push('new') console.log(`[${arr}][${index}] -> ${elem}`) return elem < 4 }) // Loop runs for 3 iterations, even after appending new items // // 1st iteration: [1, 2, 3, new][0] -> 1 // 2nd iteration: [1, 2, 3, new, new][1] -> 2 // 3rd iteration: [1, 2, 3, new, new, new][2] -> 3 // --------------- // Deleting items // --------------- arr = [1, 2, 3, 4]; arr.every( (elem, index, arr) => { arr.pop() console.log(`[${arr}][${index}] -> ${elem}`) return elem < 4 }) // Loop runs for 2 iterations only, as the remaining // items are `pop()`ed off // // 1st iteration: [1,2,3][0] -> 1 // 2nd iteration: [1,2][1] -> 2 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-array.prototype.every
      `every` 1 12 1.5 9 9.5 3 ≤37 18 4 10.1 1 1.0 ## See also - [`Array.prototype.forEach()`](foreach) - [`Array.prototype.some()`](some) - [`Array.prototype.find()`](find) - [`TypedArray.prototype.every()`](../typedarray/every) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every # Atomics.exchange() The static `Atomics.exchange()` method stores a given value at a given position in the array and returns the old value at that position. This atomic operation guarantees that no other write happens between the read of the old value and the write of the new value. ## Syntax Atomics.exchange(typedArray, index, value) ### Parameters `typedArray` An integer typed array. One of [`Int8Array`](../int8array), [`Uint8Array`](../uint8array), [`Int16Array`](../int16array), [`Uint16Array`](../uint16array), [`Int32Array`](../int32array), [`Uint32Array`](../uint32array), [`BigInt64Array`](../bigint64array), or [`BigUint64Array`](../biguint64array). `index` The position in the `typedArray` to exchange a `value`. `value` The number to exchange. ### Return value The old value at the given position (`typedArray[index]`). ### Exceptions - Throws a [`TypeError`](../typeerror), if `typedArray` is not one of the allowed integer types. - Throws a [`RangeError`](../rangeerror), if `index` is out of bounds in the `typedArray`. ## Examples ### Using exchange() const sab = new SharedArrayBuffer(1024); const ta = new Uint8Array(sab); Atomics.exchange(ta, 0, 12); // returns 0, the old value Atomics.load(ta, 0); // 12 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-atomics.exchange
      `exchange` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. ## See also - [`Atomics`](../atomics) - [`Atomics.compareExchange()`](compareexchange) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/exchange # RegExp.prototype.exec() The `exec()` method executes a search for a match in a specified string. Returns a result array, or [`null`](../null). JavaScript [`RegExp`](../regexp) objects are **stateful** when they have the [`global`](global) or [`sticky`](sticky) flags set (e.g. `/foo/g` or `/foo/y`). They store a [`lastIndex`](lastindex) from the previous match. Using this internally, `exec()` can be used to iterate over multiple matches in a string of text (with capture groups), as opposed to getting just the matching strings with [`String.prototype.match()`](../string/match). A newer function has been proposed to simplify matching multiple parts of a string (with capture groups): [`String.prototype.matchAll()`](../string/matchall). If you are executing a match to find `true` or `false`, use [`RegExp.prototype.test()`](test) method instead. If you are executing a match to find its index position in the string, use [`String.prototype.search()`](../string/search) method instead. ## Syntax exec(str) ### Parameters `str` The string against which to match the regular expression. ### Return value If the match succeeds, the `exec()` method returns an array (with extra properties `index`, `input`, and if the `d` flag is set, `indices`; see below) and updates the [`lastIndex`](lastindex) property of the regular expression object. The returned array has the matched text as the first item, and then one item for each parenthetical capture group of the matched text. If the match fails, the `exec()` method returns [`null`](../null), and sets [`lastIndex`](lastindex) to `0`. ## Description Consider the following example: // Match "quick brown" followed by "jumps", ignoring characters in between // Remember "brown" and "jumps" // Ignore case let re = /quick\s(brown).+?(jumps)/igd; let result = re.exec('The Quick Brown Fox Jumps Over The Lazy Dog'); The following table shows the state of `result` after running this script:
      Property/IndexDescriptionExample
      [0]The full string of characters matched"Quick Brown Fox Jumps"
      [1], ...[n]

      The parenthesized substring matches, if any.

      The number of possible parenthesized substrings is unlimited.

      result[1] === "Brown"

      result[2] === "Jumps"

      indexThe 0-based index of the match in the string.4
      indicesAn array where each entry represents a substring match. Each substring match itself is an array where the first entry represents its start index and the second entry its end index.
      The indices array additionally has a groups property which holds an object of all named capturing groups. The keys are the names of the capturing groups and each value is an array with the first item being the start entry and the second entry being the end index of the capturing group. If the regular expression doesn't contain any capturing groups, groups is undefined.

      indices[0] === Array [ 4, 25 ]

      indices[1] === Array [ 10, 15 ]

      indices[2] === Array [ 20, 25 ]

      indices.groups === undefined

      indices.length === 3

      inputThe original string that was matched against.The Quick Brown Fox Jumps Over The Lazy Dog
      The following table shows the state of `re` after running this script:
      Property/IndexDescriptionExample
      lastIndex

      The index at which to start the next match.

      If g is absent, this will always be 0.

      25
      dotAllIndicates if the s flag was used to let . match newlines.false
      hasIndicesIndicates if the d flag was used to generate an indices property in the returned value containing start and end indices of the substring matches.true
      ignoreCaseIndicates if the i flag was used to ignore case.true
      globalIndicates if the g flag was used for a global match.true
      multilineIndicates if the m flag was used to search across multiple lines.false
      sourceThe text of the pattern.quick\s(brown).+?(jumps)
      stickyIndicates if the y flag was used to match only from the index indicated by the lastIndex property.false
      unicodeIndicates if the u flag was used to treat the pattern as a sequence of Unicode code points.false
      ## Examples ### Finding successive matches If your regular expression uses the "`g`" flag, you can use the `exec()` method multiple times to find successive matches in the same string. When you do so, the search starts at the substring of `str` specified by the regular expression's [`lastIndex`](lastindex) property ([`test()`](test) will also advance the [`lastIndex`](lastindex) property). Note that the [`lastIndex`](lastindex) property will not be reset when searching a different string, it will start its search at its existing [`lastIndex`](lastindex) . For example, assume you have this script: let myRe = /ab*/g; let str = 'abbcdefabh'; let myArray; while ((myArray = myRe.exec(str)) !== null) { let msg = 'Found ' + myArray[0] + '. '; msg += 'Next match starts at ' + myRe.lastIndex; console.log(msg); } This script displays the following text: Found abb. Next match starts at 3 Found ab. Next match starts at 9 **Warning:** **Do _not_ place the regular expression literal (or [`RegExp`](../regexp) constructor) within the `while` condition!** It will create an infinite loop if there is a match, due to the [`lastIndex`](lastindex) property being reset upon each iteration. Also, be sure that the global flag ("`g`") is set, or it will also cause an infinite loop. ### Using exec() with RegExp literals You can also use `exec()` without creating a [`RegExp`](../regexp) object explicitly: let matches = /(hello \S+)/.exec('This is a hello world!'); console.log(matches[1]); This will log a message containing `'hello world!'`. ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-regexp.prototype.exec
      `exec` 1 12 1 4 5 1 1 18 4 10.1 1 1.0 ## See also - [Regular Expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) chapter in the [JavaScript Guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide) - [`RegExp`](../regexp) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec # Math.exp() The `Math.exp()` function returns `ex`, where `x` is the argument, and `e` is [Euler's number (also known as Napier's constant)](e), the base of the natural logarithms. ## Syntax Math.exp(x) ### Parameters `x` A number. ### Return value A number representing `ex`, where `e` is [Euler's number](e) and `x` is the argument. ## Description Because `exp()` is a static method of `Math`, you always use it as `Math.exp()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.exp() Math.exp(-1); // 0.36787944117144233 Math.exp(0); // 1 Math.exp(1); // 2.718281828459045 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.exp
      `exp` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`Math.E`](e) - [`Math.expm1()`](expm1) - [`Math.log()`](log) - [`Math.log10()`](log10) - [`Math.log1p()`](log1p) - [`Math.log2()`](log2) - [`Math.pow()`](pow) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp # Math.expm1() The `Math.expm1()` function returns `ex - 1`, where `x` is the argument, and [e](e) the base of the natural logarithms. ## Syntax Math.expm1(x) ### Parameters `x` A number. ### Return value A number representing `ex - 1`, where `e` is [Euler's number](e) and `x` is the argument. ## Description Because `expm1()` is a static method of `Math`, you always use it as `Math.expm1()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). ## Examples ### Using Math.expm1() Math.expm1(-1); // -0.6321205588285577 Math.expm1(0); // 0 Math.expm1(1); // 1.718281828459045 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.expm1
      `expm1` 38 12 25 No 25 8 38 38 25 25 8 3.0 ## See also - [`Math.E`](e) - [`Math.exp()`](exp) - [`Math.log()`](log) - [`Math.log10()`](log10) - [`Math.log1p()`](log1p) - [`Math.log2()`](log2) - [`Math.pow()`](pow) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1 # Exponentiation (\*\*) The exponentiation operator (`**`) returns the result of raising the first operand to the power of the second operand. It is equivalent to `Math.pow`, except it also accepts BigInts as operands. ## Syntax Operator: var1 ** var2 ## Description The exponentiation operator is right-associative: `a ** b ** c` is equal to `a ** (b ** c)`. In most languages, such as PHP, Python, and others that have an exponentiation operator (`**`), the exponentiation operator is defined to have a higher precedence than unary operators, such as unary `+` and unary `-`, but there are a few exceptions. For example, in Bash, the `**` operator is defined to have a lower precedence than unary operators. In JavaScript, it is impossible to write an ambiguous exponentiation expression. That is, you cannot put a unary operator (`+/-/~/!/delete/void/typeof`) immediately before the base number; doing so will cause a SyntaxError. -2 ** 2; // 4 in Bash, -4 in other languages. // This is invalid in JavaScript, as the operation is ambiguous. -(2 ** 2); // -4 in JavaScript and the author's intention is unambiguous. Note that some programming languages use the caret symbol ^ for exponentiation, but JavaScript uses that symbol for the [bitwise logical XOR operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#bitwise_xor). ## Examples ### Basic exponentiation 2 ** 3 // 8 3 ** 2 // 9 3 ** 2.5 // 15.588457268119896 10 ** -1 // 0.1 NaN ** 2 // NaN ### Associativity 2 ** 3 ** 2 // 512 2 ** (3 ** 2) // 512 (2 ** 3) ** 2 // 64 ### Usage with unary operators To invert the sign of the result of an exponentiation expression: -(2 ** 2) // -4 To force the base of an exponentiation expression to be a negative number: (-2) ** 2 // 4 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-exp-operator
      `Exponentiation` 52 14 52 No 39 10.1 51 52 52 41 10.3 6.0 ## See also - [Addition operator](addition) - [Subtraction operator](subtraction) - [Division operator](division) - [Multiplication operator](multiplication) - [Remainder operator](remainder) - [Increment operator](increment) - [Decrement operator](decrement) - [Unary negation operator](unary_negation) - [Unary plus operator](unary_plus) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Exponentiation # export The `export` statement is used when creating JavaScript modules to export live bindings to functions, objects, or primitive values from the module so they can be used by other programs with the [`import`](import) statement. Bindings that are exported can still be modified locally; when imported, although they can only be read by the importing module the value updates whenever it is updated by the exporting module. Exported modules are in [strict mode](../strict_mode) whether you declare them as such or not. The export statement cannot be used in embedded scripts. ## Syntax There are two types of exports: 1. Named Exports (Zero or more exports per module) 2. Default Exports (One per module) // Exporting individual features export let name1, name2, …, nameN; // also var, const export let name1 = …, name2 = …, …, nameN; // also var, const export function functionName(){...} export class ClassName {...} // Export list export { name1, name2, …, nameN }; // Renaming exports export { variable1 as name1, variable2 as name2, …, nameN }; // Exporting destructured assignments with renaming export const { name1, name2: bar } = o; // Default exports export default expression; export default function (…) { … } // also class, function* export default function name1(…) { … } // also class, function* export { name1 as default, … }; // Aggregating modules export * from …; // does not set the default export export * as name1 from …; // Draft ECMAScript® 2O21 export { name1, name2, …, nameN } from …; export { import1 as name1, import2 as name2, …, nameN } from …; export { default, … } from …; `nameN` Identifier to be exported (so that it can be imported via [`import`](import) in another script). ## Description There are two different types of export, **named** and **default**. You can have multiple named exports per module but only one default export. Each type corresponds to one of the above syntax: Named exports: // export features declared earlier export { myFunction, myVariable }; // export individual features (can export var, let, // const, function, class) export let myVariable = Math.sqrt(2); export function myFunction() { ... }; Default exports: // export feature declared earlier as default export { myFunction as default }; // export individual features as default export default function () { ... } export default class { .. } // each export overwrites the previous one Named exports are useful to export several values. During the import, it is mandatory to use the same name of the corresponding object. But a default export can be imported with any name for example: // file test.js let k; export default k = 12; // some other file import m from './test'; // note that we have the freedom to use import m instead of import k, because k was default export console.log(m); // will log 12 You can also rename named exports to avoid naming conflicts: export { myFunction as function1, myVariable as variable }; ### Re-exporting / Aggregating It is also possible to "import/export" from different modules in a parent module so that they are available to import from that module. In other words, one can create a single module concentrating various exports from various modules. This can be achieved with the "export from" syntax: export { default as function1, function2 } from 'bar.js'; Which is comparable to a combination of import and export: import { default as function1, function2 } from 'bar.js'; export { function1 as default, function2 }; But where `function1` and `function2` do not become available inside the current module. **Note:** The following is syntactically invalid despite its import equivalent: import DefaultExport from 'bar.js'; // Valid export DefaultExport from 'bar.js'; // Invalid The correct way of doing this is to rename the export: export { default as DefaultExport } from 'bar.js'; The "export from" syntax allows the `as` token to be omitted; however this will mean the default item cannot be imported as a named import: export { default, function2 } from 'bar.js'; ## Examples ### Using named exports In a module `my-module.js`, we could include the following code: // module "my-module.js" function cube(x) { return x * x * x; } const foo = Math.PI + Math.SQRT2; var graph = { options: { color:'white', thickness:'2px' }, draw: function() { console.log('From graph draw function'); } } export { cube, foo, graph }; Then in the top-level module included in your HTML page, we could have: import { cube, foo, graph } from './my-module.js'; graph.options = { color:'blue', thickness:'3px' }; graph.draw(); console.log(cube(3)); // 27 console.log(foo); // 4.555806215962888 It is important to note the following: - You need to include this script in your HTML with a [` you can access meta information about the module using the `import.meta` object. console.log(import.meta); // { url: "file:///home/user/my-module.js" } It returns an object with a `url` property indicating the base URL of the module. This will either be the URL from which the script was obtained, for external scripts, or the document base URL of the containing document, for inline scripts. Note that this will include query parameters and/or hash (i.e., following the `?` or `#`). For example, with the following HTML: ..the following JavaScript file will log the \``someURLInfo` parameter: // index.mjs new URL(import.meta.url).searchParams.get('someURLInfo'); // 5 The same applies when a file imports another: // index.mjs import './index2.mjs?someURLInfo=5'; // index2.mjs new URL(import.meta.url).searchParams.get('someURLInfo'); // 5 Note that while Node.js will pass on query parameters (or the hash) as in the latter example, as of Node 14.1.0, a URL with query parameters will err when loading in the form `node --experimental-modules index.mjs?someURLInfo=5` (it is treated as a file rather than a URL in this context). Such file-specific argument passing may be complementary to that used in the application-wide `location.href` (with query strings or hash added after the HTML file path) (or on Node.js, through `process.argv`). ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #prod-ImportMeta
      HTML Standard (HTML)
      #hostgetimportmetaproperties
      `import.meta` 64 79 62 No 51 11.1 64 64 62 47 12 9.0 ## See also - [`import`](import) - [`export`](export) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import.meta # WebAssembly.Module.imports() The `WebAssembly.imports()` function returns an array containing descriptions of all the declared imports of the given `Module`. ## Syntax WebAssembly.Module.imports(module) ### Parameters _module_ A [`WebAssembly.Module`](../module) object. ### Return value An array containing objects representing the imported functions of the given module. ### Exceptions If module is not a [`WebAssembly.Module`](../module) object instance, a [`TypeError`](../../typeerror) is thrown. ## Examples ### Using imports The following example (see imports.html [source code](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/imports.html); [see it live also](https://mdn.github.io/webassembly-examples/js-api-examples/imports.html)) compiles the loaded simple.wasm module. This module is then queried for its imports. WebAssembly.compileStreaming(fetch('simple.wasm')) .then(function(mod) { var imports = WebAssembly.Module.imports(mod); console.log(imports[0]); }); The output looks like this: { module: "imports", name: "imported_func", kind: "function" } ## Specifications
      Specification
      WebAssembly JavaScript Interface (WebAssembly JavaScript Interface)
      #dom-module-imports
      `imports` 57 16 52 Disabled in the Firefox 52 Extended Support Release (ESR). No 44 11 57 57 52 Disabled in the Firefox 52 Extended Support Release (ESR). 43 11 7.0 ## See also - [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) overview page - [WebAssembly concepts](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts) - [Using the WebAssembly JavaScript API](https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/imports # Math.imul() The `Math.imul()` function returns the result of the C-like 32-bit multiplication of the two parameters. ## Syntax Math.imul(a, b) ### Parameters `a` First number. `b` Second number. ### Return value The result of the C-like 32-bit multiplication of the given arguments. ## Description `Math.imul()` allows for 32-bit integer multiplication with C-like semantics. This feature is useful for projects like [Emscripten](https://en.wikipedia.org/wiki/Emscripten). Because `imul()` is a static method of `Math`, you always use it as `Math.imul()`, rather than as a method of a `Math` object you created (`Math` is not a constructor). If you use normal JavaScript floating point numbers in imul, you will experience a degrade in performance. This is because of the costly conversion from a floating point to an integer for multiplication, and then converting the multiplied integer back into a floating point. The reason imul exists is because it is faster in only one (so far) circumstance: AsmJS. AsmJS allows for JIST-optimizers to more easily implement internal integers in JavaScript. Multiplying two numbers stored internally as integers (which is only possible with AsmJS) with imul is the only potential circumstance where Math.imul may prove performant in current browsers. ## Examples ### Using Math.imul() Math.imul(2, 4); // 8 Math.imul(-1, 8); // -8 Math.imul(-2, -2); // 4 Math.imul(0xffffffff, 5); // -5 Math.imul(0xfffffffe, 5); // -10 ## Polyfill This can be emulated with the following function: if (!Math.imul) Math.imul = function(a, b) { var aHi = (a >>> 16) & 0xffff; var aLo = a & 0xffff; var bHi = (b >>> 16) & 0xffff; var bLo = b & 0xffff; // the shift by 0 fixes the sign on the high part // the final |0 converts the unsigned value into a signed value return ((aLo * bLo) + (((aHi * bLo + aLo * bHi) << 16) >>> 0) | 0); }; However, the following function is more performant because it is likely that browsers in which this polyfill would be used do not optimize with an internal integer type in JavaScript, instead using floating points for all numbers. if (!Math.imul) Math.imul = function(opA, opB) { opB |= 0; // ensure that opB is an integer. opA will automatically be coerced. // floating points give us 53 bits of precision to work with plus 1 sign bit // automatically handled for our convienence: // 1. 0x003fffff /*opA & 0x000fffff*/ * 0x7fffffff /*opB*/ = 0x1fffff7fc00001 // 0x1fffff7fc00001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/ var result = (opA & 0x003fffff) * opB; // 2. We can remove an integer coersion from the statement above because: // 0x1fffff7fc00001 + 0xffc00000 = 0x1fffffff800001 // 0x1fffffff800001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/ if (opA & 0xffc00000 /*!== 0*/) result += (opA & 0xffc00000) * opB |0; return result |0; }; ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-math.imul
      `imul` 28 12 20 No 16 7 ≤37 28 20 15 7 1.5 ## See also - [Emscripten](https://en.wikipedia.org/wiki/Emscripten) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul # in operator The `in` returns `true` if the specified property is in the specified object or its prototype chain. ## Syntax prop in object ### Parameters `prop` A string or symbol representing a property name or array index (non-symbols will be coerced to strings). `object` Object to check if it (or its prototype chain) contains the property with specified name (`prop`). ## Examples ### Basic usage The following examples show some uses of the `in` operator. // Arrays let trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'] 0 in trees // returns true 3 in trees // returns true 6 in trees // returns false 'bay' in trees // returns false (you must specify the index number, not the value at that index) 'length' in trees // returns true (length is an Array property) Symbol.iterator in trees // returns true (arrays are iterable, works only in ES2015+) // Predefined objects 'PI' in Math // returns true // Custom objects let mycar = {make: 'Honda', model: 'Accord', year: 1998} 'make' in mycar // returns true 'model' in mycar // returns true You must specify an object on the right side of the `in` operator. For example, you can specify a string created with the `String` constructor, but you cannot specify a string literal. let color1 = new String('green') 'length' in color1 // returns true let color2 = 'coral' // generates an error (color2 is not a String object) 'length' in color2 ### Using `in` with deleted or undefined properties If you delete a property with the `delete` operator, the `in` operator returns `false` for that property. let mycar = {make: 'Honda', model: 'Accord', year: 1998} delete mycar.make 'make' in mycar // returns false let trees = new Array('redwood', 'bay', 'cedar', 'oak', 'maple') delete trees[3] 3 in trees // returns false If you set a property to [`undefined`](../global_objects/undefined) but do not delete it, the `in` operator returns true for that property. let mycar = {make: 'Honda', model: 'Accord', year: 1998} mycar.make = undefined 'make' in mycar // returns true let trees = new Array('redwood', 'bay', 'cedar', 'oak', 'maple') trees[3] = undefined 3 in trees // returns true The `in` operator will return `false` for empty array slots. Even if accessing it directly returns `undefined`. let empties = new Array(3) empties[2] // returns undefined 2 in empties // returns false To avoid this, make sure a new array is always filled with non-empty values or not write to indexes past the end of array. let empties = new Array(3).fill(undefined) 2 in empties // returns true ### Inherited properties The `in` operator returns `true` for properties in the prototype chain. (If you want to check for only _non-inherited_ properties, use [`Object.prototype.hasOwnProperty()`](../global_objects/object/hasownproperty) instead.) 'toString' in {} // returns true ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-relational-operators
      `in` 1 12 1 5.5 4 1 1 18 4 10.1 1 1.0 ## See also - `for...in` - `delete` - [`Object.prototype.hasOwnProperty()`](../global_objects/object/hasownproperty) - [`Reflect.has()`](../global_objects/reflect/has) - [Enumerability and ownership of properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in # TypeError: cannot use 'in' operator to search for 'x' in 'y' The JavaScript exception "right-hand side of 'in' should be an object" occurs when the [`in` operator](../operators/in) was used to search in strings, or in numbers, or other primitive types. It can only be used to check if a property is in an object. ## Message TypeError: Invalid operand to 'in' (Edge) TypeError: right-hand side of 'in' should be an object, got 'x' (Firefox) TypeError: cannot use 'in' operator to search for 'x' in 'y' (Firefox, Chrome) ## Error type [`TypeError`](../global_objects/typeerror) ## What went wrong? The [`in` operator](../operators/in) can only be used to check if a property is in an object. You can't search in strings, or in numbers, or other primitive types. ## Examples ### Searching in strings Unlike in other programming languages (e.g. Python), you can't search in strings using the [`in` operator](../operators/in). "Hello" in "Hello World"; // TypeError: cannot use 'in' operator to search for 'Hello' in 'Hello World' Instead you will need to use [`String.prototype.indexOf()`](../global_objects/string/indexof), for example. "Hello World".indexOf("Hello") !== -1; // true ### The operand can't be null or undefined Make sure the object you are inspecting isn't actually [`null`](../global_objects/null) or [`undefined`](../global_objects/undefined). var foo = null; "bar" in foo; // TypeError: cannot use 'in' operator to search for 'bar' in 'foo' (Chrome) // TypeError: right-hand side of 'in' should be an object, got null (Firefox) The `in` operator always expects an object. var foo = { baz: "bar" }; "bar" in foo; // false "PI" in Math; // true "pi" in Math; // false ### Searching in arrays Be careful when using the `in` operator to search in [`Array`](../global_objects/array) objects. The `in` operator checks the index number, not the value at that index. var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; 3 in trees; // true "oak" in trees; // false ## See also - [`in` operator](../operators/in) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/in_operator_no_object # Array.prototype.includes() The `includes()` method determines whether an array includes a certain value among its entries, returning `true` or `false` as appropriate. ## Syntax includes(searchElement) includes(searchElement, fromIndex) ### Parameters `searchElement` The value to search for. **Note:** When comparing strings and characters, `includes()` is _case-sensitive_. `fromIndex` Optional The position in this array at which to begin searching for `searchElement`. The first element to be searched is found at `fromIndex` for positive values of `fromIndex`, or at `arr.length + fromIndex` for negative values of `fromIndex` (using the [absolute value](#) of `fromIndex` as the number of elements from the end of the array at which to start the search). Defaults to `0`. ### Return value A [`Boolean`](../boolean) which is `true` if the value `searchElement` is found within the array (or the part of the array indicated by the index `fromIndex`, if specified). Values of zero are all considered to be equal, regardless of sign. (That is, `-0` is considered to be equal to both `0` and `+0`), but `false` is _not_ considered to be the same as `0`. **Note:** Technically speaking, `includes()` uses the `sameValueZero` algorithm to determine whether the given element is found. ## Examples [1, 2, 3].includes(2) // true [1, 2, 3].includes(4) // false [1, 2, 3].includes(3, 3) // false [1, 2, 3].includes(3, -1) // true [1, 2, NaN].includes(NaN) // true ### `fromIndex` is greater than or equal to the array length If `fromIndex` is greater than or equal to the length of the array, `false` is returned. The array will not be searched. let arr = ['a', 'b', 'c'] arr.includes('c', 3) // false arr.includes('c', 100) // false ### Computed index is less than 0 If `fromIndex` is negative, the computed index is calculated to be used as a position in the array at which to begin searching for `searchElement`. If the computed index is less or equal than `-1 * arr.length`, the entire array will be searched. // array length is 3 // fromIndex is -100 // computed index is 3 + (-100) = -97 let arr = ['a', 'b', 'c'] arr.includes('a', -100) // true arr.includes('b', -100) // true arr.includes('c', -100) // true arr.includes('a', -2) // false ### includes() used as a generic method `includes()` method is intentionally generic. It does not require `this` value to be an Array object, so it can be applied to other kinds of objects (e.g. array-like objects). The example below illustrates `includes()` method called on the function's [arguments](../../functions/arguments) object. (function() { console.log(Array.prototype.includes.call(arguments, 'a')) // true console.log(Array.prototype.includes.call(arguments, 'd')) // false })('a','b','c') ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-array.prototype.includes
      `includes` 47 14 43 No 34 9 47 47 43 34 9 5.0 ## See also - [`TypedArray.prototype.includes()`](../typedarray/includes) - [`String.prototype.includes()`](../string/includes) - [`Array.prototype.indexOf()`](indexof) - [`Array.prototype.find()`](find) - [`Array.prototype.findIndex()`](findindex) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes # Increment (++) The increment operator (`++`) increments (adds one to) its operand and returns a value. ## Syntax Operator: x++ or ++x ## Description If used postfix, with operator after operand (for example, `x++`), the increment operator increments and returns the value before incrementing. If used prefix, with operator before operand (for example, `++x`), the increment operator increments and returns the value after incrementing. ## Examples ### Postfix increment let x = 3; y = x++; // y = 3 // x = 4 ### Prefix increment let a = 2; b = ++a; // a = 3 // b = 3 ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Increment operator' in that specification.
      `Increment` 2 12 1 3 3 4 1 18 4 10.1 3.2 1.0 ## See also - [Addition operator](addition) - [Subtraction operator](subtraction) - [Division operator](division) - [Multiplication operator](multiplication) - [Remainder operator](remainder) - [Exponentiation operator](exponentiation) - [Decrement operator](decrement) - [Unary negation operator](unary_negation) - [Unary plus operator](unary_plus) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Increment # JavaScript reference This part of the JavaScript section on MDN serves as a repository of facts about the JavaScript language. Read more [about this reference](about). ## Built-ins [JavaScript standard built-in objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects), along with their methods and properties. ### Value properties - [`Infinity`](global_objects/infinity) - [`NaN`](global_objects/nan) - [`undefined`](global_objects/undefined) - [`globalThis`](global_objects/globalthis) ### Function properties - [`eval()`](global_objects/eval) - [`isFinite()`](global_objects/isfinite) - [`isNaN()`](global_objects/isnan) - [`parseFloat()`](global_objects/parsefloat) - [`parseInt()`](global_objects/parseint) - [`decodeURI()`](global_objects/decodeuri) - [`decodeURIComponent()`](global_objects/decodeuricomponent) - [`encodeURI()`](global_objects/encodeuri) - [`encodeURIComponent()`](global_objects/encodeuricomponent) ### Fundamental objects - [`Object`](global_objects/object) - [`Function`](global_objects/function) - [`Boolean`](global_objects/boolean) - [`Symbol`](global_objects/symbol) ### Error objects - [`Error`](global_objects/error) - [`AggregateError`](global_objects/aggregateerror) - [`EvalError`](global_objects/evalerror) - [`InternalError`](global_objects/internalerror) - [`RangeError`](global_objects/rangeerror) - [`ReferenceError`](global_objects/referenceerror) - [`SyntaxError`](global_objects/syntaxerror) - [`TypeError`](global_objects/typeerror) - [`URIError`](global_objects/urierror) ### Numbers & dates - [`Number`](global_objects/number) - [`BigInt`](global_objects/bigint) - [`Math`](global_objects/math) - [`Date`](global_objects/date) ### Text processing - [`String`](global_objects/string) - [`RegExp`](global_objects/regexp) ### Indexed Collections - [`Array`](global_objects/array) - [`Int8Array`](global_objects/int8array) - [`Uint8Array`](global_objects/uint8array) - [`Uint8ClampedArray`](global_objects/uint8clampedarray) - [`Int16Array`](global_objects/int16array) - [`Uint16Array`](global_objects/uint16array) - [`Int32Array`](global_objects/int32array) - [`Uint32Array`](global_objects/uint32array) - [`Float32Array`](global_objects/float32array) - [`Float64Array`](global_objects/float64array) - [`BigInt64Array`](global_objects/bigint64array) - [`BigUint64Array`](global_objects/biguint64array) ### Keyed collections - [`Map`](global_objects/map) - [`Set`](global_objects/set) - [`WeakMap`](global_objects/weakmap) - [`WeakSet`](global_objects/weakset) ### Structured data - [`ArrayBuffer`](global_objects/arraybuffer) - [`SharedArrayBuffer`](global_objects/sharedarraybuffer) - [`Atomics`](global_objects/atomics) - [`DataView`](global_objects/dataview) - [`JSON`](global_objects/json) ### Control abstraction - [`GeneratorFunction`](global_objects/generatorfunction) - `AsyncGeneratorFunction` - [`Generator`](global_objects/generator) - `AsyncGenerator` - [`AsyncFunction`](global_objects/asyncfunction) - [`Promise`](global_objects/promise) ### Reflection - [`Reflect`](global_objects/reflect) - [`Proxy`](global_objects/proxy) ### Internationalization - [`Intl`](global_objects/intl) - [`Intl.Collator`](global_objects/intl/collator) - [`Intl.DateTimeFormat`](global_objects/intl/datetimeformat) - [`Intl.DisplayNames`](global_objects/intl/displaynames) - [`Intl.ListFormat`](global_objects/intl/listformat) - [`Intl.Locale`](global_objects/intl/locale) - [`Intl.NumberFormat`](global_objects/intl/numberformat) - [`Intl.PluralRules`](global_objects/intl/pluralrules) - [`Intl.RelativeTimeFormat`](global_objects/intl/relativetimeformat) ### WebAssembly - [`WebAssembly`](global_objects/webassembly) - [`WebAssembly.Module`](global_objects/webassembly/module) - [`WebAssembly.Instance`](global_objects/webassembly/instance) - [`WebAssembly.Memory`](global_objects/webassembly/memory) - [`WebAssembly.Table`](global_objects/webassembly/table) - [`WebAssembly.CompileError`](global_objects/webassembly/compileerror) - [`WebAssembly.LinkError`](global_objects/webassembly/linkerror) - [`WebAssembly.RuntimeError`](global_objects/webassembly/runtimeerror) ## Statements [JavaScript statements and declarations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements) ### Control flow - [`Block`](statements/block) - [`break`](statements/break) - [`continue`](statements/continue) - [`Empty`](statements/empty) - [`if...else`](statements/if...else) - [`switch`](statements/switch) - [`throw`](statements/throw) - [`try...catch`](statements/try...catch) ### Declarations - [`var`](statements/var) - [`let`](statements/let) - [`const`](statements/const) ### Functions and classes - [`function`](statements/function) - [`function*`](statements/function*) - [`async function`](statements/async_function) - [`return`](statements/return) - [`class`](statements/class) ### Iterations - [`do...while`](statements/do...while) - [`for`](statements/for) - `for each...in` - [`for...in`](statements/for...in) - [`for...of`](statements/for...of) - [`for await...of`](statements/for-await...of) - [`while`](statements/while) ### Other - [`debugger`](statements/debugger) - [`export`](statements/export) - [`import`](statements/import) - [`label`](statements/label) - [`with`](statements/with) ## Expressions and operators [JavaScript expressions and operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators). ### Primary expressions - [`this`](operators/this) - [`function`](operators/function) - [`class`](operators/class) - [`function*`](operators/function*) - [`yield`](operators/yield) - [`yield*`](operators/yield*) - [`async function`](operators/async_function) - [`await`](operators/await) - [`[]`](global_objects/array) - [`{}`](operators/object_initializer) - [`/ab+c/i`](global_objects/regexp) - [`( )`](operators/grouping) - [`null`](global_objects/null) ### Left-hand-side expressions - [Property accessors](operators/property_accessors) - [Optional chaining](operators/optional_chaining) - [`new`](operators/new) - [`new.target`](operators/new.target) - [`import.meta`](statements/import.meta) - [`super`](operators/super) - [`...obj`](operators/spread_syntax) ### Increment & decrement - [`A++`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#increment) - [`A--`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#decrement) - [`++A`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#increment) - [`--A`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#decrement) ### Unary operators - [`delete`](operators/delete) - [`void`](operators/void) - [`typeof`](operators/typeof) - [`+`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#unary_plus) - [`-`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#unary_negation) - [`~`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#bitwise_not) - [`!`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#logical_not) ### Arithmetic operators - [`+`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#addition) - [`-`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#subtraction) - [`/`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#division) - [`*`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#multiplication) - [`%`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#remainder) - [`**`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#exponentiation) ### Relational operators - [`in`](operators/in) - [`instanceof`](operators/instanceof) - [`<`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#less_than_operator) - [`>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#greater_than_operator) - [`<=`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#less_than_or_equal_operator) - [`>=`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#greater_than_or_equal_operator) ### Equality operators - [`==`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#equality) - [`!=`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#inequality) - [`===`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#identity) - [`!==`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#nonidentity) ### Bitwise shift operators - [`<<`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#left_shift) - [`>>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#right_shift) - [`>>>`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#unsigned_right_shift) ### Binary bitwise operators - [`&`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#bitwise_and) - [`|`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#bitwise_or) - [`^`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#bitwise_xor) ### Binary logical operators - [`&&`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#logical_and) - [`||`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#logical_or) ### Conditional (ternary) operator - [`(condition ? ifTrue : ifFalse)`](operators/conditional_operator) ### Assignment operators - [`=`](#) - [`*=`](#) - [`/=`](#) - [`%=`](#) - [`+=`](#) - [`-=`](#) - [`<<=`](#) - [`>>=`](#) - [`>>>=`](#) - [`&=`](#) - [`^=`](#) - [`|=`](#) - [`[a, b] = [1, 2]`](operators/destructuring_assignment) - [`{a, b} = {a:1, b:2}`](operators/destructuring_assignment) ## Functions This chapter documents how to work with JavaScript functions to develop your applications. - [`arguments`](functions/arguments) - [Arrow functions](functions/arrow_functions) - [Default parameters](functions/default_parameters) - [Rest parameters](functions/rest_parameters) ## Additional reference pages - [Lexical grammar](lexical_grammar) - [Data types and data structures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures) - [Strict mode](strict_mode) - [Deprecated features](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference # Array.prototype.indexOf() The `indexOf()` method returns the first index at which a given element can be found in the array, or -1 if it is not present. ## Syntax indexOf(searchElement) indexOf(searchElement, fromIndex) ### Parameters `searchElement` Element to locate in the array. `fromIndex` Optional The index to start the search at. If the index is greater than or equal to the array's length, -1 is returned, which means the array will not be searched. If the provided index value is a negative number, it is taken as the offset from the end of the array. Note: if the provided index is negative, the array is still searched from front to back. If the provided index is 0, then the whole array will be searched. Default: 0 (entire array is searched). ### Return value The first index of the element in the array; **-1** if not found. ## Description `indexOf()` compares `searchElement` to elements of the Array using [strict equality](../../operators/strict_equality) (the same method used by the `===` or triple-equals operator). **Note:** For the String method, see [`String.prototype.indexOf()`](../string/indexof). ## Examples ### Using indexOf() The following example uses `indexOf()` to locate values in an array. var array = [2, 9, 9]; array.indexOf(2); // 0 array.indexOf(7); // -1 array.indexOf(9, 2); // 2 array.indexOf(2, -1); // -1 array.indexOf(2, -3); // 0 ### Finding all the occurrences of an element var indices = []; var array = ['a', 'b', 'a', 'c', 'a', 'd']; var element = 'a'; var idx = array.indexOf(element); while (idx != -1) { indices.push(idx); idx = array.indexOf(element, idx + 1); } console.log(indices); // [0, 2, 4] ### Finding if an element exists in the array or not and updating the array function updateVegetablesCollection (veggies, veggie) { if (veggies.indexOf(veggie) === -1) { veggies.push(veggie); console.log('New veggies collection is : ' + veggies); } else if (veggies.indexOf(veggie) > -1) { console.log(veggie + ' already exists in the veggies collection.'); } } var veggies = ['potato', 'tomato', 'chillies', 'green-pepper']; updateVegetablesCollection(veggies, 'spinach'); // New veggies collection is : potato,tomato,chillies,green-pepper,spinach updateVegetablesCollection(veggies, 'spinach'); // spinach already exists in the veggies collection. ## Polyfill `indexOf()` was added to the ECMA-262 standard in the 5th edition; as such it may not be present in all browsers. You can work around this by utilizing the following code at the beginning of your scripts. This will allow you to use `indexOf()` when there is still no native support. This algorithm matches the one specified in ECMA-262, 5th edition, assuming [`TypeError`](../typeerror) and [`Math.abs()`](../math/abs) have their original values. // This version tries to optimize by only checking for "in" when looking for undefined and // skipping the definitely fruitless NaN search. Other parts are merely cosmetic conciseness. // Whether it is actually faster remains to be seen. if (!Array.prototype.indexOf) Array.prototype.indexOf = (function(Object, max, min) { "use strict" return function indexOf(member, fromIndex) { if (this === null || this === undefined) throw TypeError("Array.prototype.indexOf called on null or undefined") var that = Object(this), Len = that.length >>> 0, i = min(fromIndex | 0, Len) if (i < 0) i = max(0, Len + i) else if (i >= Len) return -1 if (member === void 0) { // undefined for (; i !== Len; ++i) if (that[i] === void 0 && i in that) return i } else if (member !== member) { // NaN return -1 // Since NaN !== NaN, it will never be found. Fast-path it. } else // all else for (; i !== Len; ++i) if (that[i] === member) return i return -1 // if the value was not found, then return -1 } })(Object, Math.max, Math.min) However, if you are more interested in all the little technical bits defined by the ECMA standard, and are less concerned about performance or conciseness, then you may find this more descriptive polyfill to be more useful. // Production steps of ECMA-262, Edition 5, 15.4.4.14 // Reference: https://es5.github.io/#x15.4.4.14 if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(searchElement, fromIndex) { "use strict"; var k; // 1. Let o be the result of calling ToObject passing // the this value as the argument. if (this == null) { throw new TypeError('"this" is null or not defined'); } var o = Object(this); // 2. Let lenValue be the result of calling the Get // internal method of o with the argument "length". // 3. Let len be ToUint32(lenValue). var len = o.length >>> 0; // 4. If len is 0, return -1. if (len === 0) { return -1; } // 5. If argument fromIndex was passed let n be // ToInteger(fromIndex); else let n be 0. var n = fromIndex | 0; // 6. If n >= len, return -1. if (n >= len) { return -1; } // 7. If n >= 0, then Let k be n. // 8. Else, n<0, Let k be len - abs(n). // If k is less than 0, then let k be 0. k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); // 9. Repeat, while k < len for (; k < len; k++) { // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the // HasProperty internal method of o with argument Pk. // This step can be combined with c // c. If kPresent is true, then // i. Let elementK be the result of calling the Get // internal method of o with the argument ToString(k). // ii. Let same be the result of applying the // Strict Equality Comparison Algorithm to // searchElement and elementK. // iii. If same is true, return k. if (k in o && o[k] === searchElement) return k; } return -1; }; } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-array.prototype.indexof
      `indexOf` 1 12 1.5 9 9.5 3 ≤37 18 4 10.1 1 1.0 ## See also - [`Array.prototype.lastIndexOf()`](lastindexof) - [`TypedArray.prototype.indexOf()`](../typedarray/indexof) - [`String.prototype.indexOf()`](../string/indexof) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf # Inequality (!=) The inequality operator (`!=`) checks whether its two operands are not equal, returning a Boolean result. Unlike the [strict inequality](strict_inequality) operator, it attempts to convert and compare operands that are of different types. ## Syntax x != y ## Description The inequality operator checks whether its operands are not equal. It is the negation of the [equality](equality) operator so the following two lines will always give the same result: x != y !(x == y) For details of the comparison algorithm, see the page for the [equality](equality) operator. Like the equality operator, the inequality operator will attempt to convert and compare operands of different types: 3 != "3"; // false To prevent this, and require that different types are considered to be different, use the [strict inequality](strict_inequality) operator instead: 3 !== "3"; // true ## Examples ### Comparison with no type conversion 1 != 2; // true "hello" != "hola"; // true 1 != 1; // false "hello" != "hello"; // false ### Comparison with type conversion "1" != 1; // false 1 != "1"; // false 0 != false; // false 0 != null; // true 0 != undefined; // true 0 != !!null; // false, look at Logical NOT operator 0 != !!undefined; // false, look at Logical NOT operator null != undefined; // false const number1 = new Number(3); const number2 = new Number(3); number1 != 3; // false number1 != number2; // true ### Comparison of objects const object1 = {"key": "value"} const object2 = {"key": "value"}; object1 != object2 // true object2 != object2 // false ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-equality-operators
      `Inequality` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Equality operator](equality) - [Strict equality operator](strict_equality) - [Strict inequality operator](strict_inequality) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Inequality # Infinity The global property `Infinity` is a numeric value representing infinity. Property attributes of `Infinity` Writable no Enumerable no Configurable no ## Description `Infinity` is a property of the _global object_. In other words, it is a variable in global scope. The initial value of `Infinity` is [`Number.POSITIVE_INFINITY`](number/positive_infinity). The value `Infinity` (positive infinity) is greater than any other number. This value behaves slightly differently than mathematical infinity; see [`Number.POSITIVE_INFINITY`](number/positive_infinity) for details. As defined by the ECMAScript 5 specification, `Infinity` is read-only (implemented in JavaScript 1.8.5 / Firefox 4). ## Examples ### Using Infinity console.log(Infinity ); /* Infinity */ console.log(Infinity + 1 ); /* Infinity */ console.log(Math.pow(10, 1000)); /* Infinity */ console.log(Math.log(0) ); /* -Infinity */ console.log(1 / Infinity ); /* 0 */ console.log(1 / 0 ); /* Infinity */ ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-value-properties-of-the-global-object-infinity
      `Infinity` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 ## See also - [`Number.NEGATIVE_INFINITY`](number/negative_infinity) - [`Number.POSITIVE_INFINITY`](number/positive_infinity) - [`Number.isFinite`](number/isfinite) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity # WebAssembly.Instance A `WebAssembly.Instance` object is a stateful, executable instance of a [`WebAssembly.Module`](module). `Instance` objects contain all the [Exported WebAssembly functions](https://developer.mozilla.org/en-US/docs/WebAssembly/Exported_functions) that allow calling into WebAssembly code from JavaScript. ## Constructor [`WebAssembly.Instance()`](instance/instance) Creates a new `Instance` object. ## Instance properties [`Instance.prototype.exports`](instance/exports) Returns an object containing as its members all the functions exported from the WebAssembly module instance, to allow them to be accessed and used by JavaScript. Read-only. ## Examples ### Synchronously instantiating a WebAssembly module The `WebAssembly.Instance()` constructor function can be called to synchronously instantiate a given [`WebAssembly.Module`](module) object, for example: const importObject = { imports: { imported_func: function(arg) { console.log(arg); } } }; fetch('simple.wasm').then(response => response.arrayBuffer() ).then(bytes => { let mod = new WebAssembly.Module(bytes); let instance = new WebAssembly.Instance(mod, importObject); instance.exports.exported_func(); }) The preferred way to get an `Instance` is asynchronously, for example using the [`WebAssembly.instantiateStreaming()`](instantiatestreaming) function like this: const importObject = { imports: { imported_func: function(arg) { console.log(arg); } } }; WebAssembly.instantiateStreaming(fetch('simple.wasm'), importObject) .then(obj => obj.instance.exports.exported_func()); This also demonstrates how the `exports` property is used to access exported functions. ## Specifications
      Specification
      WebAssembly JavaScript Interface (WebAssembly JavaScript Interface)
      #instances
      `Instance` 57 16 52 Disabled in the Firefox 52 Extended Support Release (ESR). No 44 11 57 57 52 Disabled in the Firefox 52 Extended Support Release (ESR). 43 11 7.0 `Instance` 57 16 52 Disabled in the Firefox 52 Extended Support Release (ESR). No 44 11 57 57 52 Disabled in the Firefox 52 Extended Support Release (ESR). 43 11 7.0 `exports` 57 16 52 Disabled in the Firefox 52 Extended Support Release (ESR). No 44 11 57 57 52 Disabled in the Firefox 52 Extended Support Release (ESR). 43 11 7.0 ## See also - [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) overview page - [WebAssembly concepts](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts) - [Using the WebAssembly JavaScript API](https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance # instanceof The `instanceof` tests to see if the `prototype` property of a constructor appears anywhere in the prototype chain of an object. The return value is a boolean value. ## Syntax object instanceof constructor ### Parameters `object` The object to test. `constructor` Function to test against ## Description The `instanceof` operator tests the presence of `constructor.prototype` in `object`'s prototype chain. // defining constructors function C() {} function D() {} let o = new C() // true, because: Object.getPrototypeOf(o) === C.prototype o instanceof C // false, because D.prototype is nowhere in o's prototype chain o instanceof D o instanceof Object // true, because: C.prototype instanceof Object // true C.prototype = {} let o2 = new C() o2 instanceof C // true // false, because C.prototype is nowhere in // o's prototype chain anymore o instanceof C D.prototype = new C() // add C to [[Prototype]] linkage of D let o3 = new D() o3 instanceof D // true o3 instanceof C // true since C.prototype is now in o3's prototype chain Note that the value of an `instanceof` test can change based on changes to the `prototype` property of constructors. It can also be changed by changing an object's prototype using `Object.setPrototypeOf`. It is also possible using the non-standard `__proto__` property. ### `instanceof` and multiple context (e.g. frames or windows) Different scopes have different execution environments. This means that they have different built-ins (different global object, different constructors, etc.). This may result in unexpected results. For instance, `[] instanceof window.frames[0].Array` will return `false`, because ` Array.prototype !== ``window.frames[0].Array.prototype ` and arrays inherit from the former. This may not make sense at first, but for scripts dealing with multiple frames or windows, and passing objects from one context to another via functions, this will be a valid and strong issue. For instance, you can securely check if a given object is, in fact, an Array using `Array.isArray(myObj)` For example, checking if a [Node](https://developer.mozilla.org/en-US/docs/Web/API/Node) is a [SVGElement](https://developer.mozilla.org/en-US/docs/Web/API/SVGElement) in a different context, you can use `myNode instanceof myNode.ownerDocument.defaultView.SVGElement`. ## Examples ### Using instanceof with String The following example shows the behavior of `instanceof` with `String` objects. let literalString = 'This is a literal string'; let stringObject = new String('String created with constructor'); literalString instanceof String; // false, string literal is not a String stringObject instanceof String; // true literalString instanceof Object; // false, string literal is not an Object stringObject instanceof Object; // true stringObject instanceof Date; // false ### Using instanceof with Date The following example shows the behavior of `instanceof` with `Date` objects. let myDate = new Date(); myDate instanceof Date; // true myDate instanceof Object; // true myDate instanceof String; // false ### Objects created using Object.create() The following example shows the behavior of `instanceof` with objects created using `Object.create()` function Shape() { } function Rectangle() { Shape.call(this); // call super constructor. } Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; let rect = new Rectangle(); rect instanceof Object; // true rect instanceof Shape; // true rect instanceof Rectangle; // true rect instanceof String; // false let literalObject = {}; let nullObject = Object.create(null); nullObject.name = "My object"; literalObject instanceof Object; // true, every object literal has Object.prototype as prototype ({}) instanceof Object; // true, same case as above nullObject instanceof Object; // false, prototype is end of prototype chain (null) ### Demonstrating that `mycar` is of type `Car` and type `Object` The following code creates an object type `Car` and an instance of that object type, `mycar`. The `instanceof` operator demonstrates that the `mycar` object is of type `Car` and of type `Object`. function Car(make, model, year) { this.make = make; this.model = model; this.year = year; } let mycar = new Car('Honda', 'Accord', 1998) let a = mycar instanceof Car // returns true let b = mycar instanceof Object // returns true ### Not an instanceof To test if an object is not an `instanceof` a specific constructor, you can do if (!(mycar instanceof Car)) { // Do something, like: // mycar = new Car(mycar) } This is really different from: if (!mycar instanceof Car) This will always be `false`. (`!mycar` will be evaluated before `instanceof`, so you always try to know if a boolean is an instance of `Car`). ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Relational Operators' in that specification.
      `instanceof` 1 12 1 5 4 1 1 18 4 10.1 1 1.0 ## See also - `typeof` - [`Symbol.hasInstance`](../global_objects/symbol/hasinstance) - [`Object.prototype.isPrototypeOf`](../global_objects/object/isprototypeof) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof # WebAssembly.instantiate() The `WebAssembly.instantiate()` function allows you to compile and instantiate WebAssembly code. This function has two overloads: - The primary overload takes the WebAssembly binary code, in the form of a [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) or [`ArrayBuffer`](../arraybuffer), and performs both compilation and instantiation in one step. The returned `Promise` resolves to both a compiled [`WebAssembly.Module`](module) and its first [`WebAssembly.Instance`](instance). - The secondary overload takes an already-compiled [`WebAssembly.Module`](module) and returns a `Promise` that resolves to an `Instance` of that `Module`. This overload is useful if the `Module` has already been compiled. **Warning:** This method is not the most efficient way of fetching and instantiating wasm modules. If at all possible, you should use the newer [`WebAssembly.instantiateStreaming()`](instantiatestreaming) method instead, which fetches, compiles, and instantiates a module all in one step, directly from the raw bytecode, so doesn't require conversion to an [`ArrayBuffer`](../arraybuffer). ## Syntax ### Primary overload — taking wasm binary code WebAssembly.instantiate(bufferSource, importObject); #### Parameters _bufferSource_ A [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) or [`ArrayBuffer`](../arraybuffer) containing the binary code of the .wasm module you want to compile. _importObject_ Optional An object containing the values to be imported into the newly-created `Instance`, such as functions or [`WebAssembly.Memory`](memory) objects. There must be one matching property for each declared import of the compiled module or else a [`WebAssembly.LinkError`](linkerror) is thrown. #### Return value A `Promise` that resolves to a `ResultObject` which contains two fields: - `module`: A [`WebAssembly.Module`](module) object representing the compiled WebAssembly module. This `Module` can be instantiated again, shared via [`postMessage()`](https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage) or [cached in IndexedDB](https://developer.mozilla.org/en-US/docs/WebAssembly/Caching_modules). - `instance`: A [`WebAssembly.Instance`](instance) object that contains all the [Exported WebAssembly functions](https://developer.mozilla.org/en-US/docs/WebAssembly/Exported_functions). #### Exceptions - If either of the parameters are not of the correct type or structure, a [`TypeError`](../typeerror) is thrown. - If the operation fails, the promise rejects with a [`WebAssembly.CompileError`](compileerror), [`WebAssembly.LinkError`](linkerror), or [`WebAssembly.RuntimeError`](runtimeerror), depending on the cause of the failure. ### Secondary overload — taking a module object instance WebAssembly.instantiate(module, importObject); #### Parameters _module_ The [`WebAssembly.Module`](module) object to be instantiated. _importObject_ Optional An object containing the values to be imported into the newly-created `Instance`, such as functions or [`WebAssembly.Memory`](memory) objects. There must be one matching property for each declared import of `module` or else a [`WebAssembly.LinkError`](linkerror) is thrown. #### Return value A `Promise` that resolves to an [`WebAssembly.Instance`](instance) object. #### Exceptions - If either of the parameters are not of the correct type or structure, a [`TypeError`](../typeerror) is thrown. - If the operation fails, the promise rejects with a [`WebAssembly.CompileError`](compileerror), [`WebAssembly.LinkError`](linkerror), or [`WebAssembly.RuntimeError`](runtimeerror), depending on the cause of the failure. ## Examples **Note**: You'll probably want to use [`WebAssembly.instantiateStreaming()`](instantiatestreaming) in most cases, as it is more efficient than `instantiate()`. ### First overload example After fetching some WebAssembly bytecode using fetch, we compile and instantiate the module using the [`WebAssembly.instantiate()`](instantiate) function, importing a JavaScript function into the WebAssembly Module in the process. We then call an [Exported WebAssembly function](https://developer.mozilla.org/en-US/docs/WebAssembly/Exported_functions) that is exported by the `Instance`. var importObject = { imports: { imported_func: function(arg) { console.log(arg); } } }; fetch('simple.wasm').then(response => response.arrayBuffer() ).then(bytes => WebAssembly.instantiate(bytes, importObject) ).then(result => result.instance.exports.exported_func() ); **Note:** You can also find this example at [index.html](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/index.html) on GitHub ([view it live also](https://mdn.github.io/webassembly-examples/js-api-examples/)). ### Second overload example The following example (see our [index-compile.html](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/index-compile.html) demo on GitHub, and [view it live](https://mdn.github.io/webassembly-examples/js-api-examples/index-compile.html) also) compiles the loaded simple.wasm byte code using the [`WebAssembly.compileStreaming()`](compilestreaming) method and then sends it to a [worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) using [`postMessage()`](https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage). var worker = new Worker("wasm_worker.js"); WebAssembly.compileStreaming(fetch('simple.wasm')) .then(mod => worker.postMessage(mod) ); In the worker (see `wasm_worker.js`) we define an import object for the module to use, then set up an event handler to receive the module from the main thread. When the module is received, we create an instance from it using the [`WebAssembly.instantiate()`](instantiate) method and invoke an exported function from inside it. var importObject = { imports: { imported_func: function(arg) { console.log(arg); } } }; onmessage = function(e) { console.log('module received from main thread'); var mod = e.data; WebAssembly.instantiate(mod, importObject).then(function(instance) { instance.exports.exported_func(); }); }; ## Specifications
      Specification
      WebAssembly JavaScript Interface (WebAssembly JavaScript Interface)
      #dom-webassembly-instantiate
      `instantiate` 57 16 52 Disabled in the Firefox 52 Extended Support Release (ESR). No 44 11 57 57 52 Disabled in the Firefox 52 Extended Support Release (ESR). 43 11 7.0 ## See also - [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) overview page - [WebAssembly concepts](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts) - [Using the WebAssembly JavaScript API](https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate # WebAssembly.instantiateStreaming() The `WebAssembly.instantiateStreaming()` function compiles and instantiates a WebAssembly module directly from a streamed underlying source. This is the most efficient, optimized way to load wasm code. ## Syntax WebAssembly.instantiateStreaming(source, importObject) ### Parameters _source_ A [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object or a promise that will fulfill with one, representing the underlying source of a .wasm module you want to stream, compile, and instantiate. _importObject_ Optional An object containing the values to be imported into the newly-created `Instance`, such as functions or [`WebAssembly.Memory`](memory) objects. There must be one matching property for each declared import of the compiled module or else a `WebAssembly.LinkError` is thrown. ### Return value A `Promise` that resolves to a `ResultObject` which contains two fields: - `module`: A [`WebAssembly.Module`](module) object representing the compiled WebAssembly module. This `Module` can be instantiated again or shared via [postMessage()](https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage). - `instance`: A [`WebAssembly.Instance`](instance) object that contains all the [Exported WebAssembly functions](https://developer.mozilla.org/en-US/docs/WebAssembly/Exported_functions). ### Exceptions - If either of the parameters are not of the correct type or structure, a [`TypeError`](../typeerror) is thrown. - If the operation fails, the promise rejects with a [`WebAssembly.CompileError`](compileerror), [`WebAssembly.LinkError`](linkerror), or [`WebAssembly.RuntimeError`](runtimeerror), depending on the cause of the failure. ## Examples ### Instantiating streaming The following example (see our [instantiate-streaming.html](https://github.com/mdn/webassembly-examples/blob/master/js-api-examples/instantiate-streaming.html) demo on GitHub, and [view it live](https://mdn.github.io/webassembly-examples/js-api-examples/instantiate-streaming.html) also) directly streams a .wasm module from an underlying source then compiles and instantiates it, the promise fulfilling with a `ResultObject`. Because the `instantiateStreaming()` function accepts a promise for a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object, you can directly pass it a [`WindowOrWorkerGlobalScope.fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch) call, and it will pass the response into the function when it fulfills. var importObject = { imports: { imported_func: arg => console.log(arg) } }; WebAssembly.instantiateStreaming(fetch('simple.wasm'), importObject) .then(obj => obj.instance.exports.exported_func()); The `ResultObject`'s instance member is then accessed, and the contained exported function invoked. **Note:** For this to work, `.wasm` files should be returned with an `application/wasm` MIME type by the server. ## Specifications
      Specification
      WebAssembly Web API (WebAssembly Web API)
      #dom-webassembly-instantiatestreaming
      `instantiateStreaming` 61 16 58 No 47 No 61 61 58 45 No 8.0 ## See also - [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly) overview page - [WebAssembly concepts](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts) - [Using the WebAssembly JavaScript API](https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming # Int16Array The `Int16Array` typed array represents an array of twos-complement 16-bit signed integers in the platform byte order. If control over byte order is needed, use [`DataView`](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). ## Constructor [`Int16Array()`](int16array/int16array) Creates a new `Int16Array` object. ## Static properties [`Int16Array.BYTES_PER_ELEMENT`](typedarray/bytes_per_element) Returns a number value of the element size. `2` in the case of an `Int16Array`. [`Int16Array.name`](typedarray/name) Returns the string value of the constructor name. In the case of the `Int16Array` type: "`Int16Array`". ## Static methods [`Int16Array.from()`](typedarray/from) Creates a new `Int16Array` from an array-like or iterable object. See also [`Array.from()`](array/from). [`Int16Array.of()`](typedarray/of) Creates a new `Int16Array` with a variable number of arguments. See also [`Array.of()`](array/of). ## Instance properties [`Int16Array.prototype.buffer`](typedarray/buffer) Returns the [`ArrayBuffer`](arraybuffer) referenced by the `Int16Array`. Fixed at construction time and thus **read only**. [`Int16Array.prototype.byteLength`](typedarray/bytelength) Returns the length (in bytes) of the `Int16Array` from the start of its [`ArrayBuffer`](arraybuffer). Fixed at construction time and thus **read only.** [`Int16Array.prototype.byteOffset`](typedarray/byteoffset) Returns the offset (in bytes) of the `Int16Array` from the start of its [`ArrayBuffer`](arraybuffer). Fixed at construction time and thus **read only.** [`Int16Array.prototype.length`](typedarray/length) Returns the number of elements held in the `Int16Array`. Fixed at construction time and thus **read only.** ## Instance methods [`Int16Array.prototype.copyWithin()`](typedarray/copywithin) Copies a sequence of array elements within the array. See also [`Array.prototype.copyWithin()`](array/copywithin). [`Int16Array.prototype.entries()`](typedarray/entries) Returns a new _array iterator_ object that contains the key/value pairs for each index in the array. See also [`Array.prototype.entries()`](array/entries). [`Int16Array.prototype.every()`](typedarray/every) Tests whether all elements in the array pass the test provided by a function. See also [`Array.prototype.every()`](array/every). [`Int16Array.prototype.fill()`](typedarray/fill) Fills all the elements of an array from a start index to an end index with a static value. See also [`Array.prototype.fill()`](array/fill). [`Int16Array.prototype.filter()`](typedarray/filter) Creates a new array with all of the elements of this array for which the provided filtering function returns `true`. See also [`Array.prototype.filter()`](array/filter). [`Int16Array.prototype.find()`](typedarray/find) Returns the found value in the array, if an element in the array satisfies the provided testing function or `undefined` if not found. See also [`Array.prototype.find()`](array/find). [`Int16Array.prototype.findIndex()`](typedarray/findindex) Returns the found index in the array, if an element in the array satisfies the provided testing function or `-1` if not found. See also [`Array.prototype.findIndex()`](array/findindex). [`Int16Array.prototype.forEach()`](typedarray/foreach) Calls a function for each element in the array. See also [`Array.prototype.forEach()`](array/foreach). [`Int16Array.prototype.includes()`](typedarray/includes) Determines whether a typed array includes a certain element, returning `true` or `false` as appropriate. See also [`Array.prototype.includes()`](array/includes). [`Int16Array.prototype.indexOf()`](typedarray/indexof) Returns the first (least) index of an element within the array equal to the specified value, or `-1` if none is found. See also [`Array.prototype.indexOf()`](array/indexof). [`Int16Array.prototype.join()`](typedarray/join) Joins all elements of an array into a string. See also [`Array.prototype.join()`](array/join). [`Int16Array.prototype.keys()`](typedarray/keys) Returns a new _array iterator_ that contains the keys for each index in the array. See also [`Array.prototype.keys()`](array/keys). [`Int16Array.prototype.lastIndexOf()`](typedarray/lastindexof) Returns the last (greatest) index of an element within the array equal to the specified value, or `-1` if none is found. See also [`Array.prototype.lastIndexOf()`](array/lastindexof). [`Int16Array.prototype.map()`](typedarray/map) Creates a new array with the results of calling a provided function on every element in this array. See also [`Array.prototype.map()`](array/map). [`Int16Array.prototype.reduce()`](typedarray/reduce) Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value. See also [`Array.prototype.reduce()`](array/reduce). [`Int16Array.prototype.reduceRight()`](typedarray/reduceright) Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value. See also [`Array.prototype.reduceRight()`](array/reduceright). [`Int16Array.prototype.reverse()`](typedarray/reverse) Reverses the order of the elements of an array — the first becomes the last, and the last becomes the first. See also [`Array.prototype.reverse()`](array/reverse). [`Int16Array.prototype.set()`](typedarray/set) Stores multiple values in the typed array, reading input values from a specified array. [`Int16Array.prototype.slice()`](typedarray/slice) Extracts a section of an array and returns a new array. See also [`Array.prototype.slice()`](array/slice). [`Int16Array.prototype.some()`](typedarray/some) Returns `true` if at least one element in this array satisfies the provided testing function. See also [`Array.prototype.some()`](array/some). [`Int16Array.prototype.sort()`](typedarray/sort) Sorts the elements of an array in place and returns the array. See also [`Array.prototype.sort()`](array/sort). [`Int16Array.prototype.subarray()`](typedarray/subarray) Returns a new `Int16Array` from the given start and end element index. [`Int16Array.prototype.values()`](typedarray/values) Returns a new **array iterator object that contains the values for each index in the array. See also [`Array.prototype.values()`](array/values).** **[`Int16Array.prototype.toLocaleString()`](typedarray/tolocalestring)** **Returns a localized string representing the array and its elements. See also [`Array.prototype.toLocaleString()`](array/tolocalestring).** **[`Int16Array.prototype.toString()`](typedarray/tostring)** **Returns a string representing the array and its elements. See also [`Array.prototype.toString()`](array/tostring).** **[`Int16Array.prototype[@@iterator]()`](typedarray/@@iterator)** **Returns a new _array iterator_ object that contains the values for each index in the array.** ## Examples ### Different ways to create an Int16Array // From a length var int16 = new Int16Array(2); int16[0] = 42; console.log(int16[0]); // 42 console.log(int16.length); // 2 console.log(int16.BYTES_PER_ELEMENT); // 2 // From an array var arr = new Int16Array([21,31]); console.log(arr[1]); // 31 // From another TypedArray var x = new Int16Array([21, 31]); var y = new Int16Array(x); console.log(y[0]); // 21 // From an ArrayBuffer var buffer = new ArrayBuffer(8); var z = new Int16Array(buffer, 0, 4); // From an iterable var iterable = function*(){ yield* [1,2,3]; }(); var int16 = new Int16Array(iterable); // Int16Array[1, 2, 3] ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #table-49
      `Int16Array` 7 12 4 10 11.6 5.1 4 18 4 12 4.2 1.0 `Int16Array` 7 12 4 10 11.6 5.1 4 18 4 12 4.2 1.0 ## See also - **[JavaScript typed arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays)** - **[`ArrayBuffer`](arraybuffer)** - **[`DataView`](dataview)** https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array # Int32Array The `Int32Array()` typed array constructor creates an array of twos-complement 32-bit signed integers in the platform byte order. If control over byte order is needed, use [`DataView`](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). ## Syntax new Int32Array(); // new in ES2017 new Int32Array(length); new Int32Array(typedArray); new Int32Array(object); new Int32Array(buffer); new Int32Array(buffer, byteOffset); new Int32Array(buffer, byteOffset, length); ### Parameters `length` When called with a `length` argument, an internal array buffer is created in memory, of size `length` _multiplied by `BYTES_PER_ELEMENT`_ bytes, containing zeros. `typedArray` When called with a `typedArray` argument, which can be an object of any of the typed array types (such as `Int32Array`), the `typedArray` gets copied into a new typed array. Each value in `typedArray` is converted to the corresponding type of the constructor before being copied into the new array. The length of the new typed array will be same as the length of the `typedArray` argument. `object` When called with an `object` argument, a new typed array is created as if by the `TypedArray.from()` method. `buffer`, `byteOffset`, `length` When called with a `buffer`, and optionally a `byteOffset` and a `length` argument, a new typed array view is created that views the specified [`ArrayBuffer`](arraybuffer). The `byteOffset` and `length` parameters specify the memory range that will be exposed by the typed array view. If both are omitted, all of `buffer` is viewed; if only `length` is omitted, the remainder of `buffer` is viewed. ## Examples ### Different ways to create an Int32Array // From a length var int32 = new Int32Array(2); int32[0] = 42; console.log(int32[0]); // 42 console.log(int32.length); // 2 console.log(int32.BYTES_PER_ELEMENT); // 4 // From an array var arr = new Int32Array([21,31]); console.log(arr[1]); // 31 // From another TypedArray var x = new Int32Array([21, 31]); var y = new Int32Array(x); console.log(y[0]); // 21 // From an ArrayBuffer var buffer = new ArrayBuffer(16); var z = new Int32Array(buffer, 0, 4); // From an iterable var iterable = function*(){ yield* [1,2,3]; }(); var int32 = new Int32Array(iterable); // Int32Array[1, 2, 3] ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-typedarray-constructors
      `Int32Array` 7 12 4 10 11.6 5.1 4 18 4 12 4.2 1.0 `constructor_without_arguments` 7 12 55 10 11.6 5.1 ≤37 18 55 12 5 1.0 `iterable_allowed` 39 14 52 No 26 10 39 39 52 26 10 4.0 `new_required` 7 14 44 No 15 5.1 ≤37 18 44 14 5 1.0 ### Compatibility notes Starting with ECMAScript 2015, `Int32Array` constructors require to be constructed with a [`new`](../operators/new) operator. Calling a `Int32Array` constructor as a function without `new`, will throw a [`TypeError`](typeerror) from now on. var dv = Int32Array([1, 2, 3]); // TypeError: calling a builtin Int32Array constructor // without new is forbidden var dv = new Int32Array([1, 2, 3]); ## See also - [JavaScript typed arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) - [`ArrayBuffer`](arraybuffer) - [`DataView`](dataview) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array # Int8Array The `Int8Array` typed array represents an array of twos-complement 8-bit signed integers. 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). ## Constructor [`Int8Array()`](int8array/int8array) Creates a new `Int8Array` object. ## Static properties [`Int8Array.BYTES_PER_ELEMENT`](typedarray/bytes_per_element) Returns a number value of the element size. `1` in the case of an `Int8Array`. [`Int8Array.name`](typedarray/name) Returns the string value of the constructor name. In the case of the `Int8Array` type: "`Int8Array`". ## Static methods [`Int8Array.from()`](typedarray/from) Creates a new `Int8Array` from an array-like or iterable object. See also [`Array.from()`](array/from). [`Int8Array.of()`](typedarray/of) Creates a new `Int8Array` with a variable number of arguments. See also [`Array.of()`](array/of). ## Instance properties [`Int8Array.prototype.buffer`](typedarray/buffer) Returns the [`ArrayBuffer`](arraybuffer) referenced by the `Int8Array`. Fixed at construction time and thus **read only**. [`Int8Array.prototype.byteLength`](typedarray/bytelength) Returns the length (in bytes) of the `Int8Array` from the start of its [`ArrayBuffer`](arraybuffer). Fixed at construction time and thus **read only.** [`Int8Array.prototype.byteOffset`](typedarray/byteoffset) Returns the offset (in bytes) of the `Int8Array` from the start of its [`ArrayBuffer`](arraybuffer). Fixed at construction time and thus **read only.** [`Int8Array.prototype.length`](typedarray/length) Returns the number of elements held in the `Int8Array`. Fixed at construction time and thus **read only.** ## Instance methods [`Int8Array.prototype.copyWithin()`](typedarray/copywithin) Copies a sequence of array elements within the array. See also [`Array.prototype.copyWithin()`](array/copywithin). [`Int8Array.prototype.entries()`](typedarray/entries) Returns a new _array iterator_ object that contains the key/value pairs for each index in the array. See also [`Array.prototype.entries()`](array/entries). [`Int8Array.prototype.every()`](typedarray/every) Tests whether all elements in the array pass the test provided by a function. See also [`Array.prototype.every()`](array/every). [`Int8Array.prototype.fill()`](typedarray/fill) Fills all the elements of an array from a start index to an end index with a static value. See also [`Array.prototype.fill()`](array/fill). [`Int8Array.prototype.filter()`](typedarray/filter) Creates a new array with all of the elements of this array for which the provided filtering function returns `true`. See also [`Array.prototype.filter()`](array/filter). [`Int8Array.prototype.find()`](typedarray/find) Returns the found value in the array, if an element in the array satisfies the provided testing function or `undefined` if not found. See also [`Array.prototype.find()`](array/find). [`Int8Array.prototype.findIndex()`](typedarray/findindex) Returns the found index in the array, if an element in the array satisfies the provided testing function or `-1` if not found. See also [`Array.prototype.findIndex()`](array/findindex). [`Int8Array.prototype.forEach()`](typedarray/foreach) Calls a function for each element in the array. See also [`Array.prototype.forEach()`](array/foreach). [`Int8Array.prototype.includes()`](typedarray/includes) Determines whether a typed array includes a certain element, returning `true` or `false` as appropriate. See also [`Array.prototype.includes()`](array/includes). [`Int8Array.prototype.indexOf()`](typedarray/indexof) Returns the first (least) index of an element within the array equal to the specified value, or `-1` if none is found. See also [`Array.prototype.indexOf()`](array/indexof). [`Int8Array.prototype.join()`](typedarray/join) Joins all elements of an array into a string. See also [`Array.prototype.join()`](array/join). [`Int8Array.prototype.keys()`](typedarray/keys) Returns a new _array iterator_ that contains the keys for each index in the array. See also [`Array.prototype.keys()`](array/keys). [`Int8Array.prototype.lastIndexOf()`](typedarray/lastindexof) Returns the last (greatest) index of an element within the array equal to the specified value, or `-1` if none is found. See also [`Array.prototype.lastIndexOf()`](array/lastindexof). [`Int8Array.prototype.map()`](typedarray/map) Creates a new array with the results of calling a provided function on every element in this array. See also [`Array.prototype.map()`](array/map). [`Int8Array.prototype.reduce()`](typedarray/reduce) Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value. See also [`Array.prototype.reduce()`](array/reduce). [`Int8Array.prototype.reduceRight()`](typedarray/reduceright) Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value. See also [`Array.prototype.reduceRight()`](array/reduceright). [`Int8Array.prototype.reverse()`](typedarray/reverse) Reverses the order of the elements of an array — the first becomes the last, and the last becomes the first. See also [`Array.prototype.reverse()`](array/reverse). [`Int8Array.prototype.set()`](typedarray/set) Stores multiple values in the typed array, reading input values from a specified array. [`Int8Array.prototype.slice()`](typedarray/slice) Extracts a section of an array and returns a new array. See also [`Array.prototype.slice()`](array/slice). [`Int8Array.prototype.some()`](typedarray/some) Returns `true` if at least one element in this array satisfies the provided testing function. See also [`Array.prototype.some()`](array/some). [`Int8Array.prototype.sort()`](typedarray/sort) Sorts the elements of an array in place and returns the array. See also [`Array.prototype.sort()`](array/sort). [`Int8Array.prototype.subarray()`](typedarray/subarray) Returns a new `Int8Array` from the given start and end element index. [`Int8Array.prototype.values()`](typedarray/values) Returns a new _array iterator_ object that contains the values for each index in the array. See also [`Array.prototype.values()`](array/values). [`Int8Array.prototype.toLocaleString()`](typedarray/tolocalestring) Returns a localized string representing the array and its elements. See also [`Array.prototype.toLocaleString()`](array/tolocalestring). [`Int8Array.prototype.toString()`](typedarray/tostring) Returns a string representing the array and its elements. See also [`Array.prototype.toString()`](array/tostring). [`Int8Array.prototype[@@iterator]()`](typedarray/@@iterator) Returns a new _array iterator_ object that contains the values for each index in the array. ## Examples ### Different ways to create an Int8Array // From a length var int8 = new Int8Array(2); int8[0] = 42; console.log(int8[0]); // 42 console.log(int8.length); // 2 console.log(int8.BYTES_PER_ELEMENT); // 1 // From an array var arr = new Int8Array([21,31]); console.log(arr[1]); // 31 // From another TypedArray var x = new Int8Array([21, 31]); var y = new Int8Array(x); console.log(y[0]); // 21 // From an ArrayBuffer var buffer = new ArrayBuffer(8); var z = new Int8Array(buffer, 1, 4); // From an iterable var iterable = function*(){ yield* [1,2,3]; }(); var int8 = new Int8Array(iterable); // Int8Array[1, 2, 3] ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'TypedArray constructors' in that specification.
      `Int8Array` 7 12 4 10 11.6 5.1 4 18 4 12 4.2 1.0 `Int8Array` 7 12 4 10 11.6 5.1 4 18 4 12 4.2 1.0 ## See also - [JavaScript typed arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) - [`ArrayBuffer`](arraybuffer) - [`DataView`](dataview) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array # InternalError **Non-standard** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future. The `InternalError` indicates an error that occurred internally in the JavaScript engine. Example cases are mostly when something is too large, e.g.: - "too many switch cases", - "too many parentheses in regular expression", - "array initializer too large", - "too much recursion". ## Constructor [`InternalError()`](internalerror/internalerror) Creates a new `InternalError` object. ## Instance properties [`InternalError.prototype.message`](error/message) Error message. Inherited from [`Error`](error). [`InternalError.prototype.name`](error/name) Error name. Inherited from [`Error`](error). [`InternalError.prototype.fileName`](error/filename) Path to file that raised this error. Inherited from [`Error`](error). [`InternalError.prototype.lineNumber`](error/linenumber) Line number in file that raised this error. Inherited from [`Error`](error). [`InternalError.prototype.columnNumber`](error/columnnumber) Column number in line that raised this error. Inherited from [`Error`](error). [`InternalError.prototype.stack`](error/stack) Stack trace. Inherited from [`Error`](error). ## Examples ### Too much recursion This recursive function runs 10 times, as per the exit condition. function loop(x) { if (x >= 10) // "x >= 10" is the exit condition return; // do stuff loop(x + 1); // the recursive call } loop(0); Setting this condition to an extremely high value, won't work: function loop(x) { if (x >= 1000000000000) return; // do stuff loop(x + 1); } loop(0); // InternalError: too much recursion For more information, see [InternalError: too much recursion.](../errors/too_much_recursion) ## Specifications Not part of any standard. `InternalError` No No 1 No No No No No 4 No No No `InternalError` No No 1 No No No No No 4 No No No ## See also - [`Error`](error) - [InternalError: too much recursion](../errors/too_much_recursion) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/InternalError # Intl The `Intl` object is the namespace for the ECMAScript Internationalization API, which provides language sensitive string comparison, number formatting, and date and time formatting. The `Intl` object provides access to several constructors as well as functionality common to the internationalization constructors and other language sensitive functions. ## Constructor properties [`Intl.Collator()`](intl/collator/collator) Constructor for collators, which are objects that enable language-sensitive string comparison. [`Intl.DateTimeFormat()`](intl/datetimeformat/datetimeformat) Constructor for objects that enable language-sensitive date and time formatting. [`Intl.DisplayNames()`](intl/displaynames/displaynames) Constructor for objects that enable the consistent translation of language, region and script display names. [`Intl.ListFormat()`](intl/listformat/listformat) Constructor for objects that enable language-sensitive list formatting. [`Intl.Locale()`](intl/locale/locale) Constructor for objects that represents a Unicode locale identifier. [`Intl.NumberFormat()`](intl/numberformat/numberformat) Constructor for objects that enable language-sensitive number formatting. [`Intl.PluralRules()`](intl/pluralrules/pluralrules) Constructor for objects that enable plural-sensitive formatting and language-specific rules for plurals. [`Intl.RelativeTimeFormat()`](intl/relativetimeformat/relativetimeformat) Constructor for objects that enable language-sensitive relative time formatting. ## Static methods [`Intl.getCanonicalLocales()`](intl/getcanonicallocales) Returns canonical locale names. ## Locale identification and negotiation The internationalization constructors as well as several language sensitive methods of other constructors (listed under [See also](#see_also)) use a common pattern for identifying locales and determining the one they will actually use: they all accept `locales` and `options` arguments, and negotiate the requested locale(s) against the locales they support using an algorithm specified in the `options.localeMatcher` property. ### locales argument The `locales` argument is used to determine the locale used in a given operation. The JavaScript implementation examines `locales`, and then computes a locale it understands that comes closest to satisfying the expressed preference. `locales` may be: - `undefined` (or omitted): The implementation's default locale will be used. - A locale: A locale identifier or an `Intl.Locale` object that wraps a locale identifier. - A list of locales: Any other value, that will be converted into an object and then treated as an array of locales. In the latter two cases, the actual locale used is the best-supported locale determined by [locale negotiation](#locale_negotiation). A locale identifier is a string that consists of: 1. a language subtag, 2. (optionally) a script subtag, 3. (optionally) a region (or country) subtag, 4. (optionally) one or more variant subtags (all of which must be unique), 5. (optionally) one or more BCP 47 extension sequences, and 6. (optionally) a private-use extension sequence ...with all present subtags and sequences separated by hyphens. Locale identifiers are case-insensitive ASCII. However, it's conventional to use title case (first letter capitalized, successive letters lower case) for script subtags, upper case for region subtags, and lower case for everything else. For example: - "`hi`": Hindi (language) - "`de-AT`": German (language) as used in Austria (region) - "`zh-Hans-CN`": Chinese (language) written in simplified characters (script) as used in China (region) - "`en-emodeng`": English (language) in the "Early modern English" dialect (variant) Subtags identifying languages, scripts, regions (including countries), and (rarely used) variants are registered in the [IANA Language Subtag Registry](https://www.iana.org/assignments/language-subtag-registry). This registry is periodically updated over time, and implementations may not always be up to date, so don't rely too much on subtags being universally supported. BCP 47 extension sequences consist of a single digit or letter (other than `"x"`) and one or more two- to eight-letter or digit subtags separated by hyphens. Only one sequence is permitted for each digit or letter: "`de-a-foo-a-foo`" is invalid. BCP 47 extension subtags are defined in the [Unicode CLDR Project](https://github.com/unicode-org/cldr/tree/master/common/bcp47). Currently only two extensions have defined semantics: - The `"u"` (Unicode) extension can be used to request additional customization of [`Intl/Collator`](intl/collator), [`Intl/NumberFormat`](intl/numberformat), or [`Intl/DateTimeFormat`](intl/datetimeformat) objects. Examples: - "`de-DE-u-co-phonebk`": Use the phonebook variant of the German sort order, which interprets umlauted vowels as corresponding character pairs: ä → ae, ö → oe, ü → ue. - "`th-TH-u-nu-thai`": Use Thai digits (๐, ๑, ๒, ๓, ๔, ๕, ๖, ๗, ๘, ๙) in number formatting. - "`ja-JP-u-ca-japanese`": Use the Japanese calendar in date and time formatting, so that 2013 is expressed as the year 25 of the Heisei period, or 平成 25. - "`en-GB-u-ca-islamic`": use British English with the Islamic (Hijri) calendar, where the Gregorian date 14 October, 2017 is the Hijri date 24 Muharram, 1439. - The `"t"` (transformed) extension indicates transformed content: for example, text that was translated from another locale. No `Intl` functionality currently considers the `"t"` extension. However, this extension sometimes contains a nested locale (with no extensions): for example, the transformed extension in "`de-t-en`" contains the locale identifier for English. If a nested locale is present, it must be a valid locale identifier. For example, because "`en-emodeng-emodeng`" is invalid (because it contains a duplicate `emodeng` variant subtag), "`de-t-en-emodeng-emodeng`" is also invalid. Finally, a private-use extension sequence using the letter `"x"` may appear, followed by one or more one- to eight-letter or digit subtags separated by hyphens. This allows applications to encode information for their own private use, that will be ignored by all `Intl` operations. ### Locale negotiation The list of locales specified by the `locales` argument, after Unicode extensions have been removed from them, is interpreted as a prioritized request from the application. The runtime compares it against the locales it has available and picks the best one available. Two matching algorithms exist: the "`lookup`" matcher follows the Lookup algorithm specified in [BCP 47](https://datatracker.ietf.org/doc/html/rfc4647#section-3.4); the "`best fit`" matcher lets the runtime provide a locale that's at least, but possibly more, suited for the request than the result of the Lookup algorithm. If the application doesn't provide a `locales` argument, or the runtime doesn't have a locale that matches the request, then the runtime's default locale is used. The matcher can be selected using a property of the `options` argument (see below). If the selected locale identifier had a Unicode extension sequence, that extension is now used to customize the constructed object or the behavior of the function. Each constructor or function supports only a subset of the keys defined for the Unicode extension, and the supported values often depend on the locale identifier. For example, the "`co`" key (collation) is only supported by [`Intl/Collator`](intl/collator), and its "`phonebk`" value is only supported for German. ### options argument The `options` argument must be an object with properties that vary between constructors and functions. If the `options` argument is not provided or is undefined, default values are used for all properties. One property is supported by all language sensitive constructors and functions: The `localeMatcher` property, whose value must be a string "`lookup`" or "`best fit`" and which selects one of the locale matching algorithms described above. ## Examples ### Formatting dates and numbers You can use `Intl` to format dates and numbers in a form that's conventional for a specific language and region: const count = 26254.39; const date = new Date("2012-05-24"); function log(locale) { console.log( `${new Intl.DateTimeFormat(locale).format(date)}${new Intl.NumberFormat(locale).format(count)}` ); } log("en-US"); // expected output: 5/24/2012 26,254.39 log("de-DE"); // expected output: 24.5.2012 26.254,39 ## Specifications
      Specification
      ECMAScript Internationalization API Specification (ECMAScript Internationalization API)
      #intl-object
      `Collator` 24 12 29 11 15 10 4.4 25 56 14 10 1.5 `DateTimeFormat` 24 12 29 11 15 10 4.4 25 56 14 10 1.5 `DisplayNames` 81 81 86 No 68 14.1 81 81 86 58 14.5 No `Intl` 24 12 29 11 15 10 4.4 25 56 14 10 1.5 `getCanonicalLocales` 54 16 48 No No 11 No No 56 No 11 No `@@toStringTag` 86 86 83 No 72 14 86 86 83 No 14 No `ListFormat` 72 79 78 No 60 14.1 72 72 79 51 14.5 No `Locale` 74 79 75 No 62 14 74 74 79 53 14 11.0 `NumberFormat` 24 12 29 11 15 10 4.4 25 56 14 10 1.5 `PluralRules` 63 18 58 No 50 13 63 63 58 46 13 8.0 `RelativeTimeFormat` 71 79 65 No 58 14 71 71 65 50 14 10.0 ## See also - Introduction: [The ECMAScript Internationalization API](https://norbertlindenberg.com/2012/12/ecmascript-internationalization-api/index.html) - Constructors - [`Intl.Collator`](intl/collator) - [`Intl.DateTimeFormat`](intl/datetimeformat) - [`Intl.ListFormat`](intl/listformat) - [`Intl.NumberFormat`](intl/numberformat) - [`Intl.PluralRules`](intl/pluralrules) - [`Intl.RelativeTimeFormat`](intl/relativetimeformat) - [`Intl.Locale`](intl/locale) - Methods - [`String.prototype.localeCompare()`](string/localecompare) - [`Number.prototype.toLocaleString()`](number/tolocalestring) - [`Date.prototype.toLocaleString()`](date/tolocalestring) - [`Date.prototype.toLocaleDateString()`](date/tolocaledatestring) - [`Date.prototype.toLocaleTimeString()`](date/tolocaletimestring) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl # RangeError: invalid array length The JavaScript exception "Invalid array length" occurs when specifying an array length that is either negative or exceeds the maximum supported by the platform (i.e. when creating an [`Array`](../global_objects/array) or [`ArrayBuffer`](../global_objects/arraybuffer), or when setting the [`Array.length`](../global_objects/array/length) property). The maximum allowed array length depends on the platform, browser and browser version. For [`Array`](../global_objects/array) the maximum length is 2GB-1 (2^32-1). For [`ArrayBuffer`](../global_objects/arraybuffer) the maximum is 2GB-1 on 32-bit systems (2^32-1). From Firefox version 89 the maximum value of [`ArrayBuffer`](../global_objects/arraybuffer) is 8GB on 64-bit systems (2^33). **Note:** `Array` and `ArrayBuffer` are independent data structures (the implementation of one does not affect the other). ## Message RangeError: invalid array length (Firefox) RangeError: Invalid array length (Chromium-based) RangeError: Array buffer allocation failed (Chromium-based) ## Error type [`RangeError`](../global_objects/rangeerror) ## What went wrong? An invalid array length might appear in these situations: - Creating an [`Array`](../global_objects/array) or [`ArrayBuffer`](../global_objects/arraybuffer) with a negative length, or setting a negative value for the [`Array.length`](../global_objects/array/length) property. - Creating an [`Array`](../global_objects/array) or setting the [`Array.length`](../global_objects/array/length) property greater than 2GB-1 (2^32-1). - Creating an [`ArrayBuffer`](../global_objects/arraybuffer) that is bigger than 2GB-1 (2^32-1) on a 32-bit system or 8GB (2^33) on a 64-bit system. - Before Firefox 89: Creating an [`ArrayBuffer`](../global_objects/arraybuffer) that is bigger than 2GB-1 (2^32-1). If you are creating an `Array`, using the constructor, you probably want to use the literal notation instead, as the first argument is interpreted as the length of the `Array`. Otherwise, you might want to clamp the length before setting the length property, or using it as argument of the constructor. ## Examples ### Invalid cases new Array(Math.pow(2, 40)) new Array(-1) new ArrayBuffer(Math.pow(2, 32)) //32-bit system new ArrayBuffer(-1) let a = []; a.length = a.length - 1; // set -1 to the length property let b = new Array(Math.pow(2, 32) - 1); b.length = b.length + 1; // set 2^32 to the length property ### Valid cases [ Math.pow(2, 40) ] // [ 1099511627776 ] [ -1 ] // [ -1 ] new ArrayBuffer(Math.pow(2, 32) - 1) new ArrayBuffer(Math.pow(2, 33)) // 64-bit systems after Firefox 89 new ArrayBuffer(0) let a = []; a.length = Math.max(0, a.length - 1); let b = new Array(Math.pow(2, 32) - 1); b.length = Math.min(0xffffffff, b.length + 1); // 0xffffffff is the hexadecimal notation for 2^32 - 1 // which can also be written as (-1 >>> 0) ## See also - [`Array`](../global_objects/array) - [`Array.length`](../global_objects/array/length) - [`ArrayBuffer`](../global_objects/arraybuffer) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length # ReferenceError: invalid assignment left-hand side The JavaScript exception "invalid assignment left-hand side" occurs when there was an unexpected assignment somewhere. For example, a single "`=`" sign was used instead of "`==`" or "`===`". ## Message ReferenceError: invalid assignment left-hand side ## Error type [`ReferenceError`](../global_objects/referenceerror). ## What went wrong? There was an unexpected assignment somewhere. This might be due to a mismatch of a [assignment operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#assignment_operators) and a [comparison operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators), for example. While a single "`=`" sign assigns a value to a variable, the "`==`" or "`===`" operators compare a value. ## Examples ### Typical invalid assignments if (Math.PI = 3 || Math.PI = 4) { console.log('no way!'); } // ReferenceError: invalid assignment left-hand side var str = 'Hello, ' += 'is it me ' += 'you\'re looking for?'; // ReferenceError: invalid assignment left-hand side In the `if` statement, you want to use a comparison operator ("=="), and for the string concatenation, the plus ("+") operator is needed. if (Math.PI == 3 || Math.PI == 4) { console.log('no way!'); } var str = 'Hello, ' + 'from the ' + 'other side!'; ## See also - [Assignment operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#assignment_operators) - [Comparison operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_assignment_left-hand_side # TypeError: invalid assignment to const "x" The JavaScript exception "invalid assignment to const" occurs when it was attempted to alter a constant value. JavaScript `const` declarations can't be re-assigned or redeclared. ## Message TypeError: invalid assignment to const "x" (Firefox) TypeError: Assignment to constant variable. (Chrome) TypeError: Assignment to const (Edge) TypeError: Redeclaration of const 'x' (IE) ## Error type [`TypeError`](../global_objects/typeerror) ## What went wrong? A constant is a value that cannot be altered by the program during normal execution. It cannot change through re-assignment, and it can't be redeclared. In JavaScript, constants are declared using the `const` keyword. ## Examples ### Invalid redeclaration Assigning a value to the same constant name in the same block-scope will throw. const COLUMNS = 80; // ... COLUMNS = 120; // TypeError: invalid assignment to const `COLUMNS' ### Fixing the error There are multiple options to fix this error. Check what was intended to be achieved with the constant in question. #### Rename If you meant to declare another constant, pick another name and re-name. This constant name is already taken in this scope. const COLUMNS = 80; const WIDE_COLUMNS = 120; #### `const`, `let` or `var`? Do not use const if you weren't meaning to declare a constant. Maybe you meant to declare a block-scoped variable with `let` or global variable with `var`. let columns = 80; // ... let columns = 120; #### Scoping Check if you are in the correct scope. Should this constant appear in this scope or was it meant to appear in a function, for example? const COLUMNS = 80; function setupBigScreenEnvironment() { const COLUMNS = 120; } ### `const` and immutability The `const` declaration creates a read-only reference to a value. It does **not** mean the value it holds is immutable, just that the variable identifier cannot be reassigned. For instance, in case the content is an object, this means the object itself can still be altered. This means that you can't mutate the value stored in a variable: const obj = {foo: 'bar'}; obj = {foo: 'baz'}; // TypeError: invalid assignment to const `obj' But you can mutate the properties in a variable: obj.foo = 'baz'; obj; // Object { foo: "baz" } ## See also - `const` - `let` - `var` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_const_assignment # RangeError: invalid date The JavaScript exception "invalid date" occurs when a string leading to an invalid date has been provided to [`Date`](../global_objects/date) or [`Date.parse()`](../global_objects/date/parse). ## Message RangeError: invalid date (Edge) RangeError: invalid date (Firefox) RangeError: invalid time value (Chrome) RangeError: Provided date is not in valid range (Chrome) ## Error type [`RangeError`](../global_objects/rangeerror) ## What went wrong? A string leading to an invalid date has been provided to [`Date`](../global_objects/date) or [`Date.parse()`](../global_objects/date/parse). ## Examples ### Invalid cases Unrecognizable strings or dates containing illegal element values in ISO formatted strings usually return [`NaN`](../global_objects/nan). However, depending on the implementation, non–conforming ISO format strings, may also throw `RangeError: invalid date`, like the following cases in Firefox: new Date('foo-bar 2014'); new Date('2014-25-23').toISOString(); new Date('foo-bar 2014').toString(); This, however, returns [`NaN`](../global_objects/nan) in Firefox: Date.parse('foo-bar 2014'); // NaN For more details, see the [`Date.parse()`](../global_objects/date/parse) documentation. ### Valid cases new Date('05 October 2011 14:48 UTC'); new Date(1317826080); // Unix Time Stamp for 05 October 2011 14:48:00 UTC ## See also - [`Date`](../global_objects/date) - [`Date.prototype.parse()`](../global_objects/date/parse) - [`Date.prototype.toISOString()`](../global_objects/date/toisostring) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_date # SyntaxError: for-in loop head declarations may not have initializers The JavaScript [strict mode](../strict_mode)-only exception "for-in loop head declarations may not have initializers" occurs when the head of a [for...in](../statements/for...in) contains an initializer expression, such as |`for (var i = 0 in obj)`|. This is not allowed in for-of loops in strict mode. ## Message SyntaxError: for-in loop head declarations cannot have an initializer (Edge) SyntaxError: for-in loop head declarations may not have initializers (Firefox) SyntaxError: for-in loop variable declaration may not have an initializer. (Chrome) ## Error type [`SyntaxError`](../global_objects/syntaxerror) in [strict mode](../strict_mode) only. ## What went wrong? The head of a [for...in](../statements/for...in) loop contains an initializer expression. That is, a variable is declared and assigned a value |`for (var i = 0 in obj)`|. In non-strict mode, this head declaration is silently ignored and behaves like `|for (var i in obj)|`. In [strict mode](../strict_mode), however, a `SyntaxError` is thrown. ## Examples This example throws a `SyntaxError`: "use strict"; var obj = {a: 1, b: 2, c: 3 }; for (var i = 0 in obj) { console.log(obj[i]); } // SyntaxError: for-in loop head declarations may not have initializers ### Valid for-in loop You can remove the initializer (`i = 0`) in the head of the for-in loop. "use strict"; var obj = {a: 1, b: 2, c: 3 }; for (var i in obj) { console.log(obj[i]); } ### Array iteration The for...in loop [shouldn't be used for Array iteration](../statements/for...in#array_iteration_and_for...in). Did you intend to use a `for` loop instead of a `for-in` loop to iterate an [`Array`](../global_objects/array)? The `for` loop allows you to set an initializer then as well: var arr = [ "a", "b", "c" ] for (var i = 2; i < arr.length; i++) { console.log(arr[i]); } // "c" ## See also - `for...in` - `for...of` – also disallows an initializer in both strict and non-strict mode. - `for` – preferred for array iteration, allows to define an initializer. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_for-in_initializer # SyntaxError: a declaration in the head of a for-of loop can't have an initializer The JavaScript exception "a declaration in the head of a for-of loop can't have an initializer" occurs when the head of a [for...of](../statements/for...of) loop contains an initializer expression such as |`for (var i = 0 of iterable)`|. This is not allowed in for-of loops. ## Message SyntaxError: for-of loop head declarations cannot have an initializer (Edge) SyntaxError: a declaration in the head of a for-of loop can't have an initializer (Firefox) SyntaxError: for-of loop variable declaration may not have an initializer. (Chrome) ## Error type [`SyntaxError`](../global_objects/syntaxerror) ## What went wrong? The head of a [for...of](../statements/for...of) loop contains an initializer expression. That is, a variable is declared and assigned a value |`for (var i = 0 of iterable)`|. This is not allowed in for-of loops. You might want a `for` loop that does allow an initializer. ## Examples ### Invalid `for-of` loop let iterable = [10, 20, 30]; for (let value = 50 of iterable) { console.log(value); } // SyntaxError: a declaration in the head of a for-of loop can't // have an initializer ### Valid `for-of` loop You need to remove the initializer (`value = 50`) in the head of the `for-of` loop. Maybe you intended to make 50 an offset value, in that case you could add it to the loop body, for example. let iterable = [10, 20, 30]; for (let value of iterable) { value += 50; console.log(value); } // 60 // 70 // 80 ## See also - `for...of` - `for...in` – disallows an initializer in strict mode as well ([SyntaxError: for-in loop head declarations may not have initializers](invalid_for-in_initializer)) - `for` – allows to define an initializer when iterating. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_for-of_initializer # TypeError: invalid 'instanceof' operand 'x' The JavaScript exception "invalid 'instanceof' operand" occurs when the right hand side operands of the [`instanceof` operator](../operators/instanceof) isn't used with a constructor object, i.e. an object which has a `prototype` property and is callable. ## Message TypeError: invalid 'instanceof' operand "x" (Firefox) TypeError: "x" is not a function (Firefox) TypeError: Right-hand side of 'instanceof' is not an object (Chrome) TypeError: Right-hand side of 'instanceof' is not callable (Chrome) ## Error type [`TypeError`](../global_objects/typeerror) ## What went wrong? The [`instanceof` operator](../operators/instanceof) expects the right hand side operands to be a constructor object, i.e. an object which has a `prototype` property and is callable. ## Examples ### instanceof vs typeof "test" instanceof ""; // TypeError: invalid 'instanceof' operand "" 42 instanceof 0; // TypeError: invalid 'instanceof' operand 0 function Foo() {} var f = Foo(); // Foo() is called and returns undefined var x = new Foo(); x instanceof f; // TypeError: invalid 'instanceof' operand f x instanceof x; // TypeError: x is not a function To fix these errors, you will either need to replace the [`instanceof` operator](../operators/instanceof) with the [`typeof` operator](../operators/typeof), or to make sure you use the function name, instead of the result of its evaluation. typeof "test" == "string"; // true typeof 42 == "number" // true function Foo() {} var f = Foo; // Do not call Foo. var x = new Foo(); x instanceof f; // true x instanceof Foo; // true ## See also - [`instanceof` operator](../operators/instanceof) - [`typeof` operator](../operators/typeof) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/invalid_right_hand_side_instanceof_operand # Object.is() The `Object.is()` method determines whether two values are [the same value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness). ## Syntax Object.is(value1, value2); ### Parameters `value1` The first value to compare. `value2` The second value to compare. ### Return value A [`Boolean`](../boolean) indicating whether or not the two arguments are the same value. ## Description `Object.is()` determines whether two values are [the same value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness). Two values are the same if one of the following holds: - both [`undefined`](../undefined) - both [`null`](../null) - both `true` or both `false` - both strings of the same length with the same characters in the same order - both the same object (meaning both values reference the same object in memory) - both numbers and - both `+0` - both `-0` - both [`NaN`](../nan) - or both non-zero and both not [`NaN`](../nan) and both have the same value This is _not_ the same as being equal according to the [`==`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#equality) operator. The `==` operator applies various coercions to both sides (if they are not the same Type) before testing for equality (resulting in such behavior as `"" == false` being `true`), but `Object.is` doesn't coerce either value. This is also _not_ the same as being equal according to the [`===`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#identity) operator. The only difference between `Object.is()` and `===` is in their treatment of signed zeroes and NaNs. For example, the `===` operator (and the `==` operator) treats the number values `-0` and `+0` as equal. Also, the `===` operator treats [`Number.NaN`](../number/nan) and [`NaN`](../nan) as not equal. ## Examples ### Using Object.is // Case 1: Evaluation result is the same as using === Object.is(25, 25); // true Object.is('foo', 'foo'); // true Object.is('foo', 'bar'); // false Object.is(null, null); // true Object.is(undefined, undefined); // true Object.is(window, window); // true Object.is([], []); // false var foo = { a: 1 }; var bar = { a: 1 }; Object.is(foo, foo); // true Object.is(foo, bar); // false // Case 2: Signed zero Object.is(0, -0); // false Object.is(+0, -0); // false Object.is(-0, -0); // true Object.is(0n, -0n); // true // Case 3: NaN Object.is(NaN, 0/0); // true Object.is(NaN, Number.NaN) // true ## Polyfill if (!Object.is) { Object.defineProperty(Object, "is", { value: function (x, y) { // SameValue algorithm if (x === y) { // return true if x and y are not 0, OR // if x and y are both 0 of the same sign. // This checks for cases 1 and 2 above. return x !== 0 || 1 / x === 1 / y; } else { // return true if both x AND y evaluate to NaN. // The only possibility for a variable to not be strictly equal to itself // is when that variable evaluates to NaN (example: Number.NaN, 0/0, NaN). // This checks for case 3. return x !== x && y !== y; } } }); } ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Object.is' in that specification.
      `is` 30 12 22 No 17 9 ≤37 30 22 18 9 2.0 ## See also - [Equality comparisons and sameness](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness) — a comparison of all three built-in sameness facilities © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is # TypeError: 'x' is not iterable The JavaScript exception "is not iterable" occurs when the value which is given as the right hand-side of [for…of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#for...of_statement) or as argument of a function such as [`Promise.all`](../global_objects/promise/all) or [`TypedArray.from`](../global_objects/typedarray/from), is not an [iterable object](../iteration_protocols). ## Message TypeError: 'x' is not iterable (Firefox, Chrome) TypeError: 'x' is not a function or its return value is not iterable (Chrome) ## Error type [`TypeError`](../global_objects/typeerror) ## What went wrong? The value which is given as the right hand-side of [for…of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#for...of_statement) or as argument of a function such as [`Promise.all`](../global_objects/promise/all) or [`TypedArray.from`](../global_objects/typedarray/from), is not an [iterable object](../iteration_protocols). An iterable can be a built-in iterable type such as [`Array`](../global_objects/array), [`String`](../global_objects/string) or [`Map`](../global_objects/map), a generator result, or an object implementing the [iterable protocol](../iteration_protocols#the_iterable_protocol). ## Examples ### Iterating over Object properties In JavaScript, [`Object`](../global_objects/object)s are not iterable unless they implement the [iterable protocol](../iteration_protocols#the_iterable_protocol). Therefore, you cannot use [for…of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#for...of_statement) to iterate over the properties of an object. var obj = { 'France': 'Paris', 'England': 'London' }; for (let p of obj) { // TypeError: obj is not iterable // … } Instead you have to use [`Object.keys`](../global_objects/object/keys) or [`Object.entries`](../global_objects/object/entries), to iterate over the properties or entries of an object. var obj = { 'France': 'Paris', 'England': 'London' }; // Iterate over the property names: for (let country of Object.keys(obj)) { var capital = obj[country]; console.log(country, capital); } for (const [country, capital] of Object.entries(obj)) console.log(country, capital); Another option for this use case might be to use a [`Map`](../global_objects/map): var map = new Map; map.set('France', 'Paris'); map.set('England', 'London'); // Iterate over the property names: for (let country of map.keys()) { let capital = map[country]; console.log(country, capital); } for (let capital of map.values()) console.log(capital); for (const [country, capital] of map.entries()) console.log(country, capital); ### Iterating over a generator [Generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#generators) are functions you call to produce an iterable object. function* generate(a, b) { yield a; yield b; } for (let x of generate) // TypeError: generate is not iterable console.log(x); When they are not called, the [`Function`](../global_objects/function) object corresponding to the generator is callable, but not iterable. Calling a generator produces an iterable object which will iterate over the values yielded during the execution of the generator. function* generate(a, b) { yield a; yield b; } for (let x of generate(1,2)) console.log(x); ### Iterating over a custom iterable Custom iterables can be created by implementing the [`Symbol.iterator`](../global_objects/symbol/iterator) method. You must be certain that your iterator method returns an object which is an iterator, which is to say it must have a next method. const myEmptyIterable = { [Symbol.iterator]() { return [] // [] is iterable, but it is not an iterator -- it has no next method. } } Array.from(myEmptyIterable); // TypeError: myEmptyIterable is not iterable Here is a correct implementation: const myEmptyIterable = { [Symbol.iterator]() { return [][Symbol.iterator]() } } Array.from(myEmptyIterable); // [] ## See also - [iterable protocol](../iteration_protocols#the_iterable_protocol) - [`Object.keys`](../global_objects/object/keys) - [`Object.entries`](../global_objects/object/entries) - [`Map`](../global_objects/map) - [generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#generators) - [for…of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#for...of_statement) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/is_not_iterable # Array.isArray() The `Array.isArray()` method determines whether the passed value is an [`Array`](../array). Array.isArray([1, 2, 3]); // true Array.isArray({foo: 123}); // false Array.isArray('foobar'); // false Array.isArray(undefined); // false ## Syntax Array.isArray(value) ### Parameters `value` The value to be checked. ### Return value `true` if the value is an [`Array`](../array); otherwise, `false`. ## Description If the value is an [`Array`](../array), `true` is returned; otherwise, `false` is. See the article ["Determining with absolute accuracy whether or not a JavaScript object is an array”](https://web.mit.edu/jwalden/www/isArray.html) for more details. Given a [`TypedArray`](../typedarray) instance, `false` is always returned. ## Examples ### Using Array.isArray // all following calls return true Array.isArray([]); Array.isArray([1]); Array.isArray(new Array()); Array.isArray(new Array('a', 'b', 'c', 'd')); Array.isArray(new Array(3)); // Little known fact: Array.prototype itself is an array: Array.isArray(Array.prototype); // all following calls return false Array.isArray(); Array.isArray({}); Array.isArray(null); Array.isArray(undefined); Array.isArray(17); Array.isArray('Array'); Array.isArray(true); Array.isArray(false); Array.isArray(new Uint8Array(32)); Array.isArray({ __proto__: Array.prototype }); ### `instanceof` vs `isArray` When checking for `Array` instance, `Array.isArray` is preferred over `instanceof` because it works through `iframes`. var iframe = document.createElement('iframe'); document.body.appendChild(iframe); xArray = window.frames[window.frames.length-1].Array; var arr = new xArray(1,2,3); // [1,2,3] // Correctly checking for Array Array.isArray(arr); // true // Considered harmful, because doesn't work through iframes arr instanceof Array; // false ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-array.isarray
      `isArray` 5 12 4 9 10.5 5 1 18 4 14 5 1.0 ## See also - [A polyfill](https://github.com/behnammodi/polyfill/blob/master/array.polyfill.js) - [`Array`](../array) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray # Symbol.isConcatSpreadable The `Symbol.isConcatSpreadable` well-known symbol is used to configure if an object should be flattened to its array elements when using the [`Array.prototype.concat()`](../array/concat) method. ## Description The `@@isConcatSpreadable` symbol (`Symbol.isConcatSpreadable`) can be defined as an own or inherited property and its value is a boolean. It can control behavior for arrays and array-like objects: - For array objects, the default behavior is to spread (flatten) elements. `Symbol.isConcatSpreadable` can avoid flattening in these cases. - For array-like objects, the default behavior is no spreading or flattening. `Symbol.isConcatSpreadable` can force flattening in these cases. Property attributes of `Symbol.isConcatSpreadable` Writable no Enumerable no Configurable no ## Examples ### Arrays By default, [`Array.prototype.concat()`](../array/concat) spreads (flattens) arrays into its result: let alpha = ['a', 'b', 'c'], let numeric = [1, 2, 3] let alphaNumeric = alpha.concat(numeric) console.log(alphaNumeric) // Result: ['a', 'b', 'c', 1, 2, 3] When setting `Symbol.isConcatSpreadable` to `false`, you can disable the default behavior: let alpha = ['a', 'b', 'c'], let numeric = [1, 2, 3] numeric[Symbol.isConcatSpreadable] = false let alphaNumeric = alpha.concat(numeric) console.log(alphaNumeric) // Result: ['a', 'b', 'c', [1, 2, 3] ] ### Array-like objects For array-like objects, the default is to not spread. `Symbol.isConcatSpreadable` needs to be set to `true` in order to get a flattened array: let x = [1, 2, 3] let fakeArray = { [Symbol.isConcatSpreadable]: true, length: 2, 0: 'hello', 1: 'world' } x.concat(fakeArray) // [1, 2, 3, "hello", "world"] **Note:** The `length` property is used to control the number of object properties to be added. In the above example, `length:2` indicates two properties has to be added. ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-symbol.isconcatspreadable
      `isConcatSpreadable` 48 15 48 No 35 10 48 48 48 35 10 5.0 ## See also - [`Array.prototype.concat()`](../array/concat) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable # Reflect.isExtensible() The static `Reflect.isExtensible()` method determines if an object is extensible (whether it can have new properties added to it). It is similar to [`Object.isExtensible()`](../object/isextensible), but with some [differences](#difference_to_object.isextensible). ## Syntax Reflect.isExtensible(target) ### Parameters `target` The target object which to check if it is extensible. ### Return value A [`Boolean`](../boolean) indicating whether or not the target is extensible. ### Exceptions A [`TypeError`](../typeerror), if `target` is not an [`Object`](../object). ## Description The `Reflect.isExtensible` method allows you determine if an object is extensible (whether it can have new properties added to it). It is the same method as [`Object.isExtensible()`](../object/isextensible). ## Examples ### Using Reflect.isExtensible() See also [`Object.isExtensible()`](../object/isextensible). // New objects are extensible. let empty = {} Reflect.isExtensible(empty) // === true // ...but that can be changed. Reflect.preventExtensions(empty) Reflect.isExtensible(empty) // === false // Sealed objects are by definition non-extensible. let sealed = Object.seal({}) Reflect.isExtensible(sealed) // === false // Frozen objects are also by definition non-extensible. let frozen = Object.freeze({}) Reflect.isExtensible(frozen) // === false ### Difference to Object.isExtensible() If the `target` argument to this method is not an object (a primitive), then it will cause a [`TypeError`](../typeerror). With [`Object.isExtensible()`](../object/isextensible), a non-object first argument will be coerced to an object at first. Reflect.isExtensible(1) // TypeError: 1 is not an object Object.isExtensible(1) // false ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-reflect.isextensible
      `isExtensible` 49 12 42 No 36 10 49 49 42 36 10 5.0 ## See also - [`Reflect`](../reflect) - [`Object.isExtensible()`](../object/isextensible) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible # Number.isFinite() The `Number.isFinite()` method determines whether the passed value is a finite number — that is, it checks that the type of a given value is [`Number`](../number), and the number is neither positive [`Infinity`](../infinity), negative `Infinity`, nor [`NaN`](../nan). ## Syntax Number.isFinite(value) ### Parameters `value` The value to be tested for finiteness. ### Return value A [`Boolean`](../boolean) indicating whether or not the given value is a finite number. ## Description In comparison to the global [`isFinite()`](../isfinite) function, this method doesn't first convert the parameter to a number. This means only values of the type number _and_ are finite return `true`. ## Examples ### Using isFinite Number.isFinite(Infinity); // false Number.isFinite(NaN); // false Number.isFinite(-Infinity); // false Number.isFinite(0); // true Number.isFinite(2e64); // true Number.isFinite('0'); // false, would've been true with // global isFinite('0') Number.isFinite(null); // false, would've been true with // global isFinite(null) ## Polyfill if (Number.isFinite === undefined) Number.isFinite = function(value) { return typeof value === 'number' && isFinite(value); } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-number.isfinite
      `isFinite` 19 12 16 No 15 9 ≤37 25 16 14 9 1.5 ## See also - The [`Number`](../number) object it belongs to. - The global function [`isFinite`](../isfinite). © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite # Object.isFrozen() The `Object.isFrozen()` determines if an object is [frozen](freeze). ## Syntax Object.isFrozen(obj) ### Parameters `obj` The object which should be checked. ### Return value A [`Boolean`](../boolean) indicating whether or not the given object is frozen. ## Description An object is frozen if and only if it is not [extensible](isextensible), all its properties are non-configurable, and all its data properties (that is, properties which are not accessor properties with getter or setter components) are non-writable. ## Examples ### Using Object.isFrozen // A new object is extensible, so it is not frozen. Object.isFrozen({}); // === false // An empty object which is not extensible // is vacuously frozen. var vacuouslyFrozen = Object.preventExtensions({}); Object.isFrozen(vacuouslyFrozen); // === true // A new object with one property is also extensible, // ergo not frozen. var oneProp = { p: 42 }; Object.isFrozen(oneProp); // === false // Preventing extensions to the object still doesn't // make it frozen, because the property is still // configurable (and writable). Object.preventExtensions(oneProp); Object.isFrozen(oneProp); // === false // ...but then deleting that property makes the object // vacuously frozen. delete oneProp.p; Object.isFrozen(oneProp); // === true // A non-extensible object with a non-writable // but still configurable property is not frozen. var nonWritable = { e: 'plep' }; Object.preventExtensions(nonWritable); Object.defineProperty(nonWritable, 'e', { writable: false }); // make non-writable Object.isFrozen(nonWritable); // === false // Changing that property to non-configurable // then makes the object frozen. Object.defineProperty(nonWritable, 'e', { configurable: false }); // make non-configurable Object.isFrozen(nonWritable); // === true // A non-extensible object with a non-configurable // but still writable property also isn't frozen. var nonConfigurable = { release: 'the kraken!' }; Object.preventExtensions(nonConfigurable); Object.defineProperty(nonConfigurable, 'release', { configurable: false }); Object.isFrozen(nonConfigurable); // === false // Changing that property to non-writable // then makes the object frozen. Object.defineProperty(nonConfigurable, 'release', { writable: false }); Object.isFrozen(nonConfigurable); // === true // A non-extensible object with a configurable // accessor property isn't frozen. var accessor = { get food() { return 'yum'; } }; Object.preventExtensions(accessor); Object.isFrozen(accessor); // === false // ...but make that property non-configurable // and it becomes frozen. Object.defineProperty(accessor, 'food', { configurable: false }); Object.isFrozen(accessor); // === true // But the easiest way for an object to be frozen // is if Object.freeze has been called on it. var frozen = { 1: 81 }; Object.isFrozen(frozen); // === false Object.freeze(frozen); Object.isFrozen(frozen); // === true // By definition, a frozen object is non-extensible. Object.isExtensible(frozen); // === false // Also by definition, a frozen object is sealed. Object.isSealed(frozen); // === true ### Non-object coercion In ES5, if the argument to this method is not an object (a primitive), then it will cause a [`TypeError`](../typeerror). In ES2015, a non-object argument will be treated as if it was a frozen ordinary object, return `true`. Object.isFrozen(1); // TypeError: 1 is not an object (ES5 code) Object.isFrozen(1); // true (ES2015 code) ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Object.isFrozen' in that specification.
      `isFrozen` 6 12 4 9 12 5.1 1 18 4 12 6 1.0 ## See also - [`Object.freeze()`](freeze) - [`Object.preventExtensions()`](preventextensions) - [`Object.isExtensible()`](isextensible) - [`Object.seal()`](seal) - [`Object.isSealed()`](issealed) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen # Number.isInteger() The `Number.isInteger()` method determines whether the passed value is an integer. ## Syntax Number.isInteger(value) ### Parameters `value` The value to be tested for being an integer. ### Return value A [`Boolean`](../boolean) indicating whether or not the given value is an integer. ## Description If the target value is an integer, return `true`, otherwise return `false`. If the value is [`NaN`](../nan) or [`Infinity`](../infinity), return `false`. The method will also return `true` for floating point numbers that can be represented as integer. ## Examples ### Using isInteger Number.isInteger(0); // true Number.isInteger(1); // true Number.isInteger(-100000); // true Number.isInteger(99999999999999999999999); // true Number.isInteger(0.1); // false Number.isInteger(Math.PI); // false Number.isInteger(NaN); // false Number.isInteger(Infinity); // false Number.isInteger(-Infinity); // false Number.isInteger('10'); // false Number.isInteger(true); // false Number.isInteger(false); // false Number.isInteger([1]); // false Number.isInteger(5.0); // true Number.isInteger(5.000000000000001); // false Number.isInteger(5.0000000000000001); // true ## Polyfill Number.isInteger = Number.isInteger || function(value) { return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; }; ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-number.isinteger
      `isInteger` 34 12 16 No 21 9 ≤37 34 16 21 9 2.0 ## See also - The [`Number`](../number) object it belongs to. © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger # Atomics.isLockFree() The static ` Atomics``.isLockFree() ` method is used to determine whether to use locks or atomic operations. It returns `true`, if the given size is one of the [BYTES_PER_ELEMENT](../typedarray/bytes_per_element) property of integer TypedArray types. ## Syntax Atomics.isLockFree(size) ### Parameters `size` The size in bytes to check. ### Return value A [`Boolean`](../boolean) indicating whether the operation is lock free. ## Examples ### Using isLockFree Atomics.isLockFree(1); // true Atomics.isLockFree(2); // true Atomics.isLockFree(3); // false Atomics.isLockFree(4); // true Atomics.isLockFree(5); // false Atomics.isLockFree(6); // false Atomics.isLockFree(7); // false Atomics.isLockFree(8); // true ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-atomics.islockfree
      `isLockFree` 68 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This was a temporary removal while mitigations were put in place. 79 16-17 Support was removed to mitigate [speculative execution side-channel attacks (Windows blog)](https://blogs.windows.com/msedgedev/2018/01/03/speculative-execution-mitigations-microsoft-edge-internet-explorer). 78 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No No 10.1-11.1 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 60-63 Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. 57 Support was disabled by default to mitigate [speculative execution side-channel attacks (Mozilla Security Blog)](https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/). 55-57 46-55 No 10.3-11.3 No Chrome disabled `SharedArrayBuffer` on January 5, 2018 to help reduce the efficacy of [speculative side-channel attacks](https://www.chromium.org/Home/chromium-security/ssca). This is intended as a temporary measure until other mitigations are in place. ## See also - [`Atomics`](../atomics) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/isLockFree # isNaN() The `isNaN()` function determines whether a value is [`NaN`](nan) or not. Because coercion inside the `isNaN` function can be [surprising](#confusing_special-case_behavior), you may alternatively want to use [`Number.isNaN()`](number/isnan). ## Syntax isNaN(value) ### Parameters `value` The value to be tested. ### Return value `true` if the given value is [`NaN`](nan); otherwise, `false`. ## Description ### The necessity of an isNaN function Unlike all other possible values in JavaScript, it is not possible to use the equality operators (== and ===) to compare a value against [`NaN`](nan) to determine whether the value _is_ `NaN` or not, because both `NaN == NaN` and `NaN === NaN` evaluate to `false`. Hence, the necessity of an `isNaN` function. ### Origin of NaN values `NaN` values are generated when arithmetic operations result in _undefined_ or _unrepresentable_ values. Such values do not necessarily represent overflow conditions. A `NaN` also results from attempted coercion to numeric values of non-numeric values for which no primitive numeric value is available. For example, dividing zero by zero results in a `NaN` — but dividing other numbers by zero does not. ### Confusing special-case behavior Since the very earliest versions of the `isNaN` function specification, its behavior for non-numeric arguments has been confusing. When the argument to the `isNaN` function is not of type [Number](https://es5.github.com/#x8.5), the value is first coerced to a Number. The resulting value is then tested to determine whether it is [`NaN`](nan). Thus for non-numbers that when coerced to numeric type result in a valid non-NaN numeric value (notably the empty string and boolean primitives, which when coerced give numeric values zero or one), the "false" returned value may be unexpected; the empty string, for example, is surely "not a number." The confusion stems from the fact that the term, "not a number", has a specific meaning for numbers represented as IEEE-754 floating-point values. The function should be interpreted as answering the question, "is this value, when coerced to a numeric value, an IEEE-754 'Not A Number' value?" ECMAScript 2015 contains the [`Number.isNaN()`](number/isnan) function. `Number.isNaN(x)` is a reliable way to test whether `x` is `NaN` or not. Even with `Number.isNaN`, however, the meaning of `NaN` remains the precise numeric meaning and not, "not a number". Alternatively, in the absence of `Number.isNaN`, the expression `(x != x)` is a more reliable way to test whether variable `x` is `NaN` or not, as the result is not subject to the false positives that make `isNaN` unreliable. A polyfill for `isNaN` would be (the polyfill leverages the unique never-equal-to-itself characteristic of `NaN`): const isNaN = function(value) { const n = Number(value); return n !== n; }; ## Examples isNaN(NaN); // true isNaN(undefined); // true isNaN({}); // true isNaN(true); // false isNaN(null); // false isNaN(37); // false // strings isNaN('37'); // false: "37" is converted to the number 37 which is not NaN isNaN('37.37'); // false: "37.37" is converted to the number 37.37 which is not NaN isNaN("37,5"); // true isNaN('123ABC'); // true: parseInt("123ABC") is 123 but Number("123ABC") is NaN isNaN(''); // false: the empty string is converted to 0 which is not NaN isNaN(' '); // false: a string with spaces is converted to 0 which is not NaN // dates isNaN(new Date()); // false isNaN(new Date().toString()); // true // This is a false positive and the reason why isNaN is not entirely reliable isNaN('blabla'); // true: "blabla" is converted to a number. // Parsing this as a number fails and returns NaN ### Useful special-case behavior There is a more usage oriented way to think of `isNaN()`: If `isNaN(x)` returns `false`, you can use `x` in an arithmetic expression not making the expression return `NaN`. If it returns `true`, `x` will make every arithmetic expression return `NaN`. This means that in JavaScript, `isNaN(x) == true` is equivalent to `x - 0` returning `NaN` (though in JavaScript `x - 0 == NaN` always returns false, so you can't test for it). Actually, `isNaN(x)`, `isNaN(x - 0)`, `isNaN(Number(x))`, `Number.isNaN(x - 0)`, and `Number.isNaN(Number(x))` always return the same and in JavaScript `isNaN(x)` is just the shortest possible form to express each of these terms. You can use this, for example, to test whether an argument to a function is arithmetically processable (usable "like" a number), or if it's not and you have to provide a default value or something else. This way you can have a function that makes use of the full versatility JavaScript provides by implicitly converting values depending on context. ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'isNaN' in that specification.
      `isNaN` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`NaN`](nan) - [`Number.isNaN()`](number/isnan) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN # Object.prototype.isPrototypeOf() The `isPrototypeOf()` method checks if an object exists in another object's prototype chain. **Note:** `isPrototypeOf()` differs from the [`instanceof`](../../operators/instanceof) operator. In the expression "`object instanceof AFunction`", the `object` prototype chain is checked against `AFunction.prototype`, not against `AFunction` itself. ## Syntax isPrototypeOf(object) ### Parameters `object` The object whose prototype chain will be searched. ### Return value A [`Boolean`](../boolean) indicating whether the calling object lies in the prototype chain of the specified object. ### Errors thrown [`TypeError`](../typeerror) A [`TypeError`](../typeerror) is thrown if `prototypeObj` is undefined or null. ## Description The `isPrototypeOf()` method allows you to check whether or not an object exists within another object's prototype chain. ## Examples ### Using isPrototypeOf This example demonstrates that `Baz.prototype`, `Bar.prototype`, `Foo.prototype` and `Object.prototype` exist in the prototype chain for object `baz`: function Foo() {} function Bar() {} function Baz() {} Bar.prototype = Object.create(Foo.prototype); Baz.prototype = Object.create(Bar.prototype); const foo = new Foo(); const bar = new Bar(); const baz = new Baz(); // prototype chains: // foo: Foo <- Object // bar: Bar <- Foo <- Object // baz: Baz <- Bar <- Foo <- Object console.log(Baz.prototype.isPrototypeOf(baz)); // true console.log(Baz.prototype.isPrototypeOf(bar)); // false console.log(Baz.prototype.isPrototypeOf(foo)); // false console.log(Bar.prototype.isPrototypeOf(baz)); // true console.log(Bar.prototype.isPrototypeOf(foo)); // false console.log(Foo.prototype.isPrototypeOf(baz)); // true console.log(Foo.prototype.isPrototypeOf(bar)); // true console.log(Object.prototype.isPrototypeOf(baz)); // true The `isPrototypeOf()` method — along with the [`instanceof`](../../operators/instanceof) operator — comes in particularly handy if you have code that can only function when dealing with objects descended from a specific prototype chain; e.g., to guarantee that certain methods or properties will be present on that object. For example, to execute some code that's only safe to run if a `baz` object has `Foo.prototype` in its prototype chain, you can do this: if (Foo.prototype.isPrototypeOf(baz)) { // do something safe } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-object.prototype.isprototypeof
      `isPrototypeOf` 1 12 1 9 4 3 1 18 4 10.1 1 1.0 ## See also - [`instanceof`](../../operators/instanceof) - [`Object.getPrototypeOf()`](getprototypeof) - [`Object.setPrototypeOf()`](setprototypeof) - [`Object/proto`](proto) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf # Number.isSafeInteger() The `Number.isSafeInteger()` method determines whether the provided value is a number that is a safe integer. A safe integer is an integer that - can be exactly represented as an IEEE-754 double precision number, and - whose IEEE-754 representation cannot be the result of rounding any other integer to fit the IEEE-754 representation. For example, `253 - 1` is a safe integer: it can be exactly represented, and no other integer rounds to it under any IEEE-754 rounding mode. In contrast, `253` is _not_ a safe integer: it can be exactly represented in IEEE-754, but the integer `253 + 1` can't be directly represented in IEEE-754 but instead rounds to `253` under round-to-nearest and round-to-zero rounding. The safe integers consist of all integers from `-(253 - 1)` inclusive to `253 - 1` inclusive (± `9007199254740991` or ± 9,007,199,254,740,991). Handling values larger or smaller than ~9 quadrillion with full precision requires using an [arbitrary precision arithmetic library](https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic). See [What Every Programmer Needs to Know about Floating Point Arithmetic](https://floating-point-gui.de/) for more information on floating point representations of numbers. For larger integers, consider using the [`BigInt`](../bigint) type. ## Syntax Number.isSafeInteger(testValue) ### Parameters `testValue` The value to be tested for being a safe integer. ### Return value A [`Boolean`](../boolean) indicating whether or not the given value is a number that is a safe integer. ## Polyfill Number.isSafeInteger = Number.isSafeInteger || function (value) { return Number.isInteger(value) && Math.abs(value) <= Number.MAX_SAFE_INTEGER; }; ## Examples ### Using isSafeInteger Number.isSafeInteger(3); // true Number.isSafeInteger(Math.pow(2, 53)); // false Number.isSafeInteger(Math.pow(2, 53) - 1); // true Number.isSafeInteger(NaN); // false Number.isSafeInteger(Infinity); // false Number.isSafeInteger('3'); // false Number.isSafeInteger(3.1); // false Number.isSafeInteger(3.0); // true ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-number.issafeinteger
      `isSafeInteger` 34 12 32 No 21 10 ≤37 34 32 21 10 2.0 ## See also - The [`Number`](../number) object it belongs to. - [`Number.MIN_SAFE_INTEGER`](min_safe_integer) - [`Number.MAX_SAFE_INTEGER`](max_safe_integer) - [`BigInt`](../bigint) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger # Object.isSealed() The `Object.isSealed()` method determines if an object is sealed. ## Syntax Object.isSealed(obj) ### Parameters `obj` The object which should be checked. ### Return value A [`Boolean`](../boolean) indicating whether or not the given object is sealed. ## Description Returns `true` if the object is sealed, otherwise `false`. An object is sealed if it is not [extensible](isextensible) and if all its properties are non-configurable and therefore not removable (but not necessarily non-writable). ## Examples ### Using Object.isSealed // Objects aren't sealed by default. var empty = {}; Object.isSealed(empty); // === false // If you make an empty object non-extensible, // it is vacuously sealed. Object.preventExtensions(empty); Object.isSealed(empty); // === true // The same is not true of a non-empty object, // unless its properties are all non-configurable. var hasProp = { fee: 'fie foe fum' }; Object.preventExtensions(hasProp); Object.isSealed(hasProp); // === false // But make them all non-configurable // and the object becomes sealed. Object.defineProperty(hasProp, 'fee', { configurable: false }); Object.isSealed(hasProp); // === true // The easiest way to seal an object, of course, // is Object.seal. var sealed = {}; Object.seal(sealed); Object.isSealed(sealed); // === true // A sealed object is, by definition, non-extensible. Object.isExtensible(sealed); // === false // A sealed object might be frozen, // but it doesn't have to be. Object.isFrozen(sealed); // === true // (all properties also non-writable) var s2 = Object.seal({ p: 3 }); Object.isFrozen(s2); // === false // ('p' is still writable) var s3 = Object.seal({ get p() { return 0; } }); Object.isFrozen(s3); // === true // (only configurability matters for accessor properties) ### Non-object coercion In ES5, if the argument to this method is not an object (a primitive), then it will cause a [`TypeError`](../typeerror). In ES2015, a non-object argument will be treated as if it was a sealed ordinary object, return `true`. Object.isSealed(1); // TypeError: 1 is not an object (ES5 code) Object.isSealed(1); // true (ES2015 code) ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Object.isSealed' in that specification.
      `isSealed` 6 12 4 9 12 5.1 1 18 4 12 6 1.0 ## See also - [`Object.seal()`](seal) - [`Object.preventExtensions()`](preventextensions) - [`Object.isExtensible()`](isextensible) - [`Object.freeze()`](freeze) - [`Object.isFrozen()`](isfrozen) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed # ArrayBuffer.isView() The `ArrayBuffer.isView()` method determines whether the passed value is one of the `ArrayBuffer` views, such as [typed array objects](../typedarray) or a [`DataView`](../dataview). ## Syntax ArrayBuffer.isView(value) ### Parameters `value` The value to be checked. ### Return value `true` if the given argument is one of the [`ArrayBuffer`](../arraybuffer) views; otherwise, `false`. ## Examples ### Using isView ArrayBuffer.isView(); // false ArrayBuffer.isView([]); // false ArrayBuffer.isView({}); // false ArrayBuffer.isView(null); // false ArrayBuffer.isView(undefined); // false ArrayBuffer.isView(new ArrayBuffer(10)); // false ArrayBuffer.isView(new Uint8Array()); // true ArrayBuffer.isView(new Float32Array()); // true ArrayBuffer.isView(new Int8Array(10).subarray(0, 3)); // true const buffer = new ArrayBuffer(2); const dv = new DataView(buffer); ArrayBuffer.isView(dv); // true ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-arraybuffer.isview
      `isView` 32 12 29 11 19 7 ≤37 32 29 19 7 2.0 ## See also - [JavaScript typed arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView # String.prototype.italics() **Deprecated** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the [compatibility table](#browser_compatibility) at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time. The `italics()` method creates an [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i) HTML element that causes a string to be italic. ## Syntax italics() ### Return value A string containing a [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i) HTML element. ## Description The `italics()` method embeds a string in an `` element: "`str`". ## Examples ### Using italics() The following example uses string methods to change the formatting of a string: var worldString = 'Hello, world'; console.log(worldString.blink()); // Hello, world console.log(worldString.bold()); // Hello, world console.log(worldString.italics()); // Hello, world console.log(worldString.strike()); // Hello, world ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-string.prototype.italics
      `italics` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [`String.prototype.blink()`](blink) - [`String.prototype.bold()`](bold) - [`String.prototype.strike()`](strike) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/italics # Iteration protocols As a couple of additions to ECMAScript 2015, **Iteration protocols** aren't new built-ins or syntax, but _protocols_. These protocols can be implemented by any object by following some conventions. There are two protocols: The [iterable protocol](#the_iterable_protocol) and the [iterator protocol](#the_iterator_protocol). ## The iterable protocol **The iterable protocol** allows JavaScript objects to define or customize their iteration behavior, such as what values are looped over in a [`for...of`](statements/for...of) construct. Some built-in types are [built-in iterables](#built-in_iterables) with a default iteration behavior, such as [`Array`](global_objects/array) or [`Map`](global_objects/map), while other types (such as [`Object`](global_objects/object)) are not. In order to be **iterable**, an object must implement the `@@iterator` method, meaning that the object (or one of the objects up its [prototype chain](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)) must have a property with a `@@iterator` key which is available via constant [`Symbol.iterator`](global_objects/symbol/iterator):
      PropertyValue
      [Symbol.iterator]A zero-argument function that returns an object, conforming to the iterator protocol.
      Whenever an object needs to be iterated (such as at the beginning of a [`for...of`](statements/for...of) loop), its `@@iterator` method is called with no arguments, and the returned **iterator** is used to obtain the values to be iterated. Note that when this zero-argument function is called, it is invoked as a method on the iterable object. Therefore inside of the function, the `this` keyword can be used to access the properties of the iterable object, to decide what to provide during the iteration. This function can be an ordinary function, or it can be a generator function, so that when invoked, an iterator object is returned. Inside of this generator function, each entry can be provided by using `yield`. ## The iterator protocol **The iterator protocol** defines a standard way to produce a sequence of values (either finite or infinite), and potentially a return value when all values have been generated. An object is an iterator when it implements a `next()` method with the following semantics:
      PropertyValue
      next()

      A zero-argument function that returns an object with at least the following two properties:

      done (boolean)

      Has the value false if the iterator was able to produce the next value in the sequence. (This is equivalent to not specifying the done property altogether.)

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

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

      The next() method must always return an object with appropriate properties including done and value. If a non-object value gets returned (such as false or undefined), a TypeError ("iterator.next() returned a non-object value") will be thrown.

      **Note:** It is not possible to know reflectively whether a particular object implements the iterator protocol. However, it is easy to create an object that satisfies _both_ the iterator and iterable protocols (as shown in the example below). Doing so allows an iterator to be consumed by the various syntaxes expecting iterables. Thus, it is seldom useful to implement the Iterator Protocol without also implementing Iterable. // Satisfies both the Iterator Protocol and Iterable const myIterator = { next: function() { // ... }, [Symbol.iterator]: function() { return this; } }; However, when possible, it's better for `iterable[Symbol.iterator]` to return different iterators that always start from the beginning, like `Set.prototype[@@iterator]()` does. ## Examples using the iteration protocols A [`String`](global_objects/string) is an example of a built-in iterable object: const someString = 'hi'; console.log(typeof someString[Symbol.iterator]); // "function" `String`'s [default iterator](global_objects/string/@@iterator) returns the string's code points one by one: const iterator = someString[Symbol.iterator](); console.log(iterator + ''); // "[object String Iterator]" console.log(iterator.next()); // { value: "h", done: false } console.log(iterator.next()); // { value: "i", done: false } console.log(iterator.next()); // { value: undefined, done: true } Some built-in constructs—such as the [spread syntax](operators/spread_syntax)—use the same iteration protocol under the hood: console.log([...someString]); // ["h", "i"] You can redefine the iteration behavior by supplying our own `@@iterator`: // need to construct a String object explicitly to avoid auto-boxing const someString = new String('hi'); someString[Symbol.iterator] = function () { return { // this is the iterator object, returning a single element (the string "bye") next: function () { return this._first ? { value: 'bye', done: (this._first = false) } : { done: true } }, _first: true }; }; Notice how redefining `@@iterator` affects the behavior of built-in constructs that use the iteration protocol: console.log([...someString]); // ["bye"] console.log(someString + ''); // "hi" ## Iterable examples ### Built-in iterables [`String`](global_objects/string), [`Array`](global_objects/array), [`TypedArray`](global_objects/typedarray), [`Map`](global_objects/map), and [`Set`](global_objects/set) are all built-in iterables, because each of their prototype objects implements an `@@iterator` method. ### User-defined iterables You can make your own iterables like this: const myIterable = {}; myIterable[Symbol.iterator] = function* () { yield 1; yield 2; yield 3; }; console.log([...myIterable]); // [1, 2, 3] ### Built-in APIs accepting iterables There are many APIs that accept iterables. Some examples include: - [`new Map([iterable])`](global_objects/map) - [`new WeakMap([iterable])`](global_objects/weakmap) - [`new Set([iterable])`](global_objects/set) - [`new WeakSet([iterable])`](global_objects/weakset) new Map([[1, 'a'], [2, 'b'], [3, 'c']]).get(2); // "b" const myObj = {}; new WeakMap([ [{}, 'a'], [myObj, 'b'], [{}, 'c'] ]).get(myObj); // "b" new Set([1, 2, 3]).has(3); // true new Set('123').has('2'); // true new WeakSet(function* () { yield {} yield myObj yield {} }()).has(myObj); // true #### See also - [`Promise.all(iterable)`](global_objects/promise/all) - [`Promise.race(iterable)`](global_objects/promise/race) - [`Array.from(iterable)`](global_objects/array/from) ### Syntaxes expecting iterables Some statements and expressions expect iterables, for example the [`for...of`](statements/for...of) loops, the [spread operator](operators/spread_syntax)), [`yield*`](operators/yield*), and [`destructuring assignment`](operators/destructuring_assignment): for (const value of ['a', 'b', 'c']) { console.log(value); } // "a" // "b" // "c" console.log([...'abc']); // ["a", "b", "c"] function* gen() { yield* ['a', 'b', 'c']; } console.log(gen().next()); // { value: "a", done: false } [a, b, c] = new Set(['a', 'b', 'c']); console.log(a); // "a" ### Non-well-formed iterables If an iterable's `@@iterator` method doesn't return an iterator object, then it's considered a _non-well-formed_ iterable. Using one is likely to result in runtime errors or buggy behavior: const nonWellFormedIterable = {}; nonWellFormedIterable[Symbol.iterator] = () => 1; [...nonWellFormedIterable]; // TypeError: [] is not a function ## Iterator examples ### Simple iterator function makeIterator(array) { let nextIndex = 0 return { next: function() { return nextIndex < array.length ? { value: array[nextIndex++], done: false } : { done: true }; } }; } const it = makeIterator(['yo', 'ya']); console.log(it.next().value); // 'yo' console.log(it.next().value); // 'ya' console.log(it.next().done); // true ### Infinite iterator function idMaker() { let index = 0; return { next: function() { return { value: index++, done: false }; } }; } const it = idMaker(); console.log(it.next().value); // '0' console.log(it.next().value); // '1' console.log(it.next().value); // '2' // ... ### With a generator function* makeSimpleGenerator(array) { let nextIndex = 0; while (nextIndex < array.length) { yield array[nextIndex++]; } } const gen = makeSimpleGenerator(['yo', 'ya']); console.log(gen.next().value); // 'yo' console.log(gen.next().value); // 'ya' console.log(gen.next().done); // true function* idMaker() { let index = 0; while (true) { yield index++; } } const it = idMaker() console.log(it.next().value); // '0' console.log(it.next().value); // '1' console.log(it.next().value); // '2' // ... ### With ES2015 class class SimpleClass { constructor(data) { this.data = data; } [Symbol.iterator]() { // Use a new index for each iterator. This makes multiple // iterations over the iterable safe for non-trivial cases, // such as use of break or nested looping over the same iterable. let index = 0; return { next: () => { if (index < this.data.length) { return {value: this.data[index++], done: false} } else { return {done: true} } } } } } const simple = new SimpleClass([1,2,3,4,5]); for (const val of simple) { console.log(val); // '1' '2' '3' '4' '5' } ## Is a generator object an iterator or an iterable? A [generator object](global_objects/generator) is _both_ iterator and iterable: const aGeneratorObject = function* () { yield 1; yield 2; yield 3; }(); console.log(typeof aGeneratorObject.next); // "function", because it has a next method, so it's an iterator console.log(typeof aGeneratorObject[Symbol.iterator]); // "function", because it has an @@iterator method, so it's an iterable console.log(aGeneratorObject[Symbol.iterator]() === aGeneratorObject); // true, because its @@iterator method returns itself (an iterator), so it's an well-formed iterable console.log([...aGeneratorObject]); // [1, 2, 3] console.log(Symbol.iterator in aGeneratorObject) // true, because @@iterator method is a property of aGeneratorObject ## See also - [the `function*` documentation](statements/function*) - [Iteration in the ECMAScript specification](https://tc39.es/ecma262/#sec-iteration) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols # Symbol.iterator The well-known `Symbol.iterator` symbol specifies the default iterator for an object. Used by [`for...of`](../../statements/for...of). ## Description Whenever an object needs to be iterated (such as at the beginning of a `for..of` loop), its `@@iterator` method is called with no arguments, and the returned **iterator** is used to obtain the values to be iterated. Some built-in types have a default iteration behavior, while other types (such as [`Object`](../object)) do not. The built-in types with a `@@iterator` method are: - [`Array.prototype[@@iterator]()`](../array/@@iterator) - [`TypedArray.prototype[@@iterator]()`](../typedarray/@@iterator) - [`String.prototype[@@iterator]()`](../string/@@iterator) - [`Map.prototype[@@iterator]()`](../map/@@iterator) - [`Set.prototype[@@iterator]()`](../set/@@iterator) See also [Iteration protocols](../../iteration_protocols) for more information. Property attributes of `Symbol.iterator` Writable no Enumerable no Configurable no ## Examples ### User-defined iterables We can make our own iterables like this: var myIterable = {} myIterable[Symbol.iterator] = function* () { yield 1; yield 2; yield 3; }; [...myIterable] // [1, 2, 3] Or iterables can be defined directly inside a class or object using a [computed property](../../operators/object_initializer#computed_property_names): class Foo { *[Symbol.iterator] () { yield 1; yield 2; yield 3; } } const someObj = { *[Symbol.iterator] () { yield 'a'; yield 'b'; } } console.log(...new Foo); // 1, 2, 3 console.log(...someObj); // 'a', 'b' ### Non-well-formed iterables If an iterable's `@@iterator` method does not return an iterator object, then it is a non-well-formed iterable. Using it as such is likely to result in runtime exceptions or buggy behavior: var nonWellFormedIterable = {} nonWellFormedIterable[Symbol.iterator] = () => 1 [...nonWellFormedIterable] // TypeError: [] is not a function ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Symbol.iterator' in that specification.
      `iterator` 43 12 36 No 30 10 43 43 36 30 10 4.0 ## See also - [Iteration protocols](../../iteration_protocols) - [`Array.prototype[@@iterator]()`](../array/@@iterator) - [`TypedArray.prototype[@@iterator]()`](../typedarray/@@iterator) - [`String.prototype[@@iterator]()`](../string/@@iterator) - [`Map.prototype[@@iterator]()`](../map/@@iterator) - [`Set.prototype[@@iterator]()`](../set/@@iterator) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator # Array.prototype.join() The `join()` method creates and returns a new string by concatenating all of the elements in an array (or an [array-like object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections#working_with_array-like_objects)), separated by commas or a specified separator string. If the array has only one item, then that item will be returned without using the separator. ## Syntax join() join(separator) ### Parameters `separator` Optional Specifies a string to separate each pair of adjacent elements of the array. The separator is converted to a string if necessary. If omitted, the array elements are separated with a comma (","). If `separator` is an empty string, all elements are joined without any characters in between them. ### Return value A string with all array elements joined. If `arr.length` is `0`, the empty string is returned. ## Description The string conversions of all array elements are joined into one string. **Warning:** If an element is `undefined`, `null` or an empty array `[]`, it is converted to an empty string. ## Examples ### Joining an array four different ways The following example creates an array, `a`, with three elements, then joins the array four times: using the default separator, then a comma and a space, then a plus and an empty string. var a = ['Wind', 'Water', 'Fire']; a.join(); // 'Wind,Water,Fire' a.join(', '); // 'Wind, Water, Fire' a.join(' + '); // 'Wind + Water + Fire' a.join(''); // 'WindWaterFire' ### Joining an array-like object The following example joins array-like object (`arguments`), by calling [`Function.prototype.call`](../function/call) on `Array.prototype.join`. function f(a, b, c) { var s = Array.prototype.join.call(arguments); console.log(s); // '1,a,true' } f(1, 'a', true); //expected output: "1,a,true" ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Array.prototype.join' in that specification.
      `join` 1 12 1 5.5 4 1 1 18 4 10.1 1 1.0 ## See also - [`String.prototype.split()`](../string/split) - [`Array.prototype.toString()`](tostring) - [`TypedArray.prototype.join()`](../typedarray/join) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join # JSON The `JSON` object contains methods for parsing [JavaScript Object Notation](https://json.org/) ([JSON](https://developer.mozilla.org/en-US/docs/Glossary/JSON)) and converting values to JSON. It can't be called or constructed, and aside from its two method properties, it has no interesting functionality of its own. ## Description ### JavaScript and JSON differences JSON is a syntax for serializing objects, arrays, numbers, strings, booleans, and [`null`](null). It is based upon JavaScript syntax but is distinct from it: some JavaScript is _not_ JSON. **Objects and Arrays** Property names must be double-quoted strings; [trailing commas](../trailing_commas) are forbidden. **Numbers** Leading zeros are prohibited. A decimal point must be followed by at least one digit. `NaN` and `Infinity` are unsupported. **Any JSON text is a valid JavaScript expression...** ...But only in JavaScript engines that have implemented the [proposal to make all JSON text valid ECMA-262](https://github.com/tc39/proposal-json-superset). In engines that haven't implemented the proposal, U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR are allowed in string literals and property keys in JSON; but their use in these features in JavaScript string literals is a [`SyntaxError`](syntaxerror). Consider this example where [`JSON.parse()`](json/parse) parses the string as JSON and [`Global_Objects/eval`](eval) executes the string as JavaScript: let code = '"\u2028\u2029"' JSON.parse(code) // evaluates to "\u2028\u2029" in all engines eval(code) // throws a SyntaxError in old engines Other differences include allowing only double-quoted strings and having no provisions for [`undefined`](undefined) or comments. For those who wish to use a more human-friendly configuration format based on JSON, there is [JSON5](https://json5.org/), used by the Babel compiler, and the more commonly used [YAML](https://en.wikipedia.org/wiki/YAML). ### Full JSON syntax The full JSON syntax is as follows: JSON = null or true or false or JSONNumber or JSONString or JSONObject or JSONArray JSONNumber = - PositiveNumber or PositiveNumber PositiveNumber = DecimalNumber or DecimalNumber . Digits or DecimalNumber . Digits ExponentPart or DecimalNumber ExponentPart DecimalNumber = 0 or OneToNine Digits ExponentPart = e Exponent or E Exponent Exponent = Digits or + Digits or - Digits Digits = Digit or Digits Digit Digit = 0 through 9 OneToNine = 1 through 9 JSONString = "" or " StringCharacters " StringCharacters = StringCharacter or StringCharacters StringCharacter StringCharacter = any character except " or \ or U+0000 through U+001F or EscapeSequence EscapeSequence = \" or \/ or \\ or \b or \f or \n or \r or \t or \u HexDigit HexDigit HexDigit HexDigit HexDigit = 0 through 9 or A through F or a through f JSONObject = { } or { Members } Members = JSONString : JSON or Members , JSONString : JSON JSONArray = [ ] or [ ArrayElements ] ArrayElements = JSON or ArrayElements , JSON Insignificant [whitespace](https://developer.mozilla.org/en-US/docs/Glossary/Whitespace) may be present anywhere except within a `JSONNumber` (numbers must contain no whitespace) or `JSONString` (where it is interpreted as the corresponding character in the string, or would cause an error). The tab character ([U+0009](https://unicode-table.com/en/0009/)), carriage return ([U+000D](https://unicode-table.com/en/000D/)), line feed ([U+000A](https://unicode-table.com/en/000A/)), and space ([U+0020](https://unicode-table.com/en/0020/)) characters are the only valid whitespace characters. ## Static methods [`JSON.parse(text[, reviver])`](json/parse) Parse the string `text` as JSON, optionally transform the produced value and its properties, and return the value. Any violations of the JSON syntax, including those pertaining to the differences between JavaScript and JSON, cause a [`SyntaxError`](syntaxerror) to be thrown. The `reviver` option allows for interpreting what the `replacer` has used to stand in for other datatypes. [`JSON.stringify(value[, replacer[, space]])`](json/stringify) Return a JSON string corresponding to the specified value, optionally including only certain properties or replacing property values in a user-defined manner. By default, all instances of [`undefined`](undefined) are replaced with [`null`](null), and other unsupported native data types are censored. The `replacer` option allows for specifying other behavior. ## Examples ### Example JSON { "browsers": { "firefox": { "name": "Firefox", "pref_url": "about:config", "releases": { "1": { "release_date": "2004-11-09", "status": "retired", "engine": "Gecko", "engine_version": "1.7" } } } } } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-json-object
      `JSON` 3 12 3.5 8 10.5 4 ≤37 18 4 11 4 1.0 `json_superset` 66 79 62 No 53 12 66 66 62 47 12 9.0 `parse` 3 12 3.5 8 10.5 4 ≤37 18 4 11 4 1.0 `stringify` 3 12 3.5 8 10.5 4 ≤37 18 4 11 4 1.0 ## See also - [`Date.prototype.toJSON()`](date/tojson) - [JSON Diff](http://www.jsondiff.com/) checker - [JSON Beautifier/editor](https://jsonbeautifier.org/) - [JSON Parser](http://jsonparser.org/) - [JSON Validator](https://tools.learningcontainer.com/json-validator/) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON # SyntaxError: JSON.parse: bad parsing The JavaScript exceptions thrown by [`JSON.parse()`](../global_objects/json/parse) occur when string failed to be parsed as JSON. ## Message SyntaxError: JSON.parse: unterminated string literal SyntaxError: JSON.parse: bad control character in string literal SyntaxError: JSON.parse: bad character in string literal SyntaxError: JSON.parse: bad Unicode escape SyntaxError: JSON.parse: bad escape character SyntaxError: JSON.parse: unterminated string SyntaxError: JSON.parse: no number after minus sign SyntaxError: JSON.parse: unexpected non-digit SyntaxError: JSON.parse: missing digits after decimal point SyntaxError: JSON.parse: unterminated fractional number SyntaxError: JSON.parse: missing digits after exponent indicator SyntaxError: JSON.parse: missing digits after exponent sign SyntaxError: JSON.parse: exponent part is missing a number SyntaxError: JSON.parse: unexpected end of data SyntaxError: JSON.parse: unexpected keyword SyntaxError: JSON.parse: unexpected character SyntaxError: JSON.parse: end of data while reading object contents SyntaxError: JSON.parse: expected property name or '}' SyntaxError: JSON.parse: end of data when ',' or ']' was expected SyntaxError: JSON.parse: expected ',' or ']' after array element SyntaxError: JSON.parse: end of data when property name was expected SyntaxError: JSON.parse: expected double-quoted property name SyntaxError: JSON.parse: end of data after property name when ':' was expected SyntaxError: JSON.parse: expected ':' after property name in object SyntaxError: JSON.parse: end of data after property value in object SyntaxError: JSON.parse: expected ',' or '}' after property value in object SyntaxError: JSON.parse: expected ',' or '}' after property-value pair in object literal SyntaxError: JSON.parse: property names must be double-quoted strings SyntaxError: JSON.parse: expected property name or '}' SyntaxError: JSON.parse: unexpected character SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data SyntaxError: JSON.parse Error: Invalid character at position {0} (Edge) ## Error type [`SyntaxError`](../global_objects/syntaxerror) ## What went wrong? [`JSON.parse()`](../global_objects/json/parse) parses a string as JSON. This string has to be valid JSON and will throw this error if incorrect syntax was encountered. ## Examples ### `JSON.parse()` does not allow trailing commas Both lines will throw a SyntaxError: JSON.parse('[1, 2, 3, 4,]'); JSON.parse('{"foo": 1,}'); // SyntaxError JSON.parse: unexpected character // at line 1 column 14 of the JSON data Omit the trailing commas to parse the JSON correctly: JSON.parse('[1, 2, 3, 4]'); JSON.parse('{"foo": 1}'); ### Property names must be double-quoted strings You cannot use single-quotes around properties, like 'foo'. JSON.parse("{'foo': 1}"); // SyntaxError: JSON.parse: expected property name or '}' // at line 1 column 2 of the JSON data Instead write "foo": JSON.parse('{"foo": 1}'); ### Leading zeros and decimal points You cannot use leading zeros, like 01, and decimal points must be followed by at least one digit. JSON.parse('{"foo": 01}'); // SyntaxError: JSON.parse: expected ',' or '}' after property value // in object at line 1 column 2 of the JSON data JSON.parse('{"foo": 1.}'); // SyntaxError: JSON.parse: unterminated fractional number // at line 1 column 2 of the JSON data Instead write just 1 without a zero and use at least one digit after a decimal point: JSON.parse('{"foo": 1}'); JSON.parse('{"foo": 1.0}'); ## See also - [`JSON`](../global_objects/json) - [`JSON.parse()`](../global_objects/json/parse) - [`JSON.stringify()`](../global_objects/json/stringify) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/JSON_bad_parse # Symbol.keyFor() The `Symbol.keyFor(sym)` method retrieves a shared symbol key from the global symbol registry for the given symbol. ## Syntax Symbol.keyFor(sym); ### Parameters `sym` Symbol, required. The symbol to find a key for. ### Return value A string representing the key for the given symbol if one is found on the global registry; otherwise, [`undefined`](../undefined). ## Examples ### Using keyFor() var globalSym = Symbol.for('foo'); // create a new global symbol Symbol.keyFor(globalSym); // "foo" var localSym = Symbol(); Symbol.keyFor(localSym); // undefined // well-known symbols are not symbols registered // in the global symbol registry Symbol.keyFor(Symbol.iterator) // undefined ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-symbol.keyfor
      `keyFor` 40 12 36 No 27 9 40 40 36 27 9 4.0 ## See also - [`Symbol.for()`](for) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/keyFor # Object.keys() The `Object.keys()` method returns an array of a given object's own enumerable property **names**, iterated in the same order that a normal loop would. ## Syntax Object.keys(obj) ### Parameters `obj` The object of which the enumerable's own properties are to be returned. ### Return value An array of strings that represent all the enumerable properties of the given object. ## Description `Object.keys()` returns an array whose elements are strings corresponding to the enumerable properties found directly upon `object`. The ordering of the properties is the same as that given by looping over the properties of the object manually. ## Examples ### Using Object.keys // simple array const arr = ['a', 'b', 'c']; console.log(Object.keys(arr)); // console: ['0', '1', '2'] // array-like object const obj = { 0: 'a', 1: 'b', 2: 'c' }; console.log(Object.keys(obj)); // console: ['0', '1', '2'] // array-like object with random key ordering const anObj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.keys(anObj)); // console: ['2', '7', '100'] // getFoo is a property which isn't enumerable const myObj = Object.create({}, { getFoo: { value: function () { return this.foo; } } }); myObj.foo = 1; console.log(Object.keys(myObj)); // console: ['foo'] If you want _all_ properties—including non-enumerables—see [`Object.getOwnPropertyNames()`](getownpropertynames). ### Non-object coercion In ES5, if the argument to this method is not an object (a primitive), then it will cause a [`TypeError`](../typeerror). From ES2015 onwards, a non-object argument will be coerced to an object. // In ES5 Object.keys('foo'); // TypeError: "foo" is not an object // In ES2015+ Object.keys('foo'); // ["0", "1", "2"] ## Polyfill To add compatible `Object.keys` support in older environments that do not natively support it, copy the following snippet: // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys if (!Object.keys) { Object.keys = (function() { 'use strict'; var hasOwnProperty = Object.prototype.hasOwnProperty, hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'), dontEnums = [ 'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor' ], dontEnumsLength = dontEnums.length; return function(obj) { if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) { throw new TypeError('Object.keys called on non-object'); } var result = [], prop, i; for (prop in obj) { if (hasOwnProperty.call(obj, prop)) { result.push(prop); } } if (hasDontEnumBug) { for (i = 0; i < dontEnumsLength; i++) { if (hasOwnProperty.call(obj, dontEnums[i])) { result.push(dontEnums[i]); } } } return result; }; }()); } Please note that the above code includes non-enumerable keys in IE7 (and maybe IE8), when passing in an object from a different window. For a simple Browser Polyfill, see [Javascript - Object.keys Browser Compatibility](https://tokenposts.blogspot.com.au/2012/04/javascript-objectkeys-browser.html). ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-object.keys
      `keys` 5 12 4 9 12 5 1 18 4 12 5 1.0 ## See also - [Enumerability and ownership of properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) - [`Object.prototype.propertyIsEnumerable()`](propertyisenumerable) - [`Object.create()`](create) - [`Object.getOwnPropertyNames()`](getownpropertynames) - [`Object.values()`](values) - [`Object.entries()`](entries) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys # label The **labeled statement** can be used with [`break`](break) or [`continue`](continue) statements. It is prefixing a statement with an identifier which you can refer to. ## Syntax label : statement `label` Any JavaScript identifier that is not a reserved word. `statement` A JavaScript statement. `break` can be used with any labeled statement, and `continue` can be used with looping labeled statements. ## Description 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. Note that JavaScript has _no_ `goto` statement, you can only use labels with `break` or `continue`. In [strict mode](../strict_mode) code, you can't use "`let`" as a label name. It will throw a [`SyntaxError`](../global_objects/syntaxerror) (let is a reserved identifier). ## Examples ### Using a labeled continue with for loops var i, j; loop1: for (i = 0; i < 3; i++) { //The first for statement is labeled "loop1" loop2: for (j = 0; j < 3; j++) { //The second for statement is labeled "loop2" if (i === 1 && j === 1) { continue loop1; } console.log('i = ' + i + ', j = ' + j); } } // Output is: // "i = 0, j = 0" // "i = 0, j = 1" // "i = 0, j = 2" // "i = 1, j = 0" // "i = 2, j = 0" // "i = 2, j = 1" // "i = 2, j = 2" // Notice how it skips both "i = 1, j = 1" and "i = 1, j = 2" ### Using a labeled continue statement Given an array of items and an array of tests, this example counts the number of items that passes all the tests. var itemsPassed = 0; var i, j; top: for (i = 0; i < items.length; i++) { for (j = 0; j < tests.length; j++) { if (!tests[j].pass(items[i])) { continue top; } } itemsPassed++; } ### Using a labeled break with for loops var i, j; loop1: for (i = 0; i < 3; i++) { //The first for statement is labeled "loop1" loop2: for (j = 0; j < 3; j++) { //The second for statement is labeled "loop2" if (i === 1 && j === 1) { break loop1; } console.log('i = ' + i + ', j = ' + j); } } // Output is: // "i = 0, j = 0" // "i = 0, j = 1" // "i = 0, j = 2" // "i = 1, j = 0" // Notice the difference with the previous continue example ### Using a labeled break statement Given an array of items and an array of tests, this example determines whether all items pass all tests. var allPass = true; var i, j; top: for (i = 0; i < items.length; i++) { for (j = 0; j < tests.length; j++) { if (!tests[j].pass(items[i])) { allPass = false; break top; } } } ### Using a labeled block with break You can use labels within simple blocks, but only `break` statements can make use of non-loop labels. foo: { console.log('face'); break foo; console.log('this will not be executed'); } console.log('swap'); // this will log: // "face" // "swap" ### Labeled function declarations Starting with ECMAScript 2015, labeled function declarations are now standardized for non-strict code in the [web compatibility annex of the specification](https://www.ecma-international.org/ecma-262/6.0/#sec-labelled-function-declarations). L: function F() {} In [strict mode](../strict_mode) code, however, this will throw a [`SyntaxError`](../global_objects/syntaxerror): 'use strict'; L: function F() {} // SyntaxError: functions cannot be labelled [Generator functions](function*) can neither be labeled in strict code, nor in non-strict code: L: function* F() {} // SyntaxError: generator functions cannot be labelled ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Labelled statement' in that specification.
      `label` 1 12 1 4 4 1 1 18 4 10.1 1 1.0 ## See also - [`break`](break) - [`continue`](continue) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label # Intl.Locale.prototype.language The `Intl.Locale.prototype.language` property is an accessor property that returns the language associated with the locale. ## Description Language is one of the core features of a locale. The Unicode specification treats the language identifier of a locale as the language and the region together (to make a distinction between dialects and variations, e.g. British English vs. American English). The `language` property of a [`Locale`](../locale) returns strictly the locale's language subtag. ## Examples ### Setting the language in the locale identifer string argument In order to be a valid Unicode locale identifier, a string must start with the language subtag. The main argument to the [`Locale`](locale) constructor must be a valid Unicode locale identifier, so whenever the constructor is used, it must be passed an identifier with a language subtag. let langStr = new Intl.Locale("en-Latn-US"); console.log(langStr.language); // Prints "en" ### Overriding language via the configuration object While the language subtag must be specified, the [`Locale`](../locale) constructor takes a configuration object, which can override the language subtag. let langObj = new Intl.Locale("en-Latn-US", {language: "es"}); console.log(langObj.language); // Prints "es" ## Specifications
      Specification
      ECMAScript Internationalization API Specification (ECMAScript Internationalization API)
      #sec-Intl.Locale.prototype.language
      `language` 74 79 75 No 62 14 74 74 79 53 14 11.0 ## See also - [`Intl.Locale`](../locale) - [Unicode language subtag specification](https://www.unicode.org/reports/tr35/#unicode_language_subtag_validity) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/language # RegExp: lastIndex `lastIndex` is a read/write integer property of [`RegExp`](../regexp) instances that specifies the index at which to start the next match. Note that `lastIndex` is not a property of the [`RegExp`](../regexp) prototype but is instead only exposed from [`RegExp`](../regexp) instances. Property attributes of `RegExp: lastIndex` Writable yes Enumerable no Configurable no ## Description This property is set only if the regular expression instance used the `g` flag to indicate a global search, or the `y` flag to indicate a sticky search. The following rules apply: - If `lastIndex` is greater than the length of the string, [`test()`](test) and [`exec()`](exec) fail, then `lastIndex` is set to 0. - If `lastIndex` is equal to or less than the length of the string and if the regular expression matches the empty string, then the regular expression matches input starting from `lastIndex`. - If `lastIndex` is equal to the length of the string and if the regular expression does not match the empty string, then the regular expression mismatches input, and `lastIndex` is reset to 0. - Otherwise, `lastIndex` is set to the next position following the most recent match. ## Examples ### Using lastIndex Consider the following sequence of statements: var re = /(hi)?/g; Matches the empty string. console.log(re.exec('hi')); console.log(re.lastIndex); Returns `["hi", "hi"]` with `lastIndex` equal to 2. console.log(re.exec('hi')); console.log(re.lastIndex); Returns `["", undefined]`, an empty array whose zeroth element is the match string. In this case, the empty string because `lastIndex` was 2 (and still is 2) and `hi` has length 2. ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-properties-of-regexp-instances
      `lastIndex` 1 12 1 5.5 5 1 1 18 4 10.1 1 1.0 ## See also - [`RegExp.prototype.dotAll`](dotall) - [`RegExp.prototype.global`](global) - [`RegExp.prototype.hasIndices`](hasindices) - [`RegExp.prototype.ignoreCase`](ignorecase) - [`RegExp.prototype.multiline`](multiline) - [`RegExp.prototype.source`](source) - [`RegExp.prototype.sticky`](sticky) - [`RegExp.prototype.unicode`](unicode) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex # Array.prototype.lastIndexOf() The `lastIndexOf()` method returns the last index at which a given element can be found in the array, or -1 if it is not present. The array is searched backwards, starting at `fromIndex`. ## Syntax lastIndexOf(searchElement) lastIndexOf(searchElement, fromIndex) ### Parameters `searchElement` Element to locate in the array. `fromIndex` Optional The index at which to start searching backwards. Defaults to the array's length minus one (`arr.length - 1`), i.e. the whole array will be searched. If the index is greater than or equal to the length of the array, the whole array will be searched. If negative, it is taken as the offset from the end of the array. Note that even when the index is negative, the array is still searched from back to front. If the calculated index is less than 0, -1 is returned, i.e. the array will not be searched. ### Return value The last index of the element in the array; **-1** if not found. ## Description `lastIndexOf` compares `searchElement` to elements of the Array using [strict equality](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators#using_the_equality_operators) (the same method used by the ===, or triple-equals, operator). ## Examples ### Using `lastIndexOf` The following example uses `lastIndexOf` to locate values in an array. var numbers = [2, 5, 9, 2]; numbers.lastIndexOf(2); // 3 numbers.lastIndexOf(7); // -1 numbers.lastIndexOf(2, 3); // 3 numbers.lastIndexOf(2, 2); // 0 numbers.lastIndexOf(2, -2); // 0 numbers.lastIndexOf(2, -1); // 3 ### Finding all the occurrences of an element The following example uses `lastIndexOf` to find all the indices of an element in a given array, using [`push`](push) to add them to another array as they are found. var indices = []; var array = ['a', 'b', 'a', 'c', 'a', 'd']; var element = 'a'; var idx = array.lastIndexOf(element); while (idx != -1) { indices.push(idx); idx = (idx > 0 ? array.lastIndexOf(element, idx - 1) : -1); } console.log(indices); // [4, 2, 0] Note that we have to handle the case `idx == 0` separately here because the element will always be found regardless of the `fromIndex` parameter if it is the first element of the array. This is different from the [`indexOf`](indexof) method. ## Polyfill `lastIndexOf` was added to the ECMA-262 standard in the 5th edition; as such it may not be present in other implementations of the standard. You can work around this by inserting the following code at the beginning of your scripts, allowing use of `lastIndexOf` in implementations which do not natively support it. This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming [`Object`](../object), [`TypeError`](../typeerror), [`Number`](../number), [`Math.floor`](../math/floor), [`Math.abs`](../math/abs), and [`Math.min`](../math/min) have their original values. // Production steps of ECMA-262, Edition 5, 15.4.4.15 // Reference: https://es5.github.io/#x15.4.4.15 if (!Array.prototype.lastIndexOf) { Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/) { 'use strict'; if (this === void 0 || this === null) { throw new TypeError(); } var n, k, t = Object(this), len = t.length >>> 0; if (len === 0) { return -1; } n = len - 1; if (arguments.length > 1) { n = Number(arguments[1]); if (n != n) { n = 0; } else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); } } for (k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n); k >= 0; k--) { if (k in t && t[k] === searchElement) { return k; } } return -1; }; } Again, note that this implementation aims for absolute compatibility with `lastIndexOf` in Firefox and the SpiderMonkey JavaScript engine, including in several cases which are arguably edge cases. If you intend to use this in real-world applications, you may be able to calculate `from` with less complicated code if you ignore those cases. ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-array.prototype.lastindexof
      `lastIndexOf` 1 12 1.5 9 9.5 3 ≤37 18 4 10.1 1 1.0 ## See also - [`Array.prototype.indexOf()`](indexof) - [`TypedArray.prototype.lastIndexOf()`](../typedarray/lastindexof) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf # Left shift (<<) The `<<` shifts the first operand the specified number of bits to the left. Excess bits shifted off to the left are discarded. Zero bits are shifted in from the right. ## Syntax a << b ## Description This operator shifts the first operand the specified number of bits to the left. Excess bits shifted off to the left are discarded. Zero bits are shifted in from the right. For example, `9 << 2` yields 36: . 9 (base 10): 00000000000000000000000000001001 (base 2) -------------------------------- 9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10) Bitwise shifting any number `x` to the left by `y` bits yields `x * 2 ** y`. So e.g.: `9 << 3` translates to: `9 * (2 ** 3) = 9 * (8) = 72`. ## Examples ### Using left shift 9 << 3; // 72 // 9 * (2 ** 3) = 9 * (8) = 72 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-left-shift-operator
      `Left_shift` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Bitwise operators in the JS guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise) - [Left shift assignment operator](left_shift_assignment) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift # Left shift assignment (<<=) The left shift assignment operator (`<<=`) moves the specified amount of bits to the left and assigns the result to the variable. ## Syntax Operator: x <<= y Meaning: x = x << y ## Examples ### Using left shift assignment let a = 5; // 00000000000000000000000000000101 a <<= 2; // 20 // 00000000000000000000000000010100 ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-assignment-operators
      `Left_shift_assignment` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Assignment operators in the JS guide](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#assignment) - [Left shift operator](left_shift) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift_assignment # Array.prototype.length The `length` property of an object which is an instance of type `Array` sets or returns the number of elements in that array. The value is an unsigned, 32-bit integer that is always numerically greater than the highest index in the array. ## Description The value of the `length` property is an integer with a positive sign and a value less than 2 to the 32nd power (232). var namelistA = new Array(4294967296); //2 to the 32nd power = 4294967296 var namelistC = new Array(-100) //negative sign console.log(namelistA.length); //RangeError: Invalid array length console.log(namelistC.length); //RangeError: Invalid array length var namelistB = []; namelistB.length = Math.pow(2,32)-1; //set array length less than 2 to the 32nd power console.log(namelistB.length); //4294967295 You can set the `length` property to truncate an array at any time. When you extend an array by changing its `length` property, the number of actual elements increases; for example, if you set `length` to 3 when it is currently 2, the array now contains 3 elements, which causes the third element to be a non-iterable empty slot. const arr = [1, 2]; console.log(arr); // [ 1, 2 ] arr.length = 5; // set array length to 5 while currently 2. console.log(arr); // [ 1, 2, <3 empty items> ] arr.forEach(element => console.log(element)); // 1 // 2 As you can see, the `length` property does not necessarily indicate the number of defined values in the array. See also [Relationship between `length` and numerical properties](../array#relationship_between_length_and_numerical_properties). Property attributes of `Array.prototype.length` Writable yes Enumerable no Configurable no - `Writable`: If this attribute set to `false`, the value of the property cannot be changed. - `Configurable`: If this attribute set to `false`, any attempts to delete the property or change its attributes (`Writable`, `Configurable`, or `Enumerable`) will fail. - `Enumerable`: If this attribute set to `true`, the property will be iterated over during [for](../../statements/for) or [for..in](../../statements/for...in) loops. ## Examples ### Iterating over an array In the following example, the array `numbers` is iterated through by looking at the `length` property. The value in each element is then doubled. var numbers = [1, 2, 3, 4, 5]; var length = numbers.length; for (var i = 0; i < length; i++) { numbers[i] *= 2; } // numbers is now [2, 4, 6, 8, 10] ### Shortening an array The following example shortens the array `numbers` to a length of 3 if the current length is greater than 3. var numbers = [1, 2, 3, 4, 5]; if (numbers.length > 3) { numbers.length = 3; } console.log(numbers); // [1, 2, 3] console.log(numbers.length); // 3 ### Create empty array of fixed length var numbers = []; numbers.length = 3; console.log(numbers); // [undefined, undefined, undefined] ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-properties-of-array-instances-length
      `length` 1 12 1 4 4 1 ≤37 18 4 10.1 1 1.0 ## See also - [`Array`](../array) - [RangeError: invalid array length](../../errors/invalid_array_length) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length # Less than (<) The less than operator (`<`) returns `true` if the left operand is less than the right operand, and `false` otherwise. ## Syntax x < y ## Description The operands are compared using the [Abstract Relational Comparison](https://tc39.es/ecma262/#sec-abstract-relational-comparison) algorithm, which is roughly summarised below: - First, objects are converted to primitives using `Symbol.ToPrimitive` with the `hint` parameter be `'number'`. - If both values are strings, they are compared as strings, based on the values of the Unicode code points they contain. - Otherwise JavaScript attempts to convert non-numeric types to numeric values: - Boolean values `true` and `false` are converted to 1 and 0 respectively. - `null` is converted to 0. - `undefined` is converted to `NaN`. - Strings are converted based on the values they contain, and are converted as `NaN` if they do not contain numeric values. - If either value is `NaN`, the operator returns `false`. - Otherwise the values are compared as numeric values. ## Examples ### String to string comparison console.log("a" < "b"); // true console.log("a" < "a"); // false console.log("a" < "3"); // false ### String to number comparison console.log("5" < 3); // false console.log("3" < 3); // false console.log("3" < 5); // true console.log("hello" < 5); // false console.log(5 < "hello"); // false console.log("5" < 3n); // false console.log("3" < 5n); // true ### Number to Number comparison console.log(5 < 3); // false console.log(3 < 3); // false console.log(3 < 5); // true ### Number to BigInt comparison console.log(5n < 3); // false console.log(3 < 5n); // true ### Comparing Boolean, null, undefined, NaN console.log(true < false); // false console.log(false < true); // true console.log(0 < true); // true console.log(true < 1); // false console.log(null < 0); // false console.log(null < 1); // true console.log(undefined < 3); // false console.log(3 < undefined); // false console.log(3 < NaN); // false console.log(NaN < 3); // false ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-relational-operators
      `Less_than` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Greater than operator](greater_than) - [Greater than or equal operator](greater_than_or_equal) - [Less than or equal operator](less_than_or_equal) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than # Less than or equal (<=) The less than or equal operator (`<=`) returns `true` if the left operand is less than or equal to the right operand, and `false` otherwise. ## Syntax x <= y ## Description The operands are compared using the [Abstract Relational Comparison](https://tc39.es/ecma262/#sec-abstract-relational-comparison) algorithm. See the documentation for the [Less than](less_than) operator for a summary of this algorithm. ## Examples ### String to string comparison console.log("a" <= "b"); // true console.log("a" <= "a"); // true console.log("a" <= "3"); // false ### String to number comparison console.log("5" <= 3); // false console.log("3" <= 3); // true console.log("3" <= 5); // true console.log("hello" <= 5); // false console.log(5 <= "hello"); // false ### Number to Number comparison console.log(5 <= 3); // false console.log(3 <= 3); // true console.log(3 <= 5); // true ### Number to BigInt comparison console.log(5n <= 3); // false console.log(3 <= 3n); // true console.log(3 <= 5n); // true ### Comparing Boolean, null, undefined, NaN console.log(true <= false); // false console.log(true <= true); // true console.log(false <= true); // true console.log(true <= 0); // false console.log(true <= 1); // true console.log(null <= 0); // true console.log(1 <= null); // false console.log(undefined <= 3); // false console.log(3 <= undefined); // false console.log(3 <= NaN); // false console.log(NaN <= 3); // false ## Specifications
      Specification
      ECMAScript (ECMA-262)
      The definition of 'Relational operators' in that specification.
      `Less_than_or_equal` 1 12 1 3 3 1 1 18 4 10.1 1 1.0 ## See also - [Greater than operator](greater_than) - [Greater than or equal operator](greater_than_or_equal) - [Less than operator](less_than) © 2005–2021 MDN contributors. Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than_or_equal # let The `let` statement declares a block-scoped local variable, optionally initializing it to a value. ## Syntax let name1 [= value1] [, name2 [= value2]] [, ..., nameN [= valueN]; ### Parameters `nameN` The names of the variable or variables to declare. Each must be a legal JavaScript identifier. ` value``N ` Optional For each variable declared, you may optionally specify its initial value to any legal JavaScript expression. Alternatively, the [Destructuring Assignment](../operators/destructuring_assignment) syntax can also be used to declare variables. let { bar } = foo; // where foo = { bar:10, baz:12 }; /* This creates a variable with the name 'bar', which has a value of 10 */ ## Description `let` allows you to declare variables that are limited to the scope of a [block](block) statement, or expression on which it is used, unlike the [`var`](var) keyword, which declares a variable globally, or locally to an entire function regardless of block scope. The other difference between [`var`](var) and `let` is that the latter is initialized to a value only when a [parser evaluates it (see below)](#temporal_dead_zone). Just like [`const`](const#description) the `let` does _not_ create properties of the [`window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) object when declared globally (in the top-most scope). An explanation of why the name "**let**" was chosen can be found [here](https://stackoverflow.com/questions/37916940/why-was-the-name-let-chosen-for-block-scoped-variable-declarations-in-javascri). **Note:** Many issues with `let` variables can be avoided by declaring them at the top of the scope in which they are used (doing so may impact readibility). ## Examples ### Scoping rules Variables declared by `let` have their scope in the block for which they are declared, as well as in any contained sub-blocks. In this way, `let` works very much like `var`. The main difference is that the scope of a `var` variable is the entire enclosing function: function varTest() { var x = 1; { var x = 2; // same variable! console.log(x); // 2 } console.log(x); // 2 } function letTest() { let x = 1; { let x = 2; // different variable console.log(x); // 2 } console.log(x); // 1 } At the top level of programs and functions, `let`, unlike `var`, does not create a property on the global object. For example: var x = 'global'; let y = 'global'; console.log(this.x); // "global" console.log(this.y); // undefined ### Emulating private members In dealing with [constructors](https://developer.mozilla.org/en-US/docs/Glossary/Constructor) it is possible to use the `let` bindings to share one or more private members without using [closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures): var Thing; { let privateScope = new WeakMap(); let counter = 0; Thing = function() { this.someProperty = 'foo'; privateScope.set(this, { hidden: ++counter, }); }; Thing.prototype.showPublic = function() { return this.someProperty; }; Thing.prototype.showPrivate = function() { return privateScope.get(this).hidden; }; } console.log(typeof privateScope); // "undefined" var thing = new Thing(); console.log(thing); // Thing {someProperty: "foo"} thing.showPublic(); // "foo" thing.showPrivate(); // 1 The same privacy pattern with closures over local variables can be created with `var`, but those need a function scope (typically an [IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE) in the module pattern) instead of just a block scope like in the example above. ### Redeclarations Redeclaring the same variable within the same function or block scope raises a [`SyntaxError`](../global_objects/syntaxerror). if (x) { let foo; let foo; // SyntaxError thrown. } You may encounter errors in [`switch`](switch) statements because there is only one block. let x = 1; switch(x) { case 0: let foo; break; case 1: let foo; // SyntaxError for redeclaration. break; } However, it's important to point out that a block nested inside a case clause will create a new block scoped lexical environment, which will not produce the redeclaration errors shown above. let x = 1; switch(x) { case 0: { let foo; break; } case 1: { let foo; break; } } ### Temporal dead zone (TDZ) `let` variables cannot be read/written until they have been fully initialized, which happens when they are declared (if no initial value is specified on declaration, the variable is initialized with a value of `undefined`). Accessing the variable before the initialization results in a [`ReferenceError`](../global_objects/referenceerror). **Note:** This differs from [`var`](var#var_hoisting) variables, which will return a value of `undefined` if they are accessed before they are declared. The variable is said to be in a "temporal dead zone" (TDZ) from the start of the block until the initialization has completed. { // TDZ starts at beginning of scope console.log(bar); // undefined console.log(foo); // ReferenceError var bar = 1; let foo = 2; // End of TDZ (for foo) } The term "temporal" is used because the zone depends on the order of execution (time) rather than the order in which the code is written (position). For example, the code below works because, even though the function that uses the `let` variable appears before the variable is declared, the function is _called_ outside the TDZ. { // TDZ starts at beginning of scope const func = () => console.log(letVar); // OK // Within the TDZ letVar access throws `ReferenceError` let letVar = 3; // End of TDZ (for letVar) func(); // Called outside TDZ! } #### The TDZ and `typeof` Using the `typeof` operator for a `let` variable in its TDZ will throw a [`ReferenceError`](../global_objects/referenceerror): // results in a 'ReferenceError' console.log(typeof i); let i = 10; This differs from using `typeof` for undeclared variables, and variables that hold a value of `undefined`: // prints out 'undefined' console.log(typeof undeclaredVariable); #### TDZ combined with lexical scoping The following code results in a `ReferenceError` at the line shown: function test(){ var foo = 33; if(foo) { let foo = (foo + 55); // ReferenceError } } test(); The `if` block is evaluated because the outer `var foo` has a value. However due to lexical scoping this value is not available inside the block: the identifier `foo` _inside_ the `if` block is the `let foo`. The expression `(foo + 55)` throws a `ReferenceError` because initialization of `let foo` has not completed — it is still in the temporal dead zone. This phenomenon can be confusing in a situation like the following. The instruction `let n of n.a` is already inside the private scope of the for loop's block. So, the identifier `n.a` is resolved to the property '`a`' of the '`n`' object located in the first part of the instruction itself (`let n`). This is still in the temporal dead zone as its declaration statement has not been reached and terminated. function go(n) { // n here is defined! console.log(n); // Object {a: [1,2,3]} for (let n of n.a) { // ReferenceError console.log(n); } } go({a: [1, 2, 3]}); ### Other situations When used inside a block, `let` limits the variable's scope to that block. Note the difference between `var`, whose scope is inside the function where it is declared. var a = 1; var b = 2; if (a === 1) { var a = 11; // the scope is global let b = 22; // the scope is inside the if-block console.log(a); // 11 console.log(b); // 22 } console.log(a); // 11 console.log(b); // 2 However, this combination of `var` and `let` declaration below is a [`SyntaxError`](../global_objects/syntaxerror) due to `var` being hoisted to the top of the block. This results in an implicit re-declaration of the variable. let x = 1; { var x = 2; // SyntaxError for re-declaration } ## Specifications
      Specification
      ECMAScript Language Specification (ECMAScript)
      #sec-let-and-const-declarations
      `let` 49 48-49 Support outside of [strict mode](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Strict_mode). 41-49 [Strict mode](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Strict_mode) is required. 14 12-14 In Edge 12 and 13, `let` within a `for` loop initializer does not create a separate variable for each loop iteration as defined by ES2015. Instead, it behaves as though the loop were wrapped in a scoping block with the `let` immediately before the loop. 44 \["Prior to Firefox 44, `let` is only available to code blocks in HTML wrapped in a ` The same concept applies to promises. If we modify the above example a little bit, we get this: If we change this so that the ` In the above example, the inner text of the ` ## See also - [`