Array：length - JavaScript

Array：length
============

**`length`** 是 `Array` 的实例属性，表示该数组中元素的个数。该值是一个无符号 32 位整数，并且其数值总是大于数组最大索引。

尝试一下
----

值
-

一个小于 232 的非负整数。

| `Array：length` 的属性特性 |
| --- |
| 可写 | 是 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

`length` 属性的值是一个小于 232 的非负整数

```js
const listA = [1, 2, 3];
const listB = new Array(6);

console.log(listA.length);
// 3

console.log(listB.length);
// 6

listB.length = 2 \*\* 32; // 4294967296
// RangeError: Invalid array length

const listC = new Array(-100); // 负数是不允许的
// RangeError: Invalid array length
```

数组对象会观察 `length` 属性，并自动将 `length` 值与数组的内容同步。这意味着：

* 设置 `length` 小于当前长度的值将会截断数组——超过新 `length` 的元素将被删除。
* 设置超过当前 `length` 的任何数组索引（小于 232 的非负整数）将会扩展数组——`length` 属性增加以反映新的最高索引。
* 将 `length` 设置为无效值（例如负数或非整数）会引发 `RangeError` 异常。

当 `length` 被设置为比当前长度更大的值时，数组通过添加空槽来扩展，而不是实际的 `undefined` 值。空槽与数组方法有一些特殊的交互作用；详见数组方法和空槽。

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

arr.length = 5; // 将数组长度设置为 5，而当前为 2。
console.log(arr);
// [ 1, 2, <3 empty items> ]

arr.forEach((element) => console.log(element));
// 1
// 2
```

另请参阅：`length` 与数值属性的关系。

示例
--

### 遍历数组

在下面的示例中，通过查看 `length` 属性来遍历数组 `numbers`。然后将每个元素中的值加倍。

```js
const numbers = [1, 2, 3, 4, 5];
const length = numbers.length;
for (let i = 0; i < length; i++) {
  numbers[i] \*= 2;
}
// 遍历后的结果 [2, 4, 6, 8, 10]
```

### 截断数组

在下面的示例中，如果当前长度大于 3，数组 `numbers` 将会缩短为 3。

```js
const numbers = [1, 2, 3, 4, 5];

if (numbers.length > 3) {
  numbers.length = 3;
}

console.log(numbers); // [1, 2, 3]
console.log(numbers.length); // 3
console.log(numbers[3]); // undefined；多余的元素会被删除
```

### 创建固定长度的空数组

将 `length` 设置为大于当前长度的值将会创建一个稀疏数组。

```js
const numbers = [];
numbers.length = 3;
console.log(numbers); // [empty x 3]
```

### 长度不可写的数组

当添加的元素超过当前长度时，数组会自动更新 `length` 属性。如果 `length` 属性设置为不可写，则数组将无法更新它。在严格模式中这会导致错误。

```js
"use strict";

const numbers = [1, 2, 3, 4, 5];
Object.defineProperty(numbers, "length", { writable: false });
numbers[5] = 6; // TypeError: Cannot assign to read only property 'length' of object '[object Array]'
numbers.push(5); // // TypeError: Cannot assign to read only property 'length' of object '[object Array]'
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-properties-of-array-instances-length |

浏览器兼容性
------

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

参见
--

* 索引集合类
* `Array`
* `TypedArray`：`length`
* `String`: `length`
* RangeError: invalid array length


Array.prototype.reverse() - JavaScript

Array.prototype.reverse()
=========================

**`reverse()`** 方法*就地*反转数组中的元素，并返回同一数组的引用。数组的第一个元素会变成最后一个，数组的最后一个元素变成第一个。换句话说，数组中的元素顺序将被翻转，变为与之前相反的方向。

要在不改变原始数组的情况下反转数组中的元素，使用 `toReversed()`。

尝试一下
----

语法
--

```js
reverse()
```

### 返回值

原始数组反转后的引用。注意，数组是*就地*反转的，并且没有复制。

描述
--

`reverse` 方法反转数组中元素的位置，改变了数组，并返回该数组的引用。

`reverse()` 方法会保留空槽。如果源数组是稀疏的，则空槽对应的新索引将被删除，并且也成为空槽。

`reverse()` 方法是通用的。它只期望 `this` 值具有 `length` 属性和整数键属性。虽然字符串也是类似于数组的，但这个方法不适用于它们，因为字符串是不可变的。

示例
--

### 反转数组中的元素

下面的示例创建一个数组 `items`，其中包含三个元素，然后反转数组。调用 `reverse()` 会返回反转后的数组 `items` 的引用。

```js
const items = [1, 2, 3];
console.log(items); // [1, 2, 3]

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

### reverse() 方法返回对同一数组的引用

`reverse()` 方法返回对原始数组的引用，因此改变返回的数组也会改变原始数组。

```js
const numbers = [3, 2, 4, 1, 5];
const reversed = numbers.reverse();
// numbers 和 reversed 的顺序都是颠倒的 [5, 1, 4, 2, 3]
reversed[0] = 5;
console.log(numbers[0]); // 5
```

如果你希望 `reverse()` 不改变原始数组，但返回一个浅拷贝数组，就像其他数组方法（例如 `map()`）一样，使用 `toReversed()` 方法。或者，你可以在调用 `reverse()` 之前做一个浅拷贝，使用展开语法或 `Array.from()`。

```js
const numbers = [3, 2, 4, 1, 5];
// [...numbers] 创建一个浅拷贝，因此 reverse() 不会改变原始数据
const reverted = [...numbers].reverse();
reverted[0] = 5;
console.log(numbers[0]); // 3
```

### 对稀疏数组使用 reverse()

调用 `reverse()` 后，稀疏数组保持稀疏状态。空槽将以空槽的形式被复制到它们各自的新索引中。

```js
console.log([1, , 3].reverse()); // [3, empty, 1]
console.log([1, , 3, 4].reverse()); // [4, 3, empty, 1]
```

### 对非数组对象调用 reverse()

`reverse()` 方法读取 `this` 的 `length` 属性。然后，它访问 `0` 和 `length / 2` 之间的每个索引，并交换两端对应的两个索引，并在必要时，删除某些属性。

```js
const arrayLike = {
  length: 3,
  unrelated: "foo",
  2: 4,
};
console.log(Array.prototype.reverse.call(arrayLike));
// { '0': 4, length: 3, unrelated: 'foo' }
// 索引“2”被删除了，因为原本的数据中索引“0”不存在了
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype.reverse |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Array.prototype.reverse` 的 polyfill
* 索引集合类
* `Array`
* `Array.prototype.join()`
* `Array.prototype.sort()`
* `Array.prototype.toReversed()`
* `TypedArray.prototype.reverse()`


Array.prototype[@@unscopables] - JavaScript

Array.prototype[@@unscopables]
==============================

`Array.prototype` 的 **`@@unscopables`** 数据属性被所有 `Array` 实例共享。它包含在 ES2015 版本之前 ECMAScript 标准中未收纳的属性名，并且这些属性被排除在由 `with` 语句绑定的环境中。

值
-

一个 `null` 原型对象，包含下面给出的属性名称，且它们的值都设置为 `true`。

| `Array.prototype[@@unscopables]` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 是 |

描述
--

在 `with` 语句绑定中未包含的 `Array` 默认属性包括：

* `at()`
* `copyWithin()`
* `entries()`
* `fill()`
* `find()`
* `findIndex()`
* `findLast()`
* `findLastIndex()`
* `flat()`
* `flatMap()`
* `includes()`
* `keys()`
* `toReversed()`
* `toSorted()`
* `toSpliced()`
* `values()`

`Array.prototype[@@unscopables]` 是一个只包含所有上述属性且对应值为 `true` 的空对象。它的原型是 `null`，因此不会意外地使 `Object.prototype` 属性（比如 `toString`）变为非作用域属性，而令在 `with` 语句中调用数组的 `toString()` 方法仍然有效。

请参阅 `Symbol.unscopables` 了解如何为自定义对象设置非作用域属性。

示例
--

假设下面的 `keys.push('something')` 是在 ECMAScript 2015 之前编写的代码中调用的。

```js
var keys = [];

with (Array.prototype) {
  keys.push("something");
}
```

当 ECMAScript 2015 引入 `Array.prototype.keys()` 方法时，如果 `@@unscopables` 数据属性也没有被引入，那么 `keys.push('something')` 调用将会出现问题——因为 JavaScript 运行时会将 `keys` 解释为 `Array.prototype.keys()` 方法，而不是示例代码中定义的 `keys` 数组。

因此，`Array.prototype` 的 `@@unscopables` 数据属性使得 ECMAScript 2015 中引入的 `Array` 属性在 `with` 语句绑定时被忽略，从而使得在 ECMAScript 2015 之前编写的代码继续按预期工作，而不会出现问题。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype-@@unscopables |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Array.prototype[@@unscopables]` 的 polyfill
* 索引集合类
* `Array`
* `with`
* `Symbol.unscopables`


Array.prototype.toSpliced() - JavaScript

Array.prototype.toSpliced()
===========================

`Array` 实例的 **`toSpliced()`** 方法是 `splice()` 方法的复制版本。它返回一个新数组，并在给定的索引处删除和/或替换了一些元素。

语法
--

```js
toSpliced(start)
toSpliced(start, deleteCount)
toSpliced(start, deleteCount, item1)
toSpliced(start, deleteCount, item1, item2, itemN)
```

### 参数

`start`

从 0 开始计算的索引，表示要开始改变数组的位置，它会被转换为整数。

* 如果 `start < 0`，则从数组末尾开始计数，使用 `start + array.length`。
* 如果 `start < -array.length` 或者省略了 `start`，则使用 `0`。
* 如果 `start >= array.length`，不会删除任何元素，但该方法将表现为添加元素的函数，添加提供的所有元素。

`deleteCount` 可选

一个整数，指示数组中要从 `start` 删除的元素数量。

如果 `deleteCount` 被省略了，或者如果它的值大于或等于由 `start` 指定的位置到数组末尾的元素数量，将会删除从 `start` 到数组末尾的所有元素。但是，如果你想要传递任何 `itemN` 参数，则应向 `deleteCount` 传递 `Infinity` 值，以删除 `start` 之后的所有元素，因为显式的 `undefined` 会转换为 `0`。

如果 `deleteCount` 是 `0` 或者负数，则不会删除元素。在这种情况下，你应该指定至少一个新元素（见下文）。

`item1`, …, `itemN` 可选

元素将从 `start` 开始添加到数组当中。

如果你没有指定任何元素，`toSpliced()` 只会从数组中删除元素。

### 返回值

一个新数组，由 `start` 之前的所有元素、`item1`、`item2`、...、`itemN`，以及 `start + deleteCount` 之后的所有元素组成。

描述
--

`toSpliced()` 方法与 `splice()` 类似，可以同时完成多个操作：在数组中给定的索引开始移除指定数量的元素，然后在相同的索引处插入给定的元素。但是，它返回一个新数组，而不是修改原始数组。因此，此方法不会返回已删除的元素。

`toSpliced()` 方法不会产生稀疏数组。如果原始数组是稀疏的，在新数组中空槽将会被替换成 `undefined`。

`toSpliced()` 方法是通用的。它只期望 `this` 值具有 `length` 属性和整数键属性。

示例
--

### 删除、添加和替换元素

你可以通过使用 `toSpliced()` 来删除、添加和替换数组中的元素，并生成一个新的数组，这比使用 `slice()` 和 `concat()` 更高效。

```js
const months = ["Jan", "Mar", "Apr", "May"];

// 在索引 1 处添加一个元素
const months2 = months.toSpliced(1, 0, "Feb");
console.log(months2); // ["Jan", "Feb", "Mar", "Apr", "May"]

// 从第 2 个索引开始删除两个元素
const months3 = months2.toSpliced(2, 2);
console.log(months3); // ["Jan", "Feb", "May"]

// 在索引 1 处用两个新元素替换一个元素
const months4 = months3.toSpliced(1, 1, "Feb", "Mar");
console.log(months4); // ["Jan", "Feb", "Mar", "May"]

// 原数组不会被修改
console.log(months); // ["Jan", "Mar", "Apr", "May"]
```

### 在稀疏数组上使用 toSpliced()

`toSpliced()` 方法总是会生成一个密集的数组。

```js
const arr = [1, , 3, 4, , 6];
console.log(arr.toSpliced(1, 2)); // [1, 4, undefined, 6]
```

### 对非数组对象调用 toSpliced()

`toSpliced()` 方法将会读取 `this` 的 `length` 属性。然后，它读取所需的整数键属性并将其写入新数组。

```js
const arrayLike = {
  length: 3,
  unrelated: "foo",
  0: 5,
  2: 4,
};
console.log(Array.prototype.toSpliced.call(arrayLike, 0, 1, 2, 3));
// [2, 3, undefined, 4]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype.tospliced |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Array.prototype.toSpliced` 的 polyfill
* `Array.prototype.splice()`
* `Array.prototype.toReversed()`
* `Array.prototype.toSorted()`
* `Array.prototype.with()`


Array.prototype.splice() - JavaScript

Array.prototype.splice()
========================

**`splice()`** 方法通过移除或者替换已存在的元素和/或添加新元素就地改变一个数组的内容。

要创建一个删除和/或替换部分内容而不改变原数组的新数组，请使用 `toSpliced()`。要访问数组的一部分而不修改它，参见 `slice()`。

尝试一下
----

语法
--

```js
splice(start)
splice(start, deleteCount)
splice(start, deleteCount, item1)
splice(start, deleteCount, item1, item2, itemN)
```

### 参数

`start`

从 0 开始计算的索引，表示要开始改变数组的位置，它会被转换成整数。

* 负索引从数组末尾开始计算——如果 `start < 0`，使用 `start + array.length`。
* 如果 `start < -array.length`，使用 `0`。
* 如果 `start >= array.length`，则不会删除任何元素，但是该方法会表现为添加元素的函数，添加所提供的那些元素。
* 如果 `start` 被省略了（即调用 `splice()` 时不传递参数），则不会删除任何元素。这与传递 `undefined` 不同，后者会被转换为 `0`。

`deleteCount` 可选

一个整数，表示数组中要从 `start` 开始删除的元素数量。

如果省略了 `deleteCount`，或者其值大于或等于由 `start` 指定的位置到数组末尾的元素数量，那么从 `start` 到数组末尾的所有元素将被删除。但是，如果你想要传递任何 `itemN` 参数，则应向 `deleteCount` 传递 `Infinity` 值，以删除 `start` 之后的所有元素，因为显式的 `undefined` 会转换为 `0`。

如果 `deleteCount` 是 `0` 或者负数，则不会移除任何元素。在这种情况下，你应该至少指定一个新元素（请参见下文）。

`item1`, …, `itemN` 可选

从 `start` 开始要加入到数组中的元素。

如果不指定任何元素，`splice()` 将只从数组中删除元素。

### 返回值

一个包含了删除的元素的数组。

如果只移除一个元素，则返回一个元素的数组。

如果没有删除任何元素，则返回一个空数组。

描述
--

`splice()` 方法是一个修改方法。它可能会更改 `this` 的内容。如果指定的要插入的元素数量与要删除的元素数量不同，数组的 `length` 也将会更改。同时，它会使用 `@@species` 来创建一个新数组实例并返回。

如果删除的部分是稀疏的，则 `splice()` 返回的数组也是稀疏的，对应的索引为空槽。

`splice()` 方法是通用的。它只期望 `this` 值具有 `length` 属性和整数键属性。尽管字符串也类似于数组，但这种方法不适用于它，因为字符串是不可变的。

示例
--

### 移除索引 2 之前的 0（零）个元素，并插入“drum”

```js
const myFish = ["angel", "clown", "mandarin", "sturgeon"];
const removed = myFish.splice(2, 0, "drum");

// 运算后的 myFish 是 ["angel", "clown", "drum", "mandarin", "sturgeon"]
// removed 是 []，没有元素被删除
```

### 移除索引 2 之前的 0（零）个元素，并插入“drum”和“guitar”

```js
const myFish = ["angel", "clown", "mandarin", "sturgeon"];
const removed = myFish.splice(2, 0, "drum", "guitar");

// 运算后的 myFish 是 ["angel", "clown", "drum", "guitar", "mandarin", "sturgeon"]
// removed 是 []，没有元素被删除
```

### 在索引 3 处移除 1 个元素

```js
const myFish = ["angel", "clown", "drum", "mandarin", "sturgeon"];
const removed = myFish.splice(3, 1);

// 运算后的 myFish 是 ["angel", "clown", "drum", "sturgeon"]
// removed 是 ["mandarin"]
```

### 在索引 2 处移除 1 个元素，并插入“trumpet”

```js
const myFish = ["angel", "clown", "drum", "sturgeon"];
const removed = myFish.splice(2, 1, "trumpet");

// 运算后的 myFish 是 ["angel", "clown", "trumpet", "sturgeon"]
// removed 是 ["drum"]
```

### 从索引 0 处移除 2 个元素，并插入“parrot”、“anemone”和“blue”

```js
const myFish = ["angel", "clown", "trumpet", "sturgeon"];
const removed = myFish.splice(0, 2, "parrot", "anemone", "blue");

// 运算后的 myFish 是 ["parrot", "anemone", "blue", "trumpet", "sturgeon"]
// removed 是 ["angel", "clown"]
```

### 从索引 2 处开始移除 2 个元素

```js
const myFish = ["parrot", "anemone", "blue", "trumpet", "sturgeon"];
const removed = myFish.splice(2, 2);

// 运算后的 myFish 是 ["parrot", "anemone", "sturgeon"]
// removed 是 ["blue", "trumpet"]
```

### 从索引 -2 处移除 1 个元素

```js
const myFish = ["angel", "clown", "mandarin", "sturgeon"];
const removed = myFish.splice(-2, 1);

// 运算后的 myFish 是 ["angel", "clown", "sturgeon"]
// removed 是 ["mandarin"]
```

### 从索引 2 开始删除所有元素

```js
const myFish = ["angel", "clown", "mandarin", "sturgeon"];
const removed = myFish.splice(2);

// 运算后的 myFish 是 ["angel", "clown"]
// removed 是 ["mandarin", "sturgeon"]
```

### 在稀疏数组中使用 splice()

`splice()` 方法保留了数组的稀疏性。

```js
const arr = [1, , 3, 4, , 6];
console.log(arr.splice(1, 2)); // [empty, 3]
console.log(arr); // [1, 4, empty, 6]
```

### 在非数组对象中使用 splice()

`splice()` 方法读取 `this` 的 `length` 属性。然后，它根据需要更新整数键属性和 `length` 属性。

```js
const arrayLike = {
  length: 3,
  unrelated: "foo",
  0: 5,
  2: 4,
};
console.log(Array.prototype.splice.call(arrayLike, 0, 1, 2, 3));
// [ 5 ]
console.log(arrayLike);
// { '0': 2, '1': 3, '3': 4, length: 4, unrelated: 'foo' }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype.splice |

浏览器兼容性
------

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

参见
--

* 索引集合类
* `Array`
* `Array.prototype.concat()`
* `Array.prototype.push()`
* `Array.prototype.pop()`
* `Array.prototype.shift()`
* `Array.prototype.slice()`
* `Array.prototype.toSpliced()`
* `Array.prototype.unshift()`


Array.prototype.at() - JavaScript

Array.prototype.at()
====================

Baseline 2022
-------------

Newly availableSince March 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
**`at()`** 方法接收一个整数值并返回该索引对应的元素，允许正数和负数。负整数从数组中的最后一个元素开始倒数。

尝试一下
----

语法
--

```js
at(index)
```

### 参数

`index`

要返回的数组元素的索引（从零开始），会被转换为整数。负数索引从数组末尾开始计数——如果 `index < 0`，则会访问 `index + array.length` 位置的元素。

### 返回值

返回数组中与给定索引匹配的元素。如果 `index < -array.length` 或 `index >= array.length`，则总是返回 `undefined`，而不会尝试访问相应的属性。

描述
--

在传递非负数时，`at()` 方法等价于括号表示法。例如，`array[0]` 和 `array.at(0)` 均返回第一个元素。但是，当你需要从数组的末端开始倒数时，则不能使用 Python 和 R 语言中支持的 `array[-1]`，因为方括号内的所有值都会被视为字符串属性，因此你最终读取的是 `array["-1"]`，这只是一个普通的字符串属性而不是数组索引。

通常的做法是访问 `length` 并将其减去从末端开始的相对索引。例如，`array[array.length - 1]`。`at()` 方法允许使用相对索引，因此上面的示例可以简化为 `array.at(-1)`。

`at()` 方法是通用的。其仅期望 `this` 具有 `length` 属性和以整数为键的属性。

示例
--

### 返回数组的最后一个值

下面的示例提供了一个函数，它返回在一个指定的数组中找到的最后一个元素。

```js
// 数组及数组元素
const cart = ["apple", "banana", "pear"];

// 一个函数，用于返回给定数组的最后一个元素
function returnLast(arr) {
  return arr.at(-1);
}

// 获取 'cart' 数组的最后一个元素
const item1 = returnLast(cart);
console.log(item1); // 输出：'pear'

// 在 'cart' 数组中添加一个元素
cart.push("orange");
const item2 = returnLast(cart);
console.log(item2); // 输出：'orange'
```

### 比较不同的数组方法

这个示例比较了选择 `Array` 中倒数第二个元素的不同方法。虽然下面显示的所有方法都是可行的，但这个示例凸显了 `at()` 方法的简洁性和可读性。

```js
// 数组及数组元素
const colors = ["red", "green", "blue"];

// 使用长度属性
const lengthWay = colors[colors.length - 2];
console.log(lengthWay); // 输出：'green'

// 使用 slice() 方法。注意会返回一个数组
const sliceWay = colors.slice(-2, -1);
console.log(sliceWay[0]); // 输出：'green'

// 使用 at() 方法
const atWay = colors.at(-2);
console.log(atWay); // 输出：'green'
```

### 在非数组对象上调用 at()

`at()` 方法读取 `this` 的 `length` 属性并计算需要访问的索引。

```js
const arrayLike = {
  length: 2,
  0: "a",
  1: "b",
};
console.log(Array.prototype.at.call(arrayLike, -1)); // "b"
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype.at |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Array.prototype.at` 的 polyfill
* 索引集合类
* `Array`
* `Array.prototype.findIndex()`
* `Array.prototype.indexOf()`
* `TypedArray.prototype.at()` (en-US)
* `String.prototype.at()`


Array.prototype.toLocaleString() - JavaScript

Array.prototype.toLocaleString()
================================

**`toLocaleString()`** 方法返回一个字符串，表示数组中的所有元素。每个元素通过调用它们自己的 `toLocaleString` 方法转换为字符串，并且使用特定于语言环境的字符串（例如逗号“,”）分隔开。

尝试一下
----

语法
--

```js
toLocaleString()
toLocaleString(locales)
toLocaleString(locales, options)
```

### 参数

`locales` 可选

带有 BCP 47 语言标签的字符串，或者此类字符串的数组。对于 `locales` 参数的一般形式和说明，可以参见 `Intl` 主页面的参数说明。

`options` 可选

一个具有配置属性的对象。对于数字，请参见 `Number.prototype.toLocaleString()`；对于日期，请参见 `Date.prototype.toLocaleString()`。

### 返回值

一个字符串，表示数组中的所有元素。

描述
--

`Array.prototype.toLocaleString` 方法遍历数组内容，并使用提供的 `locales` 和 `options` 参数调用每个元素的 `toLocaleString` 方法，通过由实现定义的分隔符（例如逗号“,”）将转换后的字符串拼接起来。请注意，该方法本身不会使用这两个参数——它只是将其传递给每个元素的 `toLocaleString()`。分隔符的选择取决于主机当前的语言环境，而不是 `locales` 参数。

如果一个元素是 `undefined`、`null`，它会被转换为空字符串，而不是 `"null"` 或者 `"undefined"`。

当用于稀疏数组时，`toLocaleString()` 方法迭代时会把空槽当作 `undefined` 一样处理它。

`toLocaleString()` 方法是通用的。它只期望 `this` 值具有 `length` 属性和整数键属性。

示例
--

### 使用 locales 和 options

数组元素通过使用它们的 `toLocaleString` 方法转换为字符串。

* `Object`：`Object.prototype.toLocaleString()`
* `Number`：`Number.prototype.toLocaleString()`
* `Date`：`Date.prototype.toLocaleString()`

始终显示 `prices` 数组中字符串和数字的货币符号：

```js
const prices = ["￥7", 500, 8123, 12];
prices.toLocaleString("ja-JP", { style: "currency", currency: "JPY" });

// "￥7,￥500,￥8,123,￥12"
```

更多示例请参见 `Intl.NumberFormat` 和 `Intl.DateTimeFormat` 页面。

### 在稀疏数组中使用 toLocaleString()

`toLocaleString()` 将空槽视为 `undefined` ，并生成一个额外的分隔符：

```js
console.log([1, , 3].toLocaleString()); // '1,,3'
```

### 在非数组对象中使用 toLocaleString()

`toLocaleString()` 方法读取 `this` 的 `length` 属性，然后访问每个整数索引。

```js
const arrayLike = {
  length: 3,
  0: 1,
  1: 2,
  2: 3,
};
console.log(Array.prototype.toLocaleString.call(arrayLike));
// 1,2,3
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype.tolocalestring |
| ECMAScript Internationalization API Specification # sup-array.prototype.tolocalestring |

浏览器兼容性
------

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

参见
--

* 索引集合类
* `Array`
* `Array.prototype.toString()`
* `TypedArray.prototype.toLocaleString()`
* `Intl`
* `Intl.ListFormat`
* `Object.prototype.toLocaleString()`
* `Number.prototype.toLocaleString()`
* `Date.prototype.toLocaleString()`


Array.prototype.values() - JavaScript

Array.prototype.values()
========================

**`values()`** 方法返回一个新的*数组迭代器*对象，该对象迭代数组中每个元素的值。

尝试一下
----

语法
--

```js
values()
```

### 返回值

一个新的可迭代迭代器对象。

描述
--

`Array.prototype.values()` 是 `Array.prototype[@@iterator]()` 的默认实现。

```js
Array.prototype.values === Array.prototype[Symbol.iterator]; // true
```

当应用于稀疏数组时，`values()` 方法会将空槽作为 `undefined` 迭代。

`values()` 方法是通用的。它只需要 `this` 值具有 `length` 属性和整数键属性。

示例
--

### 使用 for...of 循环进行迭代

由于 `values()` 返回一个可迭代迭代器对象，你可以使用 `for...of` 循环来迭代它。

```js
const arr = ["a", "b", "c", "d", "e"];
const iterator = arr.values();

for (const letter of iterator) {
  console.log(letter);
} // "a" "b" "c" "d" "e"
```

### 使用 next() 迭代

由于返回值也是一个迭代器，你可以直接调用其 `next()` 方法。

```js
const arr = ["a", "b", "c", "d", "e"];
const iterator = arr.values();
iterator.next(); // { value: "a", done: false }
iterator.next(); // { value: "b", done: false }
iterator.next(); // { value: "c", done: false }
iterator.next(); // { value: "d", done: false }
iterator.next(); // { value: "e", done: false }
iterator.next(); // { value: undefined, done: true }
console.log(iterator.next().value); // undefined
```

### 重复使用可迭代对象

**警告：** 数组迭代器对象应该是一次性使用的对象。不要重复使用它。

`values()` 返回的可迭代对象是不可重复使用的。当 `next().done = true` 或 `currentIndex > length` 时，`for...of` 循环结束，进一步迭代它没有任何效果。

```js
const arr = ["a", "b", "c", "d", "e"];
const values = arr.values();
for (const letter of values) {
  console.log(letter);
}
// "a" "b" "c" "d" "e"
for (const letter of values) {
  console.log(letter);
}
// undefined
```

如果使用 `break` 语句提前结束迭代，当继续迭代时，迭代器可以从当前位置恢复迭代。

```js
const arr = ["a", "b", "c", "d", "e"];
const values = arr.values();
for (const letter of values) {
  console.log(letter);
  if (letter === "b") {
    break;
  }
}
// "a" "b"

for (const letter of values) {
  console.log(letter);
}
// "c" "d" "e"
```

### 迭代期间的修改操作

`values()` 返回的数组迭代器对象中没有存储任何值；但是它存储了用于创建它的数组的地址，并在每次迭代中读取当前访问的索引。因此，它的迭代输出取决于在迭代时存储在该索引中的值。如果数组中的值发生了改变，数组迭代器对象的值也会改变。

```js
const arr = ["a", "b", "c", "d", "e"];
const iterator = arr.values();
console.log(iterator); // Array Iterator { }
console.log(iterator.next().value); // "a"
arr[1] = "n";
console.log(iterator.next().value); // "n"
```

### 迭代稀疏数组

`values()` 会访问空槽并将其视为 `undefined`。

```js
for (const element of [, "a"].values()) {
  console.log(element);
}
// undefined
// 'a'
```

### 在非数组对象上调用 values()

`values()` 方法读取 `this` 的 `length` 属性，然后访问每个整数索引。

```js
const arrayLike = {
  length: 3,
  0: "a",
  1: "b",
  2: "c",
};
for (const entry of Array.prototype.values.call(arrayLike)) {
  console.log(entry);
}
// a
// b
// c
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype.values |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Array.prototype.values` 的 polyfill
* 索引集合类
* `Array`
* `Array.prototype.entries()`
* `Array.prototype.keys()`
* `Array.prototype[@@iterator]()`
* `TypedArray.prototype.values()`
* 迭代协议


Array.prototype.sort() - JavaScript

Array.prototype.sort()
======================

**`sort()`** 方法*就地*对数组的元素进行排序，并返回对相同数组的引用。默认排序是将元素转换为字符串，然后按照它们的 UTF-16 码元值升序排序。

由于它取决于具体实现，因此无法保证排序的时间和空间复杂度。

如果想要不改变原数组的排序方法，可以使用 `toSorted()`。

尝试一下
----

语法
--

```js
sort()
sort(compareFn)
```

### 参数

`compareFn` 可选

定义排序顺序的函数。返回值应该是一个数字，其正负性表示两个元素的相对顺序。该函数使用以下参数调用：

`a`

第一个用于比较的元素。不会是 `undefined`。

`b`

第二个用于比较的元素。不会是 `undefined`。

如果省略该函数，数组元素会被转换为字符串，然后根据每个字符的 Unicode 码位值进行排序。

### 返回值

经过排序的原始数组的引用。注意数组是*就地*排序的，不会进行复制。

描述
--

如果没有提供 `compareFn`，所有非 `undefined` 的数组元素都会被转换为字符串，并按照 UTF-16 码元顺序比较字符串进行排序。例如“banana”会被排列到“cherry”之前。在数值排序中，9 出现在 80 之前，但因为数字会被转换为字符串，在 Unicode 顺序中“80”排在“9”之前。所有的 `undefined` 元素都会被排序到数组的末尾。

`sort()` 方法保留空槽。如果源数组是稀疏的，则空槽会被移动到数组的末尾，并始终排在所有 `undefined` 元素的后面。

**备注：** 在 UTF-16 中，Unicode 字符超出 `\uFFFF` 的范围会被编码为两个代理码元（surrogate code unit），这些码位的范围是 `\uD800` 到 `\uDFFF`。每个码位的值都会被单独考虑进行比较。因此，由代理对 `\uD855\uDE51` 组成的字符将排在字符 `\uFF3A` 的前面。

如果提供了 `compareFn`，所有非 `undefined` 的数组元素都会按照比较函数的返回值进行排序（所有的 `undefined` 元素都会被排序到数组的末尾，并且不调用 `compareFn`）。

| `compareFn(a, b)` 返回值 | 排序顺序 |
| --- | --- |
| > 0 | `a` 在 `b` 后，如 `[b, a]` |
| < 0 | `a` 在 `b` 前，如 `[a, b]` |
| === 0 | 保持 `a` 和 `b` 原来的顺序 |

所以，比较函数形式如下：

```js
function compareFn(a, b) {
  if (根据排序标准，a 小于 b) {
    return -1;
  }
  if (根据排序标准，a 大于 b) {
    return 1;
  }
  // a 一定等于 b
  return 0;
}
```

更正式地说，为了确保正确的排序行为，比较函数应具有以下属性：

* *纯函数*：比较函数不会改变被比较的对象或任何外部状态。（这很重要，因为无法保证比较函数将在*何时*以及*如何*调用，因此任何特定的调用都不应对外部产生可见的效果。）
* *稳定性*：比较函数对于相同的输入对应始终返回相同的结果。
* *自反性*：`compareFn(a, a) === 0`。
* *反对称性*：`compareFn(a, b)` 和 `compareFn(b, a)` 必须都是 `0` 或者具有相反的符号。
* *传递性*：如果 `compareFn(a, b)` 和 `compareFn(b, c)` 都是正数、零或负数，则 `compareFn(a, c)` 的符号与前面两个相同。

符合上述限制的比较函数将始终能够返回 `1`、`0` 和 `-1` 中的任意一个，或者始终返回 `0`。例如，如果比较函数只返回 `1` 和 `0`，或者只返回 `0` 和 `-1`，它将无法可靠地排序，因为*反对称性*被破坏了。一个总是返回 `0` 的比较函数将不会改变数组，但仍然是可靠的。

默认的字典比较函数符合上述所有限制。

要比较数字而非字符串，比较函数可以简单的用 `a` 减 `b`，如下的函数将会将数组升序排列（如果它不包含 `Infinity` 和 `NaN`）：

```js
function compareNumbers(a, b) {
  return a - b;
}
```

`sort()` 方法是通用的，它只期望 `this` 值具有 `length` 属性和整数键属性。虽然字符串也类似于数组，但此方法不适用于字符串，因为字符串是不可变的。

示例
--

### 创建、显示及排序数组

下述示例创建了四个数组，并展示原数组。之后对数组进行排序。对比了数字数组分别指定与不指定比较函数的结果。

```js
const stringArray = ["Blue", "Humpback", "Beluga"];
const numberArray = [40, 1, 5, 200];
const numericStringArray = ["80", "9", "700"];
const mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];

function compareNumbers(a, b) {
  return a - b;
}

stringArray.join(); // 'Blue,Humpback,Beluga'
stringArray.sort(); // ['Beluga', 'Blue', 'Humpback']

numberArray.join(); // '40,1,5,200'
numberArray.sort(); // [1, 200, 40, 5]
numberArray.sort(compareNumbers); // [1, 5, 40, 200]

numericStringArray.join(); // '80,9,700'
numericStringArray.sort(); // ['700', '80', '9']
numericStringArray.sort(compareNumbers); // ['9', '80', '700']

mixedNumericArray.join(); // '80,9,700,40,1,5,200'
mixedNumericArray.sort(); // [1, 200, 40, 5, '700', '80', '9']
mixedNumericArray.sort(compareNumbers); // [1, 5, '9', 40, '80', 200, '700']
```

### 对象数组的排序

对象数组可以通过比较它们的某个属性的值来排序。

```js
const items = [
  { name: "Edward", value: 21 },
  { name: "Sharpe", value: 37 },
  { name: "And", value: 45 },
  { name: "The", value: -12 },
  { name: "Magnetic", value: 13 },
  { name: "Zeros", value: 37 },
];

// 根据 value 排序
items.sort((a, b) => a.value - b.value);

// 根据 name 排序
items.sort((a, b) => {
  const nameA = a.name.toUpperCase(); // 忽略大小写
  const nameB = b.name.toUpperCase(); // 忽略大小写
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }

  // name 必须相等
  return 0;
});
```

### 对非 ASCII 字符排序

当排序非 ASCII 字符的字符串（如包含类似 e、é、è、a、ä 等字符的字符串）。一些非英语语言的字符串需要使用 `String.localeCompare`。这个函数可以将函数排序到正确的顺序。

```js
var items = ["réservé", "premier", "cliché", "communiqué", "café", "adieu"];
items.sort(function (a, b) {
  return a.localeCompare(b);
});

// items 是 ['adieu', 'café', 'cliché', 'communiqué', 'premier', 'réservé']
```

### 使用 map 改善排序

`compareFn` 可能会在数组中的每个元素上调用多次。根据 `compareFn` 的性质，这可能会产生很高的开销。如果 `compareFn` 执行的工作更多，需要排序的元素更多，使用 `map()` 进行排序可能更有效率。其思路是遍历数组一次，将用于排序的实际值提取到一个临时数组中，对临时数组进行排序，然后遍历临时数组以获得正确的顺序。

```js
// 需要被排序的数组
const data = ["delta", "alpha", "charlie", "bravo"];

// 用于存放位置和排序值的对象数组
const mapped = data.map((v, i) => {
  return { i, value: someSlowOperation(v) };
});

// 按照多个值排序数组
mapped.sort((a, b) => {
  if (a.value > b.value) {
    return 1;
  }
  if (a.value < b.value) {
    return -1;
  }
  return 0;
});

const result = mapped.map((v) => data[v.i]);
```

有一个开源库叫做 mapsort，它采用了这种方法。

### sort() 方法返回对同一数组的引用

`sort()` 方法返回对原始数组的引用，因此更改返回的数组将同时更改原始数组。

```js
const numbers = [3, 1, 4, 1, 5];
const sorted = numbers.sort((a, b) => a - b);
// numbers 和 sorted 都是 [1, 1, 3, 4, 5]
sorted[0] = 10;
console.log(numbers[0]); // 10
```

如果你希望 `sort()` 方法不会改变原始数组，而是返回一个类似于其他数组方法（如 `map()` ）返回的浅拷贝数组，可以使用 `toSorted()` 方法。或者，你可以在调用 `sort()` 之前使用展开语法或 `Array.from()` 进行浅拷贝。

```js
const numbers = [3, 1, 4, 1, 5];
// [...numbers] 创建一个浅拷贝，因此 sort() 不会改变原始数组。
const sorted = [...numbers].sort((a, b) => a - b);
sorted[0] = 10;
console.log(numbers[0]); // 3
```

### 排序稳定性

自 EcmaScript 第 10 版（EcmaScript 2019）起，规范 要求 `Array.prototype.sort` 为稳定排序。

假设有一个包含学生名字和年级的列表，已经将它按学生名字字母顺序进行预排序：

```js
const students = [
  { name: "Alex", grade: 15 },
  { name: "Devlin", grade: 15 },
  { name: "Eagle", grade: 13 },
  { name: "Sam", grade: 14 },
];
```

对这个数组执行 `grade` 升序排序后：

```js
students.sort((firstItem, secondItem) => firstItem.grade - secondItem.grade);
```

`students` 变量会具有以下值：

```js
[
  { name: "Eagle", grade: 13 },
  { name: "Sam", grade: 14 },
  { name: "Alex", grade: 15 }, // grade 相同时维持原先的顺序（稳定排序）
  { name: "Devlin", grade: 15 }, // grade 相同时维持原先的顺序（稳定排序）
];
```

注意，那些年级相同的学生（如 Alex 和 Devlin）会维持调用排序之前的顺序，这是稳定排序所确保的。

EcmaScript 第 10 版（EcmaScript 2019）以前没有要求稳定性，意味着你可能会得到以下结果：

```js
[
  { name: "Eagle", grade: 13 },
  { name: "Sam", grade: 14 },
  { name: "Devlin", grade: 15 }, // 没有维持原先的顺序
  { name: "Alex", grade: 15 }, // 没有维持原先的顺序
];
```

### 使用非规范的比较函数进行排序

如果一个比较函数不符合纯函数、稳定性、自反性、反对称性和传递性规则，就像在描述中解释的那样，程序的行为是未定义的。

例如，请看这个示例：

```js
const arr = [3, 1, 4, 1, 5, 9];
const compareFn = (a, b) => (a > b ? 1 : 0);
arr.sort(compareFn);
```

在这个例子中，`compareFn` 函数是不规范的，因为它不满足反对称性：如果 `a > b`，它返回 `1`；但是通过交换 `a` 和 `b`，它返回了 `0` 而不是一个负值。因此，对于不同的引擎，结果数组也会有所不同。例如，V8（用于 Chrome、Node.js 等）和 JavaScriptCore（用于 Safari）根本不会对数组进行排序，而是返回 `[3, 1, 4, 1, 5, 9]`；而 SpiderMonkey（用于 Firefox）将返回升序排序的数组 `[1, 1, 3, 4, 5, 9]`。

然而，如果 `compareFn` 函数稍微改变一下，使其返回 `-1` 或 `0`：

```js
const arr = [3, 1, 4, 1, 5, 9];
const compareFn = (a, b) => (a > b ? -1 : 0);
arr.sort(compareFn);
```

那么在 V8 和 JavaScriptCore 中，它将按降序排序，结果为 `[9, 5, 4, 3, 1, 1]`，而 SpiderMonkey 返回的结果是原始数组：`[3, 1, 4, 1, 5, 9]`。

由于这种实现的不一致性，建议始终遵循五个约束条件以确保你的比较函数是规范的。

### 在稀疏数组上使用 sort()

空槽会被移动到数组的末尾。

```js
console.log(["a", "c", , "b"].sort()); // ['a', 'b', 'c', empty]
console.log([, undefined, "a", "b"].sort()); // ["a", "b", undefined, empty]
```

### 在类数组对象上调用 sort()

`sort()` 方法会读取 `this` 的 `length` 属性。然后它会收集在 `0` 到 `length - 1` 范围内所有已存在的整数键属性，对它们进行排序，然后写回。如果范围内存在缺失的属性，则相应的尾随属性将被删除，好像不存在的属性被排序到末尾一样。

```js
const arrayLike = {
  length: 3,
  unrelated: "foo",
  0: 5,
  2: 4,
};
console.log(Array.prototype.sort.call(arrayLike));
// { '0': 4, '1': 5, length: 3, unrelated: 'foo' }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype.sort |

浏览器兼容性
------

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

参见
--

* Polyfill of `Array.prototype.sort` with modern behavior like stable sort in `core-js`
* 索引集合类
* `Array`
* `Array.prototype.reverse()`
* `Array.prototype.toSorted()`
* `String.prototype.localeCompare()`
* `TypedArray.prototype.sort()`
* 在 V8 中进行排序 （v8.dev，2018 年 9 月 28 日）
* 稳定的 `Array.prototype.sort` 方法
* Mathias Bynens 的排序稳定性演示


Array.prototype.pop() - JavaScript

Array.prototype.pop()
=====================

**`pop()`** 方法从数组中删除**最后一个**元素，并返回该元素的值。此方法会更改数组的长度。

尝试一下
----

语法
--

```js
pop()
```

### 返回值

从数组中删除的元素（当数组为空时返回 `undefined`）。

描述
--

`pop()` 方法从一个数组中删除并返回最后一个元素给调用者。如果你在空数组上调用 `pop()`，它会返回 `undefined`。

`Array.prototype.shift()` 和 `pop()` 有类似的行为，但是它是作用在数组的第一个元素上的。

`pop()` 是修改方法。其改变了 `this` 的长度和内容。如果你想要 `this` 不变，但是返回一个新的最后一个元素被移除的数组，你可以使用 `arr.slice(0, -1)` 来代替。

`pop()` 方法是通用的。它只期望 `this` 值具有 `length` 属性和整数键属性。虽然字符串也是类数组对象，但是由于其不能被修改，所以 `pop()` 方法并不能应用在字符串上。

示例
--

### 删除掉数组的最后一个元素

下面的代码首先创建了一个拥有四个元素的数组 `myFish`，然后删除掉它的最后一个元素。

```js
const myFish = ["angel", "clown", "mandarin", "sturgeon"];

const popped = myFish.pop();

console.log(myFish); // ['angel', 'clown', 'mandarin' ]

console.log(popped); // 'sturgeon'
```

### 在非数组对象上调用 pop()

`pop()` 方法会读取 `this` 上的 `length` 属性。如果规范化的 length 属性为 0，`length` 会被再次设置为 0（鉴于之前可能是负数或者 `undefined`）。否则，返回并删除位于 `length - 1` 处的属性。

```js
const arrayLike = {
  length: 3,
  unrelated: "foo",
  2: 4,
};
console.log(Array.prototype.pop.call(arrayLike));
// 4
console.log(arrayLike);
// { length: 2, unrelated: 'foo' }

const plainObj = {};
// 没有 length 属性，所以长度为 0
Array.prototype.pop.call(plainObj);
console.log(plainObj);
// { length: 0 }
```

### 以类数组的方式使用对象

`push` 和 `pop` 方法是通用的，我们可以利用这一点来编写更灵活的代码——如以下示例所示。

请注意，在此示例中，我们不会创建数组来存储对象集合。相反，我们将集合存储在对象本身上，并在 `Array.prototype.push` 和 `Array.prototype.pop` 上使用 `call` 来欺骗这些方法，让它们认为我们正在处理一个数组。

```js
const collection = {
  length: 0,
  addElements(...elements) {
    // 每次添加元素时
    // obj.length 都会自动增加

    // 返回 push 方法的返回值，即 length 属性的新值
    return [].push.call(this, ...elements);
  },
  removeElement() {
    // 每次移除元素时
    // obj.length 都会自动减少

    // 返回 pop 方法的返回值，即被移除的元素
    return [].pop.call(this);
  },
};

collection.addElements(10, 20, 30);
console.log(collection.length); // 3
collection.removeElement();
console.log(collection.length); // 2
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype.pop |

浏览器兼容性
------

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

参见
--

* 索引集合类
* `Array`
* `Array.prototype.push()`
* `Array.prototype.shift()`
* `Array.prototype.unshift()`
* `Array.prototype.concat()`
* `Array.prototype.splice()`


Array.prototype.filter() - JavaScript

Array.prototype.filter()
========================

**`filter()`** 方法创建给定数组一部分的浅拷贝，其包含通过所提供函数实现的测试的所有元素。

尝试一下
----

语法
--

```js
filter(callbackFn)
filter(callbackFn, thisArg)
```

### 参数

`callbackFn`

为数组中的每个元素执行的函数。它应该返回一个真值以将元素保留在结果数组中，否则返回一个假值。该函数被调用时将传入以下参数：

`element`

数组中当前正在处理的元素。

`index`

正在处理的元素在数组中的索引。

`array`

调用了 `filter()` 的数组本身。

`thisArg`可选

执行 `callbackFn` 时用作 `this` 的值。参见迭代方法。

### 返回值

返回给定数组的一部分的浅拷贝，其中只包括通过提供的函数实现的测试的元素。如果没有元素通过测试，则返回一个空数组。

描述
--

`filter()` 方法是一个迭代方法。它为数组中的每个元素调用提供的 `callbackFn` 函数一次，并构造一个由所有返回真值的元素值组成的新数组。未通过 `callbackFn` 测试的数组元素不会包含在新数组中。

`callbackFn` 仅对已分配值的数组索引调用。它不会对稀疏数组中的空槽调用。

`filter()` 方法是一个复制方法。它不会改变 `this`，而是返回一个包含与原始数组相同的元素（其中某些元素已被过滤掉）的浅拷贝。但是，作为 `callbackFn` 的函数可以更改数组。请注意，在第一次调用 `callbackFn` *之前*，数组的长度已经被保存。因此：

* 当开始调用 `filter()` 时，`callbackFn` 将不会访问超出数组初始长度的任何元素。
* 对已访问索引的更改不会导致再次在这些元素上调用 `callbackFn`。
* 如果数组中一个现有的、尚未访问的元素被 `callbackFn` 更改，则它传递给 `callbackFn` 的值将是该元素被修改后的值。被删除的元素则不会被访问。

**警告：** 上述类型的并发修改经常导致难以理解的代码，通常应避免（特殊情况除外）。

`filter()` 方法是通用的。它只期望 `this` 值具有 `length` 属性和整数键属性。

示例
--

### 筛选排除所有较小的值

以下示例使用 `filter()` 创建一个过滤数组，该数组删除了所有值小于 `10` 的元素。

```js
function isBigEnough(value) {
  return value >= 10;
}

const filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]
```

### 找出数组中所有的素数

下面的例子返回数组中的所有素数：

```js
const array = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];

function isPrime(num) {
  for (let i = 2; num > i; i++) {
    if (num % i === 0) {
      return false;
    }
  }
  return num > 1;
}

console.log(array.filter(isPrime)); // [2, 3, 5, 7, 11, 13]
```

### 过滤 JSON 中的无效条目

以下示例使用 `filter()` 创建具有非零 `id` 的元素的 json。

```js
const arr = [
  { id: 15 },
  { id: -1 },
  { id: 0 },
  { id: 3 },
  { id: 12.2 },
  {},
  { id: null },
  { id: NaN },
  { id: "undefined" },
];

let invalidEntries = 0;

function filterByID(item) {
  if (Number.isFinite(item.id) && item.id !== 0) {
    return true;
  }
  invalidEntries++;
  return false;
}

const arrByID = arr.filter(filterByID);

console.log("过滤后的数组\n", arrByID);
// 过滤后的数组
// [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]

console.log("无效条目数量 =", invalidEntries);
// 无效条目数量 = 5
```

### 在数组中搜索

下例使用 `filter()` 根据搜索条件来过滤数组内容。

```js
const fruits = ["apple", "banana", "grapes", "mango", "orange"];

/\*\*
 \* 根据搜索条件（查询）筛选数组项
 \*/
function filterItems(arr, query) {
  return arr.filter((el) => el.toLowerCase().includes(query.toLowerCase()));
}

console.log(filterItems(fruits, "ap")); // ['apple', 'grapes']
console.log(filterItems(fruits, "an")); // ['banana', 'mango', 'orange']
```

### 在稀疏数组上使用 filter()

`filter()` 将跳过空槽。

```js
console.log([1, , undefined].filter((x) => x === undefined)); // [undefined]
console.log([1, , undefined].filter((x) => x !== 2)); // [1, undefined]
```

### 在非数组对象上调用 filter()

`filter()` 方法读取 `this` 的 `length` 属性，然后访问每个整数索引。

```js
const arrayLike = {
  length: 3,
  0: "a",
  1: "b",
  2: "c",
};
console.log(Array.prototype.filter.call(arrayLike, (x) => x <= "b"));
// [ 'a', 'b' ]
```

### 影响初始数组（修改、追加和删除）

下面的示例测试在修改数组时 `filter()` 方法的行为。

```js
// 修改每个单词
let words = ["spray", "limit", "exuberant", "destruction", "elite", "present"];

const modifiedWords = words.filter((word, index, arr) => {
  arr[index + 1] += " extra";
  return word.length < 6;
});

console.log(modifiedWords);
// 注意，在长度为 6 以下有三个单词，但是由于它们已经被修改，所以返回一个单词
// ["spray"]

// 添加新单词
words = ["spray", "limit", "exuberant", "destruction", "elite", "present"];
const appendedWords = words.filter((word, index, arr) => {
  arr.push("new");
  return word.length < 6;
});

console.log(appendedWords);
// 只有三个符合条件，即使 `words` 本身现在有更多字符长度小于 6 的单词
// ["spray" ,"limit" ,"elite"]

// 删除单词
words = ["spray", "limit", "exuberant", "destruction", "elite", "present"];
const deleteWords = words.filter((word, index, arr) => {
  arr.pop();
  return word.length < 6;
});

console.log(deleteWords);
// 注意我们没有得到 'elite'，因为它在过滤器访问到它之前就已经从 'words' 弹出了
// ["spray" ,"limit"]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype.filter |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Array.prototype.filter` 的 polyfill
* 索引集合类
* `Array`
* `Array.prototype.forEach()`
* `Array.prototype.every()`
* `Array.prototype.map()`
* `Array.prototype.some()`
* `Array.prototype.reduce()`
* `TypedArray.prototype.filter()`


Array.prototype.slice() - JavaScript

Array.prototype.slice()
=======================

**`slice()`** 方法返回一个新的数组对象，这一对象是一个由 `start` 和 `end` 决定的原数组的浅拷贝（包括 `start`，不包括 `end`），其中 `start` 和 `end` 代表了数组元素的索引。原始数组不会被改变。

尝试一下
----

语法
--

```js
slice()
slice(start)
slice(start, end)
```

参数
--

`start` 可选

提取起始处的索引（从 `0` 开始），会转换为整数。

* 如果索引是负数，则从数组末尾开始计算——如果 `start < 0`，则使用 `start + array.length`。
* 如果 `start < -array.length` 或者省略了 `start`，则使用 `0`。
* 如果 `start >= array.length`，则不提取任何元素。

`end` 可选

提取终止处的索引（从 `0` 开始），会转换为整数。`slice()` 会提取到但不包括 `end` 的位置。

* 如果索引是负数，则从数组末尾开始计算——如果 `end < 0`，则使用 `end + array.length`。
* 如果 `end < -array.length`，则使用 `0`。
* 如果 `end >= array.length` 或者省略了 `end`，则使用 `array.length`，提取所有元素直到末尾。
* 如果 `end` 在规范化后小于或等于 `start`，则不提取任何元素。

### 返回值

一个含有被提取元素的新数组。

描述
--

`slice()` 方法是一个复制方法。它不会改变 `this`，而是返回一个浅拷贝，其中包含了原始数组的一部分相同的元素。

`slice()` 方法会保留空槽。如果被切片的部分是稀疏的，则返回的数组也是稀疏的。

`slice()` 方法是通用的。它只要求 `this` 上有 `length` 属性和整数键属性。

示例
--

### 返回现有数组的一部分

```js
const fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
const citrus = fruits.slice(1, 3);

// fruits 包含 ['Banana', 'Orange', 'Lemon', 'Apple', 'Mango']
// citrus 包含 ['Orange','Lemon']
```

### 使用 `slice`

在下例中，`slice` 从 `myCar` 创建了一个新数组 `newCar`。两个数组都包含了一个 `myHonda` 对象的引用。当 `myHonda` 的 `color` 属性改变为 `purple`，则两个数组中的对应元素都会随之改变。

```js
// 使用 slice 方法从 myCar 创建一个 newCar。
const myHonda = {
  color: "red",
  wheels: 4,
  engine: { cylinders: 4, size: 2.2 },
};
const myCar = [myHonda, 2, "cherry condition", "purchased 1997"];
const newCar = myCar.slice(0, 2);

console.log("myCar =", myCar);
console.log("newCar =", newCar);
console.log("myCar[0].color =", myCar[0].color);
console.log("newCar[0].color =", newCar[0].color);

// 改变 myHonda 对象的 color。
myHonda.color = "purple";
console.log("The new color of my Honda is", myHonda.color);

console.log("myCar[0].color =", myCar[0].color);
console.log("newCar[0].color =", newCar[0].color);
```

上述代码输出：

```js
myCar = [
  { color: 'red', wheels: 4, engine: { cylinders: 4, size: 2.2 } },
  2,
  'cherry condition',
  'purchased 1997'
]
newCar = [ { color: 'red', wheels: 4, engine: { cylinders: 4, size: 2.2 } }, 2 ]
myCar[0].color = red
newCar[0].color = red
The new color of my Honda is purple
myCar[0].color = purple
newCar[0].color = purple
```

### 在类数组对象上调用 slice()

`slice()` 方法会读取 `this` 对象的 `length` 属性，然后从 `start` 到 `end` 读取整数键属性，并将它们定义在一个新创建的数组中。

```js
const arrayLike = {
  length: 3,
  0: 2,
  1: 3,
  2: 4,
};
console.log(Array.prototype.slice.call(arrayLike, 1, 3));
// [ 3, 4 ]
```

### 使用 slice() 把类数组对象转化为数组

`slice()` 方法经常与 `bind()` 和 `call()` 一起使用，用于创建一个实用方法，将类数组对象转换为数组。

```js
// 调用 slice() 方法时，会将 this 对象作为第一个参数传入
const slice = Function.prototype.call.bind(Array.prototype.slice);

function list() {
  return slice(arguments);
}

const list1 = list(1, 2, 3); // [1, 2, 3]
```

### 在稀疏数组上使用 slice()

如果源数组是稀疏数组，`slice()` 方法返回的数组也会是稀疏数组。

```js
console.log([1, 2, , 4, 5].slice(1, 4)); // [2, empty, 4]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype.slice |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Array.prototype.slice` 的 polyfill
* 索引集合类
* `Array`
* `Array.prototype.pop()`
* `Array.prototype.shift()`
* `Array.prototype.concat()`
* `Array.prototype.splice()`
* `TypedArray.prototype.slice()`
* `String.prototype.slice()`


Math.expm1() - JavaScript

Math.expm1()
============

**`Math.expm1()`** 函数返回 `E^x - 1`, 其中 `x` 是该函数的参数，`E` 是自然对数的底数 `2.718281828459045`。

语法
--
```

Math.expm1(x)
```

### 参数

`x`

任意数字。

描述
--

参数 `x` 会被自动类型转换成 `number` 类型。

`expm1` 是 "exponent minus 1" 的缩写。

示例
--

```js
Math.expm1(-Infinity); // -1
Math.expm1(-1); // -0.6321205588285577
Math.expm1(-0); // -0
Math.expm1(0); // 0
Math.expm1(1); // 1.718281828459045
Math.expm1(Infinity); // Infinity
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.expm1 |

浏览器兼容性
------

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

参见
--

* `Math` 对象。


Math.SQRT1_2 - JavaScript

Math.SQRT1\_2
=============

概述
--

**`Math.SQRT1_2`** 属性表示 1/2 的平方根，约为 0.707：

Math.SQRT1\_2

=

1
2

=

1

2

≈
0.707

\mathtt{\mi{Math.SQRT1\_2}} = \sqrt{\frac{1}{2}} = \frac{1}{\sqrt{2}} \approx 0.707

| `Math.SQRT1_2` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

由于 `SQRT1_2` 是 `Math` 对象的静态属性，所以应该像这样使用：`Math.SQRT1_2`，而不是作为你创建的 `Math` 实例的属性（`Math` 不是构造函数）。

示例
--

### 示例：使用 `SQRT1_2`

下面的函数返回 1/2 的平方根：

```js
function getRoot1\_2() {
  return Math.SQRT1\_2;
}

getRoot1\_2(); // 0.7071067811865476
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.sqrt1\_2 |

浏览器兼容性
------

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

参见
--

* `Math.pow()`
* `Math.sqrt()`


Math.tanh() - JavaScript

Math.tanh()
===========

**`Math.tanh()`** 函数将会返回一个数的双曲正切函数值，公式如下：

tanh
x
=

sinh
x

cosh
x

=

e
x

-

e

-
x

e
x

+

e

-
x

=

e

2
x

-
1

e

2
x

+
1

\tanh x = \frac{\sinh x}{\cosh x} = \frac {e^x - e^{-x}} {e^x + e^{-x}} = \frac{e^{2x} - 1}{e^{2x}+1}

尝试一下
----

语法
--
```

Math.tanh(x)
```

### 参数

`x`

待计算的数字。

### 返回值

所给数字的双曲正切值。

描述
--

因为 `tanh()` 是 `Math` 的静态方法，所以总应该直接调用 `Math.tanh()` ，而不是创建 `Math` 对象再调用该方法（`Math` 不是一个构造函数）。

示例
--

### 使用 `Math.tanh()`

```js
Math.tanh(0); // 0
Math.tanh(Infinity); // 1
Math.tanh(1); // 0.7615941559557649
```

向下兼容
----

`tanh()` 可以通过 `Math.exp()` 函数实现：

```js
Math.tanh =
  Math.tanh ||
  function (x) {
    var a = Math.exp(+x),
      b = Math.exp(-x);
    return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (a + b);
  };
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.tanh |

浏览器兼容性
------

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

参见
--

* `Math.acosh()`
* `Math.asinh()`
* `Math.atanh()`
* `Math.cosh()`
* `Math.sinh()`


Math.atanh() - JavaScript

Math.atanh()
============

**`Math.atanh()`** 函数返回一个数值反双曲正切值，即：

∀
x
∊

(

-
1
,
1

)

,

Math.atanh
(
x
)

=
arctanh
(
x
)
=
 the unique

y

such that

tanh
(
y
)
=
x

\forall x \in \left( -1, 1 \right), \mathtt{\operatorname{Math.atanh}(x)} = \operatorname{arctanh}(x) = \text{ the unique } ; y ; \text{such that} ; \tanh(y) = x

语法
--
```

Math.atanh(x)
```

### 参数

`x`

一个数值

描述
--

由于 `atanh()` 是 `Math` 的静态方法，所以应该像这样使用：`Math.atanh()`，而不是作为你创建的 `Math` 实例的方法（`Math` 不是一个构造函数）。

示例
--

### 使用 `Math.atanh()`

```js
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
```

对于大于 1 或是小于－1 的值，函数返回 `NaN` 。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.atanh |

浏览器兼容性
------

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

参见
--

* `Math.acosh()`
* `Math.asinh()`
* `Math.cosh()`
* `Math.sinh()`
* `Math.tanh()`


Math.ceil() - JavaScript

Math.ceil()
===========

**`Math.ceil()`** 静态方法总是向上舍入，并返回大于等于给定数字的最小整数。

尝试一下
----

语法
--

```js
Math.ceil(x)
```

### 参数

`x`

一个数值。

### 返回值

大于等于 `x` 的最小整数。它的值与 `-Math.floor(-x)` 相同。

描述
--

因为 `ceil()` 是 `Math` 的静态方法，所以你应始终使用 `Math.ceil()`，而不是作为你创建的 `Math` 对象的方法（`Math` 不是构造函数）。

示例
--

### 使用 Math.ceil()

```js
Math.ceil(-Infinity); // -Infinity
Math.ceil(-7.004); // -7
Math.ceil(-4); // -4
Math.ceil(-0.95); // -0
Math.ceil(-0); // -0
Math.ceil(0); // 0
Math.ceil(0.95); // 1
Math.ceil(4); // 4
Math.ceil(7.004); // 8
Math.ceil(Infinity); // Infinity
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.ceil |

浏览器兼容性
------

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

参见
--

* `Math.abs()`
* `Math.floor()`
* `Math.round()`
* `Math.sign()`
* `Math.trunc()`


Math.LN2 - JavaScript

Math.LN2
========

概述
--

**`Math.LN2`** 属性表示 2 的自然对数，约为 0.693：

Math.LN2

=
ln
(
2
)
≈
0.693

\mathtt{\mi{Math.LN2}} = \ln(2) \approx 0.693

| `Math.LN2` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

由于 `LN2` 是 `Math` 的静态属性，所以应该像这样使用：`Math.LN2`，而不是作为你创建的 `Math` 实例的属性（`Math` 不是构造函数）。

示例
--

### 示例：使用 `Math.LN2`

下面的函数返回 2 的自然对数：

```js
function getNatLog2() {
  return Math.LN2;
}

getNatLog2(); // 0.6931471805599453
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.ln2 |

浏览器兼容性
------

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

参见
--

* `Math.exp()`
* `Math.log()`
* `Math.log2()`


Math.SQRT2 - JavaScript

Math.SQRT2
==========

概述
--

**`Math.SQRT2`** 属性表示 2 的平方根，约为 1.414：

描述
--

由于 `SQRT2` 是 `Math` 的静态属性，所以应该像这样使用：`Math.SQRT2`，而不是作为你创建的 `Math` 实例的属性（`Math` 不是构造函数）。

示例
--

### 示例：使用 `Math.SQRT2`

下面的函数返回 2 的平方根：

```js
function getRoot2() {
  return Math.SQRT2;
}

getRoot2(); // 1.4142135623730951
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.sqrt2 |

浏览器兼容性
------

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

参见
--

* `Math.pow()`
* `Math.sqrt()`


Math.hypot() - JavaScript

Math.hypot()
============

**`Math.hypot()`** 函数返回所有参数的平方和的平方根，即：

𝙼𝚊𝚝𝚑.𝚑𝚢𝚙𝚘𝚝
(

v
1

,

v
2

,
…
,

v
n

)

=

∑

i
=
1

n

v
i
2

=

v
1
2

+

v
2
2

+
…
+

v
n
2

\mathtt{\operatorname{Math.hypot}(v\_1, v\_2, \dots, v\_n)} = \sqrt{\sum\_{i=1}^n v\_i^2} = \sqrt{v\_1^2 + v\_2^2 + \dots + v\_n^2}

尝试一下
----

语法
--
```

Math.hypot([value1[,value2, ...]])
```

### 参数

`value1, value2, ...`

任意个数字。

### 返回值

将所提供的参数求平方和后开平方根。如果有参数不能转换为数字，则返回 `NaN`。

描述
--

计算直角三角形的斜边，或复数的幅值时可以使用函数 `Math.sqrt(v1*v1 + v2*v2)` ，其中 v1 和 v2 是三角形的两个直角边或复数的实部和虚部。如果想计算更多维度，那么只需要在后面添加更多的数的平方就可以了，比如 `Math.sqrt(v1*v1 + v2*v2 + v3*v3 + v4*v4)`。

本函数比 `Math.sqrt()` 更简单也更快，你只需要调用 `Math.hypot(v1, v2)` 或 `Math.hypot(v1, v2, v3, v4, ...)`。

它还避免了幅值过大的问题。JS 中最大的双精度浮点数是 `Number.MAX_VALUE = 1.797...e+308`。如果你的数字比约 1e154 大，计算其平方值会返回 Infinity，使你的结果出现问题。比如，`Math.sqrt(1e200*1e200 + 1e200*1e200) = Infinity`。如果你改用 `hypot()` 函数，你可以得到正确的答案：`Math.hypot(1e200, 1e200) = 1.4142...e+200`。在数字非常小的时候同样如此，比如 `Math.sqrt(1e-200*1e-200 + 1e-200*1e-200) = 0`，但 `Math.hypot(1e-200, 1e-200) = 1.4142...e-200` 则是正确的结果。

由于 `hypot` 是 `Math` 的静态方法，所以应该以 `Math.hypot()`的方式使用，而不是作为你创建的 `Math` 对象的属性（`Math` 不是一个构造函数）。

如果不传入任何参数，则返回 +0。

如果参数列表中有至少一个参数不能被转换为数字，则返回 `NaN`。

如果只传入一个参数，`Math.hypot(x)` 等同于 `Math.abs(x)`。

示例
--

### Using `Math.hypot()`

```js
Math.hypot(3, 4); // 5
Math.hypot(3, 4, 5); // 7.0710678118654755
Math.hypot(); // 0
Math.hypot(NaN); // NaN
Math.hypot(3, 4, "foo"); // NaN, +'foo' => NaN
Math.hypot(3, 4, "5"); // 7.0710678118654755, +'5' => 5
Math.hypot(-3); // 3, the same as Math.abs(-3)
```

向下兼容
----

此函数可以使用如下代码模拟：

```js
if (!Math.hypot)
  Math.hypot = function () {
    var y = 0,
      i = arguments.length;
    while (i--) y += arguments[i] \* arguments[i];
    return Math.sqrt(y);
  };
```

另一种避免结果溢出的实现：

```js
if (!Math.hypot)
  Math.hypot = function (x, y) {
    // https://bugzilla.mozilla.org/show\_bug.cgi?id=896264#c28
    var max = 0;
    var s = 0;
    for (var i = 0; i < arguments.length; i += 1) {
      var arg = Math.abs(Number(arguments[i]));
      if (arg > max) {
        s \*= (max / arg) \* (max / arg);
        max = arg;
      }
      s += arg === 0 && max === 0 ? 0 : (arg / max) \* (arg / max);
    }
    return max === 1 / 0 ? 1 / 0 : max \* Math.sqrt(s);
  };
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.hypot |

浏览器兼容性
------

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

参见
--

* `Math.abs()`
* `Math.pow()`
* `Math.sqrt()`


Math.E - JavaScript

Math.E
======

概述
--

**`Math.E`** 属性表示自然对数的底数（或称为基数），e，约等于 2.718。

Math.E

=
e
≈
2.718

\mathtt{\mi{Math.E}} = e \approx 2.718

| `Math.E` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

由于 `E` 是 `Math` 对象的静态属性，所以应该像这样使用：`Math.E`，而不是作为你创建的 `Math` 实例对象的属性（`Math` 不是构造函数）。

示例
--

### 示例：使用 `Math.E`

下面的函数返回 e：

```js
function getNapier() {
  return Math.E;
}

getNapier(); // 2.718281828459045
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.e |

浏览器兼容性
------

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

参见
--

* `Math.exp()`
* `Math.log()`
* `Math.log1p()`


Math.log2() - JavaScript

Math.log2()
===========

概述
--

**`Math.log2()`** 函数返回一个数字以 2 为底的对数。

语法
--
```

Math.log2(x)
```

### 参数

`x`

任意数字。

描述
--

如果传入的参数小于 0，则返回 `NaN`.

示例
--

```js
Math.log2(2); // 1
Math.log2(1024); // 10
Math.log2(1); // 0
Math.log2(0); // -Infinity
Math.log2(-2); // NaN
Math.log2("1024"); // 10
Math.log2("foo"); // NaN
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.log2 |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Math.log2` 的 polyfill
* `Math.exp()`
* `Math.log()`
* `Math.log10()`
* `Math.log1p()`
* `Math.pow()`


Math.log1p() - JavaScript

Math.log1p()
============

概述
--

**`Math.log1p()`** 函数返回一个数字加 1 后的自然对数 (底为 `E`), 既`log(x+1)`.

语法
--

```js
Math.log1p(x)
```

### 参数

`x`

任意数字。

描述
--

如果参数的值小于 `-1`，则返回 `NaN`。

函数 `y = log(x+1)` 的图形是这样的：

![log(x+1)](/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p/logx1.jpg)

示例
--

```js
Math.log1p(Math.E - 1); // 1
Math.log1p(0); // 0
Math.log1p("0"); // 0
Math.log1p(-1); // -Infinity
Math.log1p(-2); // NaN
Math.log1p("foo"); // NaN
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.log1p |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Math.log1p` 的 polyfill
* `Math.exp()`
* `Math.log()`
* `Math.expm1()`
* `Math.log10()`
* `Math.log2()`
* `Math.pow()`


Math.asinh() - JavaScript

Math.asinh()
============

**`Math.asinh()`** 返回一个数值的反双曲正弦值，即：

Math.asinh
(
x
)

=
arsinh
(
x
)
=
 the unique

y

such that

sinh
(
y
)
=
x

\mathtt{\operatorname{Math.asinh}(x)} = \operatorname{arsinh}(x) = \text{ the unique } ; y ; \text{such that} ; \sinh(y) = x

尝试一下
----

语法
--
```

Math.asinh(x)
```

### 参数

`x`

一个数值。

### 返回值

返回指定数值的反双曲正弦值。

描述
--

由于 `asinh()` 是 `Math` 的静态方法，所以应该像这样使用：`Math.asinh()`，而不是作为你创建的 `Math` 实例的方法（`Math` 不是一个构造函数）。

示例
--

### 使用 `Math.asinh()`

```js
Math.asinh(-Infinity); // -Infinity
Math.asinh(-1); // -0.881373587019543
Math.asinh(-0); // -0
Math.asinh(0); // 0
Math.asinh(1); // 0.881373587019543
Math.asinh(Infinity); // Infinity
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.asinh |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Math.asinh` 的 polyfill
* `Math.acosh()`
* `Math.atanh()`
* `Math.cosh()`
* `Math.sinh()`
* `Math.tanh()`


Math.sinh() - JavaScript

Math.sinh()
===========

概述
--

**`Math.sinh()`** 函数返回一个数字 (单位为角度) 的双曲正弦值。

语法
--
```

Math.sinh(x)
```

### 参数

`x`

任意数字 (单位为度).

描述
--

双曲正弦的图像如下：

![](http://upload.wikimedia.org/wikipedia/commons/1/17/Sinh.png)

示例
--

```js
Math.sinh(-Infinity); // -Infinity
Math.sinh(-0); // -0
Math.sinh(0); // 0
Math.sinh(1); // 1.1752011936438014
Math.sinh(Infinity); // Infinity
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.sinh |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Math.sinh` 的 polyfill
* `Math.acos()`
* `Math.asin()`
* `Math.atan()`
* `Math.atan2()`
* `Math.cos()`
* `Math.tan()`


Math.floor() - JavaScript

Math.floor()
============

**`Math.floor()`** 函数总是返回小于等于一个给定数字的最大整数。

尝试一下
----

语法
--

```js
Math.floor(x)
```

### 参数

`x`

一个数字。

### 返回值

小于等于 `x` 的最大整数。它的值与 `-Math.ceil(-x)` 相同。

描述
--

因为 `floor()` 是 `Math` 的静态方法，所以你应始终使用 `Math.floor()`，而不是作为你创建的 `Math` 对象的方法（`Math` 不是构造函数）。

示例
--

### 使用 Math.floor()

```js
Math.floor(-Infinity); // -Infinity
Math.floor(-45.95); // -46
Math.floor(-45.05); // -46
Math.floor(-0); // -0
Math.floor(0); // 0
Math.floor(4); // 4
Math.floor(45.05); // 45
Math.floor(45.95); // 45
Math.floor(Infinity); // Infinity
```

### 十进制调整

在本例中，我们实现了一个名为 `decimalAdjust()` 的方法，它是 `Math.floor()`、`Math.ceil()` 和 `Math.round()` 的增强方法。三个 `Math` 函数总是将输入调整为个位数，`decimalAdjust` 接受 `exp` 参数，该参数指定小数点左侧应该调整的位数。例如，`-1` 表示它将在小数点后留下一位数字（如 "× 10-1"）。此外，它还允许你通过 `type` 参数选择调整方式——`round`、`bottom` 或 `ceiling`。

它是这样做的：将数字乘以 10 的幂，然后四舍五入到最接近的整数，然后除以 10 的幂。为了更好地保持精度，它利用了数字的 `toString()` 方法，该方法使用科学记数法表示任意数字（如 `6.02e23`）。

```js
/\*\*
 \* Adjusts a number to the specified digit.
 \*
 \* @param {"round" | "floor" | "ceil"} type The type of adjustment.
 \* @param {number} value The number.
 \* @param {number} exp The exponent (the 10 logarithm of the adjustment base).
 \* @returns {number} The adjusted value.
 \*/
function decimalAdjust(type, value, exp) {
  type = String(type);
  if (!["round", "floor", "ceil"].includes(type)) {
    throw new TypeError(
      "The type of decimal adjustment must be one of 'round', 'floor', or 'ceil'.",
    );
  }
  exp = Number(exp);
  value = Number(value);
  if (exp % 1 !== 0 || Number.isNaN(value)) {
    return NaN;
  } else if (exp === 0) {
    return Math[type](value);
  }
  const [magnitude, exponent = 0] = value.toString().split("e");
  const adjustedValue = Math[type](`${magnitude}e${exponent - exp}`);
  // Shift back
  const [newMagnitude, newExponent = 0] = adjustedValue.toString().split("e");
  return Number(`${newMagnitude}e${+newExponent + exp}`);
}

// Decimal round
const round10 = (value, exp) => decimalAdjust("round", value, exp);
// Decimal floor
const floor10 = (value, exp) => decimalAdjust("floor", value, exp);
// Decimal ceil
const ceil10 = (value, exp) => decimalAdjust("ceil", value, exp);

// Round
round10(55.55, -1); // 55.6
round10(55.549, -1); // 55.5
round10(55, 1); // 60
round10(54.9, 1); // 50
round10(-55.55, -1); // -55.5
round10(-55.551, -1); // -55.6
round10(-55, 1); // -50
round10(-55.1, 1); // -60
// Floor
floor10(55.59, -1); // 55.5
floor10(59, 1); // 50
floor10(-55.51, -1); // -55.6
floor10(-51, 1); // -60
// Ceil
ceil10(55.51, -1); // 55.6
ceil10(51, 1); // 60
ceil10(-55.59, -1); // -55.5
ceil10(-59, 1); // -50
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.floor |

浏览器兼容性
------

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

参见
--

* `Math.abs()`
* `Math.ceil()`
* `Math.round()`
* `Math.sign()`
* `Math.trunc()`


Math.sign() - JavaScript

Math.sign()
===========

**`Math.sign()`** 函数返回一个数字的符号，指示数字是正数，负数还是零。

语法
--
```

Math.sign(x);
```

### 参数

`x`

任意数字。

描述
--

因为 `sign` 是 `Math` 的一个静态方法，所以你应该使用 Math.sign()，而不是作为你创建的一个 Math 对象的一种方法（Math 不是一个构造函数）。

而不是作为你创建的 Math 对象的一种方法（Math 不是构造函数）。

此函数共有 5 种返回值，分别是 **1, -1, 0, -0, NaN.** 代表的各是**正数，负数，正零，负零，NaN**。

传入该函数的参数会被**隐式转换**成数字类型。

示例
--

### 使用 Math.sign()

```js
Math.sign(3); // 1
Math.sign(-3); // -1
Math.sign("-3"); // -1
Math.sign(0); // 0
Math.sign(-0); // -0
Math.sign(NaN); // NaN
Math.sign("foo"); // NaN
Math.sign(); // NaN
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.sign |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Math.sign` 的 polyfill
* `Math.abs()`
* `Math.ceil()`
* `Math.floor()`
* `Math.round()`
* `Math.trunc()`


Math.atan2() - JavaScript

Math.atan2()
============

概述
--

**`Math.atan2()`** 返回从原点 (0,0) 到 (x,y) 点的线段与 x 轴正方向之间的平面角度 (弧度值)，也就是 Math.atan2(y,x)

语法
--
```

Math.atan2(y, x)
```

参数
--

`y, x`

数值

描述
--

`atan2` 方法返回一个 -pi 到 pi 之间的数值，表示点 (x, y) 对应的偏移角度。这是一个逆时针角度，以弧度为单位，正 X 轴和点 (x, y) 与原点连线 之间。注意此函数接受的参数：先传递 y 坐标，然后是 x 坐标。

`atan2` 接受单独的 x 和 y 参数，而 `atan` 接受两个参数的比值。

由于 `atan2` 是 `Math` 的静态方法，所以应该像这样使用：`Math.atan2()`，而不是作为你创建的 `Math` 实例的方法。

示例
--

### 示例：使用 `Math.atan2`

```js
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.
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.atan2 |

浏览器兼容性
------

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

参见
--

* `Math.acos()`
* `Math.asin()`
* `Math.atan()`
* `Math.cos()`
* `Math.sin()`
* `Math.tan()`


Math.clz32() - JavaScript

Math.clz32()
============

概述
--

**`Math.clz32()`** 函数返回一个数字在转换成 32 无符号整形数字的二进制形式后，开头的 0 的个数，比如 `1000000` 转换成 32 位无符号整形数字的二进制形式后是 `00000000000011110100001001000000`, 开头的 0 的个数是 12 个，则 `Math.clz32(1000000)` 返回 `12`.

语法
--
```

Math.clz32 (x)
```

### 参数

x

一个数字。

描述
--

"clz32" 是 CountLeadingZeroes32 的缩写。

如果 `x` 不是数字类型，则它首先会被转换成数字类型，然后再转成 32 位无符号整形数字。

如果转换后的 32 位无符号整形数字是 `0`, 则返回 `32`, 因为此时所有位上都是 `0`.

`NaN`, `Infinity`, `-Infinity` 这三个数字转成 32 位无符号整形数字后都是 `0`.

这个函数主要用于那些编译目标为 JS 语言的系统中，比如 Emscripten.

示例
--

```js
Math.clz32(1); // 31
Math.clz32(1000); // 22
Math.clz32(); // 32

const 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
```

计算前导 1 的个数
----------

目前 javascript 尚未提供 `Math.clon` 函数来计算前导 1 的个数（之所以叫“clon”而非“clo”，是因为“clo”与“clz”太过相似，特别对那些母语不是英语的人来说），但是你可以通过将一个数取反并将其作为 `Math.clz32` 的参数来实现 clon 函数。其中的原理非常简单，因为对 1 取反是 0，反之亦然，所以用 `Math.clz32` 计算前导 0 的个数就变成计算前导 1 的个数。

先看以下代码：

```js
const a = 32776; // 00000000000000001000000000001000（16 个前导 0）
Math.clz32(a); // 16

const b = ~32776; // 11111111111111110111111111110111（对 32776 取反，0 个前导 0）
Math.clz32(b); // 0（这与 a 中有多少个前导 0 等价）
```

通过以上方法，`clon` 函数可以定义如下：

```js
const clz = Math.clz32;

function clon(integer) {
  return clz(~integer);
}
```

现在，我们可以进一步实现计算“尾随 0”和“尾随 1”的个数了。下面的 `ctrz` 函数将第一个 1 之后的高数位全部置为 1 然后取反，再用 `Math.clz32` 求得尾随 0 的个数。

```js
var clz = Math.clz32;
function ctrz(integer) {
  // 计算尾随 0 个数
  // 1. 将第一个 1 之后的高数位全部置为 1
  // 00000000000000001000000000001000 => 11111111111111111111111111111000
  integer |= integer << 16;
  integer |= integer << 8;
  integer |= integer << 4;
  integer |= integer << 2;
  integer |= integer << 1;
  // 2. 然后，对该数取反，此时低位的 1 的个数即为所求
  return (32 - clz(~integer)) | 0; // `| 0` 用于保证结果为整数
}
function ctron(integer) {
  // 计算尾随 1 个数
  // JavaScript 中没有移位补 1 的运算符
  // 所以下面的代码是最快的
  return ctrz(~integer);
  /\* 为了看起来比较对称，你也可以使用以下代码：
 // 1. 将第一个 0 之后的高数位全部置为 0
 integer &= (integer << 16) | 0xffff;
 integer &= (integer << 8 ) | 0x00ff;
 integer &= (integer << 4 ) | 0x000f;
 integer &= (integer << 2 ) | 0x0003;
 integer &= (integer << 1 ) | 0x0001;
 // 2. 然后，对该数取反，此时低位的 0 的个数即为所求
 return 32 - clon(~integer) |0;
 \*/
}
```

将以上函数改写成 ASM.JS 模块——然后，你就可以去跟别人炫耀了！ASM.JS 就是用来干这个的。

```js
var countTrailsMethods = (function (stdlib, foreign, heap) {
  "use asm";
  var clz = stdlib.Math.clz32;
  function ctrz(integer) {
    // 计算尾随 0 个数
    integer = integer | 0; // 确保是整数
    // 1. 将第一个 1 之后的高数位全部置为 1
    // ASMjs 中不允许^=、&=、和 |=
    integer = integer | (integer << 16);
    integer = integer | (integer << 8);
    integer = integer | (integer << 4);
    integer = integer | (integer << 2);
    integer = integer | (integer << 1);
    // 2. 然后，对该数取反，此时低位的 1 的个数即为所求
    return (32 - clz(~integer)) | 0;
  }
  function ctron(integer) {
    // 计算尾随 1 个数
    integer = integer | 0; // 确保是整数
    return ctrz(~integer) | 0;
  }
  // 蛋疼的是，ASM.JS 必须使用糟糕的 object 类型：
  // unfourtunately, ASM.JS demands slow crummy objects:
  return { a: ctrz, b: ctron };
})(window, null, null);
var ctrz = countTrailsMethods.a;
var ctron = countTrailsMethods.b;
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.clz32 |

浏览器兼容性
------

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

参见
--

* `Math`
* `Math.imul`


Math.trunc() - JavaScript

Math.trunc()
============

**`Math.trunc()`** 方法会将数字的小数部分去掉，只保留整数部分。

语法
--
```

Math.trunc(value)
```

### 参数

`value`

任意数字

### 返回值

给定数字的整数部分

描述
--

不像 `Math` 的其他三个方法： `Math.floor()`、`Math.ceil()`、`Math.round()` ，`Math.trunc()` 的执行逻辑很简单，仅仅是**删除**掉数字的小数部分和小数点，不管参数是正数还是负数。

传入该方法的参数会被隐式转换成数字类型。

因为 `trunc()` 是 `Math` 对象的静态方法，你必须用 `Math.trunc()` 来使用，而不是调用你创建的 `Math` 对象的一个实例方法（`Math` 没有构造函数）

示例
--

```js
Math.trunc(13.37); // 13
Math.trunc(42.84); // 42
Math.trunc(0.123); // 0
Math.trunc(-0.123); // -0
Math.trunc("-1.123"); // -1
Math.trunc(NaN); // NaN
Math.trunc("foo"); // NaN
Math.trunc(); // NaN
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.trunc |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Math.trunc` 的 polyfill
* `Math.abs()`
* `Math.ceil()`
* `Math.floor()`
* `Math.round()`
* `Math.sign()`


Math.exp() - JavaScript

Math.exp()
==========

概述
--

**`Math.exp()`** 函数返回 `e^x`，`x` 表示参数，`e` 是欧拉常数（Euler's constant），自然对数的底数。

语法
--

```js
Math.exp(x)
```

### 参数

`x`

一个数值

描述
--

由于 `exp` 是 `Math` 的静态方法，所以应该像这样使用：`Math.exp()`，而不是作为你创建的 `Math` 实例的方法。

示例
--

### 示例：使用 `Math.exp`

```js
Math.exp(-1); // 0.36787944117144233
Math.exp(0); // 1
Math.exp(1); // 2.718281828459045
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.exp |

浏览器兼容性
------

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

参见
--

* `Math.E`
* `Math.expm1()`
* `Math.log()`
* `Math.log10()`
* `Math.log1p()`
* `Math.log2()`
* `Math.pow()`


Math.LN10 - JavaScript

Math.LN10
=========

概述
--

**`Math.LN10`** 属性表示 10 的自然对数，约为 2.302：

Math.LN10

=
ln
(
10
)
≈
2.302

\mathtt{\mi{Math.LN10}} = \ln(10) \approx 2.302

| `Math.LN10` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

由于 `LN10` 是 `Math` 的静态属性，所以应该像这样使用：`Math.LN10`，而不是作为你创建的 `Math` 实例的属性（`Math` 不是构造函数）。

示例
--

### 示例：使用 `Math.LN10`

下面的函数返回 10 的自然对数：

```js
function getNatLog10() {
  return Math.LN10;
}

getNatLog10(); // 2.302585092994046
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.ln10 |

浏览器兼容性
------

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

参见
--

* `Math.exp()`
* `Math.log()`
* `Math.log10()`


Math.pow() - JavaScript

Math.pow()
==========

**`Math.pow()`** 函数返回基数（`base`）的指数（`exponent`）次幂，即 `base^exponent`。

尝试一下
----

语法
--
```

Math.pow(base, exponent)
```

### 参数

`base`

基数

`exponent`

指数

描述
--

由于 `pow` 是 `Math` 的静态方法，所以应该像这样使用：`Math.pow()`，而不是作为你创建的 `Math` 对象的方法。

示例
--

### 使用 `Math.pow`

```js
function raisePower(x, y) {
  return Math.pow(x, y);
}
```

如果 `x` 是 2，且 `y` 是 7，则 raisePower 函数返回 128（2 的 7 次幂）。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.pow |

浏览器兼容性
------

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

参见
--

* `Math.cbrt()`
* `Math.exp()`
* `Math.log()`
* `Math.sqrt()`
* 乘方（`**`）


Math.fround() - JavaScript

Math.fround()
=============

概述
--

**`Math.fround()`** 可以将任意的数字转换为离它最近的单精度浮点数形式的数字。

语法
--

```js
Math.fround(doubleFloat)
```

### 参数

`doubleFloat`

一个 `Number`。若参数为非数字类型，则会被转投成数字。无法转换时，设置成`NaN`。

### 返回值

指定数字最接近的 32 位单精度浮点数表示。

描述
--

JavaScript 内部使用 64 位的双浮点数字，支持很高的精度。但是，有时你需要用 32 位浮点数字，比如你从一个`Float32Array` 读取值时。这时会产生混乱：检查一个 64 位浮点数和一个 32 位浮点数是否相等会失败，即使二个数字几乎一模一样。

要解决这个问题，可以使用 `Math.fround()` 来将 64 位的浮点数转换为 32 位浮点数。在内部，JavaScript 继续把这个数字作为 64 位浮点数看待，仅仅是在尾数部分的第 23 位执行了“舍入到偶数”的操作，并将后续的尾数位设置为 0。如果数字超出 32 位浮点数的范围，则返回 `Infinity` 或 `-Infinity`。

因为`fround()` 是`Math` 的静态方法，你必须通过 `Math.fround()` 来使用，而不是调用你创建的`Math` 对象的一个实例方法（`Math`不是一个构造函数）。

示例
--

### 使用 Math.fround()

数字 1.5 可以在二进制数字系统中精确表示，32 位和 64 位的值相同：

```js
Math.fround(1.5); // 1.5
Math.fround(1.5) === 1.5; // true
```

但是，数字 1.337 却无法在二进制数字系统中精确表示，所以 32 位和 64 位的值是不同的：

```js
Math.fround(1.337); // 1.3370000123977661
Math.fround(1.337) === 1.337; // false
```

2^150 超出 32 位浮点，所以返回`Infinity`：

```js
2 \*\* 150; // 1.42724769270596e+45
Math.fround(2 \*\* 150); // Infinity
```

如果参数无法转换成数字，或者为 `NaN`（`NaN`），`Math.fround()` 会返回 `NaN`：

```js
Math.fround("abc"); // NaN
Math.fround(NaN); // NaN
```

在某些精度不高的场合下，可以通过将二个浮点数转换成 32 位浮点数进行比较，以解决 64 位浮点数比较结果不正确的问题：

```js
0.1 + 0.2 == 0.3; //false

function equal(v1, v2) {
  return Math.fround(v1) == Math.fround(v2);
}

equal(0.1 + 0.2, 0.3); //true
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.fround |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Math.fround` 的 polyfill
* `Math.round()`


Math.tan() - JavaScript

Math.tan()
==========

概述
--

**`Math.tan()`** 方法返回一个数值的正切值。

语法
--
```

Math.tan(x)
```

### 参数

`x`

一个数值，表示一个角（单位：弧度）。

描述
--

`tan` 方法返回一个数值，表示一个角的正切值。

由于 `tan` 是 `Math` 的静态方法，所以应该像这样使用 `Math.tan()`，而不是作为你创建的 `Math` 实例的方法。

示例
--

### 示例：使用 `Math.tan`

下面的函数返回变量 `x` 的正切值：

```js
function getTan(x) {
  return Math.tan(x);
}
```

由于 `Math.tan()` 函数接受弧度数值，但是通常使用度更方便，下面的函数可以接受以度为单位的数值，将其转为弧度，然后返回其正切值。

```js
function getTanDeg(deg) {
  var rad = (deg \* Math.PI) / 180;
  return Math.tan(rad);
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.tan |

浏览器兼容性
------

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


Math.PI - JavaScript

Math.PI
=======

概述
--

**`Math.PI`** 表示一个圆的周长与直径的比例，约为 3.14159：

Math.PI

=
π
≈
3.14159

\mathtt{\mi{Math.PI}} = \pi \approx 3.14159

| `Math.PI` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

由于 `PI` 是 `Math` 的静态属性，所以应该像这样使用：`Math.PI`，而不是作为你创建的 `Math` 实例的属性（`Math` 不是构造函数）。

示例
--

### 使用 `Math.PI`

下面的函数使用 Math.PI 计算给定半径的圆周长：

```js
function calculateCircumference(radius) {
  return 2 \* Math.PI \* radius;
}

calculateCircumference(1); // 6.283185307179586
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.pi |

浏览器兼容性
------

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

参见
--

* `Math`


Math.sin() - JavaScript

Math.sin()
==========

概述
--

**`Math.sin()`** 函数返回一个数值的正弦值。

语法
--
```

Math.sin(x)
```

### 参数

`x`

一个数值（以弧度为单位）。

描述
--

`sin` 方法返回一个 -1 到 1 之间的数值，表示给定角度（单位：弧度）的正弦值。

由于 `sin` 是 `Math` 的静态方法，所以应该像这样使用：`Math.sin()`，而不是作为你创建的 `Math` 实例的方法。

示例
--

### 示例：使用 `Math.sin`

```js
Math.sin(0); // 0
Math.sin(1); // 0.8414709848078965

Math.sin(Math.PI / 2); // 1
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.sin |

浏览器兼容性
------

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

参见
--

* `Math.acos()`
* `Math.asin()`
* `Math.atan()`
* `Math.atan2()`
* `Math.cos()`
* `Math.tan()`


Math.cbrt() - JavaScript

Math.cbrt()
===========

**`Math.cbrt()`** 函数返回任意数字的立方根。

语法
--
```

Math.cbrt(x)
```

### 参数

`x`

任意数字。

### 返回值

给定数字的立方根

描述
--

该方法为 Math 的静态方法，因此请直接通过 Math.cbrt() 方式调用。

而不是作为你创建的 Math 对象的方法 (Math 不是构造函数)。

cbrt 是 "cube root" 的缩写，意思是立方根。

示例
--

### 使用 Math.cbrt()

```js
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
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.cbrt |

浏览器兼容性
------

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

参见
--

* `Math.pow()`
* `Math.sqrt()`


Math.log() - JavaScript

Math.log()
==========

概述
--

**`Math.log()`** 函数返回一个数的自然对数，即：

∀
x
>
0
,

Math.log
(
x
)

=
ln
(
x
)
=
the unique

y

such that

e
y

=
x

\forall x > 0, \mathtt{\operatorname{Math.log}(x)} = \ln(x) = \text{the unique} ; y ; \text{such that} ; e^y = x

语法
--
```

Math.log(x)
```

### 参数

`x`

一个数字。

描述
--

如果指定的 `number` 为负数，则返回值为 `NaN`。

由于 `log` 是 `Math` 的静态方法，所以应该像这样使用：`Math.log()`，而不是作为你创建的 `Math` 对象的方法。

示例
--

### 示例 1:使用`Math.log`

下面的函数返回指定变量的自然对数：

```js
Math.log(-1); // NaN, out of range
Math.log(0); // -Infinity
Math.log(1); // 0
Math.log(10); // 2.302585092994046
```

### 示例 2：使用 `Math.log` 时基于不同的底数

下面的函数返回以 `x` 为底 `y` 的对数（即 logx y）：

```js
function getBaseLog(x, y) {
  return Math.log(y) / Math.log(x);
}
```

如果你运行 `getBaseLog(10, 1000)`，则会返回 `2.9999999999999996`，非常接近实际答案：3，原因是浮点数精度问题。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.log |

浏览器兼容性
------

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

参见
--

* `Math.exp()`
* `Math.log1p()`
* `Math.log10()`
* `Math.log2()`
* `Math.pow()`


Math.LOG2E - JavaScript

Math.LOG2E
==========

概述
--

**`Math.LOG2E`** 属性表示以 2 为底数，e 的对数，约为 1.442：

Math.LOG2E

=

log
2

(
e
)
≈
1.442

\mathtt{\mi{Math.LOG2E}} = \log\_2(e) \approx 1.442

| `Math.LOG2E` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

由于 `LOG2E` 是 `Math` 的静态属性，所以应该像这样使用：`Math.LOG2E`，而不是作为你创建的 `Math` 对象的属性（`Math` 不是一个构造函数）。

示例
--

### 示例：使用 `Math.LOG2E`

下面的函数返回以 2 为底数，E 的对数：

```js
function getLog2e() {
  return Math.LOG2E;
}

getLog2e(); // 1.4426950408889634
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.log2e |

浏览器兼容性
------

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

参见
--

* `Math.exp()`
* `Math.log()`
* `Math.log2()`


Math.LOG10E - JavaScript

Math.LOG10E
===========

概述
--

**`Math.LOG10E`** 属性表示以 10 为底数，e 的对数，约为 0.434：

Math.LOG10E

=

log
10

(
e
)
≈
0.434

\mathtt{\mi{Math.LOG10E}} = \log\_10(e) \approx 0.434

| `Math.LOG10E` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

由于 `LOG10E` 是 `Math` 的静态属性，所以应该像这样使用：`Math.LOG10E`，而不是作为你创建的 `Math` 实例的属性（`Math` 不是一个构造函数）。

示例
--

### 示例：使用 `Math.LOG10E`

下面的函数返回以 10 为底数，E 的对数：

```js
function getLog10e() {
  return Math.LOG10E;
}

getLog10e(); // 0.4342944819032518
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.log10e |

浏览器兼容性
------

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

参见
--

* `Math.exp()`
* `Math.log()`
* `Math.log10()`


Math.acos() - JavaScript

Math.acos()
===========

概述
--

**`Math.acos()`** 返回一个数的反余弦值（单位为弧度），即：

∀
x
∊
[

-
1

;
1
]
,

Math.acos
(
x
)

=
arccos
(
x
)
=
 the unique

y
∊
[
0
;
π
]

such that

cos
(
y
)
=
x

\forall x \in [{-1};1],;\mathtt{\operatorname{Math.acos}(x)} = \arccos(x) = \text{ the unique } ; y \in [0; \pi] , \text{such that} ; \cos(y) = x

语法
--
```

Math.acos(x)
```

参数
--

`x`

一个数值

描述
--

`acos` 方法以 -1 到 1 的一个数为参数，返回一个 0 到 pi（弧度）的数值。如果传入的参数值超出了限定的范围，将返回 `NaN`。

由于 `acos` 是 `Math` 的静态方法，所以应该像这样使用：`Math.acos()`，而不是作为你创建的 `Math` 实例的属性（`Math` 不是一个构造函数）。

示例
--

### 示例：使用 `Math.acos`

```js
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
```

对于小于 -1 或大于 1 的值，`Math.acos` 返回 `NaN`。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.acos |

浏览器兼容性
------

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

参见
--

* `Math.asin()`
* `Math.atan()`
* `Math.atan2()`
* `Math.cos()`
* `Math.sin()`
* `Math.tan()`


Math.cos() - JavaScript

Math.cos()
==========

概述
--

**`Math.cos()`** 函数返回一个数值的余弦值。

语法
--
```

Math.cos(x)
```

### 参数

`x`

一个以弧度为单位的数值。

描述
--

`cos` 方法返回一个 -1 到 1 之间的数值，表示角度（单位：弧度）的余弦值。

由于 `cos` 是 `Math` 的静态方法，所以应该像这样使用：`Math.cos()`，而不是作为你创建的 `Math` 实例的方法。

示例
--

### 示例：使用 `Math.cos`

```js
Math.cos(0); // 1
Math.cos(1); // 0.5403023058681398

Math.cos(Math.PI); // -1
Math.cos(2 \* Math.PI); // 1
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.cos |

浏览器兼容性
------

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

参见
--

* `Math.acos()`
* `Math.asin()`
* `Math.atan()`
* `Math.atan2()`
* `Math.sin()`
* `Math.tan()`


Math.abs() - JavaScript

Math.abs()
==========

**`Math.abs(x)`** 函数返回一个数字的绝对值。

尝试一下
----

语法
--

```js
Math.abs(x)
```

### 参数

`x`

一个数字。

### 返回值

`x` 的绝对值。如果 `x` 是负数（包括 `-0`），则返回 `-x`。否则，返回 `x`。

描述
--

由于 `abs()` 是 `Math` 中的一个静态方法，所以你应该通过 `Math.abs()` 调用，而不是作为你创建的 `Math` 对象的方法（`Math` 不是构造器）。

示例
--

### 使用 Math.abs()

```js
Math.abs(-Infinity); // Infinity
Math.abs(-1); // 1
Math.abs(-0); // 0
Math.abs(0); // 0
Math.abs(1); // 1
Math.abs(Infinity); // Infinity
```

### 强制转换参数

`Math.abs()` 将其参数强制转换为数字。无法强制转换的值将变成 `NaN`，使 `Math.abs()` 也返回 `NaN`。

```js
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
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.abs |

浏览器兼容性
------

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

参见
--

* `Math.ceil()`
* `Math.floor()`
* `Math.round()`
* `Math.sign()`
* `Math.trunc()`


Math.round() - JavaScript

Math.round()
============

**`Math.round()`** 函数返回一个数字四舍五入后最接近的整数。

语法
--
```

Math.round(x)
```

### 参数

`x`

一个数值。

### 返回值

给定数字的值四舍五入到最接近的整数。

描述
--

如果参数的小数部分大于 0.5，则舍入到相邻的绝对值更大的整数。如果参数的小数部分小于 0.5，则舍入到相邻的绝对值更小的整数。如果参数的小数部分恰好等于 0.5，则舍入到相邻的在正无穷（+∞）方向上的整数。**注意，与很多其他语言中的`round()` 函数不同，`Math.round()` 并不总是舍入到远离 0 的方向（尤其是在负数的小数部分恰好等于 0.5 的情况下）。**

因为 `round()` 是 `Math` 的静态方法，你应该直接使用 `Math.round()`，而不是作为你创建的 `Math` 对象的一个实例方法来使用（`Math`没有构造函数）。

示例
--

```js
x = Math.round(20.49); //20
x = Math.round(20.5); //21
x = Math.round(-20.5); //-20
x = Math.round(-20.51); //-21
```

### 小数舍入

```js
// 闭包
(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
Math.round10(1.005, -2); // 1.01 -- compare this with Math.round(1.005\*100)/100 above
// 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
```

或：

```js
function round(number, precision) {
  return Math.round(+number + "e" + precision) / Math.pow(10, precision);
  //same as:
  //return Number(Math.round(+number + 'e' + precision) + 'e-' + precision);
}

round(1.005, 2); //1.01
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.round |

浏览器兼容性
------

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

参见
--

* `Math.abs()`
* `Math.ceil()`
* `Math.floor()`


Math.asin() - JavaScript

Math.asin()
===========

概述
--

**`Math.asin()`** 方法返回一个数值的反正弦（单位为弧度），即：

∀
x
∊
[

-
1

;
1
]
,

Math.asin
(
x
)

=
arcsin
(
x
)
=
 the unique

y
∊

[

-

π
2

;

π
2

]

such that

sin
(
y
)
=
x

\forall x \in [{-1};1],;\mathtt{\operatorname{Math.asin}(x)} = \arcsin(x) = \text{ the unique } ; y \in \left[-\frac{\pi}{2}; \frac{\pi}{2}\right] , \text{such that} ; \sin(y) = x

语法
--
```

Math.asin(x)
```

### 参数

`x`

一个数值

描述
--

`asin` 方法接受 -1 到 1 之间的数值作为参数，返回一个介于

-

π
2

-\frac{\pi}{2}

 到

π
2

\frac{\pi}{2}

 弧度的数值。如果接受的参数值超出范围，则返回 `NaN`。

由于 `asin` 是 `Math` 的静态方法，所有应该像这样使用：`Math.asin()`，而不是作为你创建的 `Math` 实例的方法。

示例
--

### 示例：使用 `Math.asin()`

```js
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
```

对于小于 -1 或大于 1 的参数值，`Math.asin` 返回 `NaN`。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.asin |

浏览器兼容性
------

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

参见
--

* `Math.acos()`
* `Math.atan()`
* `Math.atan2()`
* `Math.cos()`
* `Math.sin()`
* `Math.tan()`


Math.imul() - JavaScript

Math.imul()
===========

该函数将两个参数分别转换为 32 位整数，相乘后返回 32 位结果，类似 C 语言的 32 位整数相乘。

尝试一下
----

语法
--
```

var product = Math.imul(a, b)
```

### 参数

`a`

被乘数。

`b`

乘数。

### 返回值

类似 C 语言 32 位整数相乘的结果。

描述
--

`Math.imul()` 可以进行类似 C 语言的 32 位整数相乘。该特性对于一些项目比如 Emscripten 很有用。因为 `imul()` 是 `Math` 的静态方法，所以用法是 `Math.imul()`，而不是新创建的 `Math` 对象的方法 (`Math` 不是构造函数)。如果使用 JavaScript 浮点数做为 `imul` 的参数，会有性能损失。这是因为相乘前 imul 会将浮点数转换为整数，相乘后会将整数重新转换为浮点数，这两步转换的开销是比较大的。imul 存在的原因是在 AsmJS(目前为止唯一一种环境) 下它是快速的。AsmJS 使 JIST-optimizers 更容易实现 JavaScript 内部的整数。现代浏览器中，唯一能体现出 imul 性能优越的场景是两个 Number 内部以整数的形式相乘 (仅在 AsmJS 下可行)。

示例
--

```js
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
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.imul |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Math.imul` 的 Polyfill
* 维基百科上的 Emscripten 词条


Math.atan() - JavaScript

Math.atan()
===========

概述
--

**`Math.atan()`** 函数返回一个数值的反正切（以弧度为单位），即：

Math.atan
(
x
)

=
arctan
(
x
)
=
 the unique

y
∊

[

-

π
2

;

π
2

]

such that

tan
(
y
)
=
x

\mathtt{\operatorname{Math.atan}(x)} = \arctan(x) = \text{ the unique } ; y \in \left[-\frac{\pi}{2}; \frac{\pi}{2}\right] , \text{such that} ; \tan(y) = x

语法
--
```

Math.atan(x)
```

### 参数

`x`

一个数值

描述
--

`atan` 返回一个

-

π
2

-\frac{\pi}{2}

 到

π
2

\frac{\pi}{2}

 弧度之间的数值。

由于 `atan` 是 `Math` 的静态方法，所以应该像这样使用：`Math.atan()`，而不是作为你创建的 `Math` 实例的方法。

示例
--

### 示例：使用 `Math.atan`

```js
Math.atan(1); // 0.7853981633974483
Math.atan(0); // 0
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.atan |

浏览器兼容性
------

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

参见
--

* `Math.acos()`
* `Math.asin()`
* `Math.atan2()`
* `Math.cos()`
* `Math.sin()`
* `Math.tan()`


Math.random() - JavaScript

Math.random()
=============

**`Math.random()`** 函数返回一个浮点数，伪随机数在范围从**0 到**小于**1**，也就是说，从 0（包括 0）往上，但是不包括 1（排除 1），然后你可以缩放到所需的范围。实现将初始种子选择到随机数生成算法;它不能被用户选择或重置。尝试一下
----

**备注：** `Math.random()` *不能*提供像密码一样安全的随机数字。不要使用它们来处理有关安全的事情。使用 Web Crypto API 来代替，和更精确的`window.crypto.getRandomValues()` 方法。

语法
--
```

Math.random()
```

### 返回值

一个浮点型伪随机数字，在`0`（包括 0）和`1`（不包括）之间。

示例
--

请注意，由于 JavaScript 中的数字是 IEEE 754 浮点数字，具有最近舍入（round-to-nearest-even）的行为，因此以下函数的范围 (不包括`Math.random()` 本身) 并不准确。如果选择了非常大的边界 (2^53 或更高), 在极罕见的情况下会计算通常 - 排除（usually-excluded）的上界。（注：round-to-nearest-even 采用最近舍入的去偶数舍入的方式，对.5 的舍入上，采用取偶数的方式）

### 得到一个大于等于 0，小于 1 之间的随机数

```js
function getRandom() {
  return Math.random();
}
```

### 得到一个两数之间的随机数

这个例子返回了一个在指定值之间的随机数。这个值不小于 `min`（有可能等于），并且小于（不等于）`max`。

```js
function getRandomArbitrary(min, max) {
  return Math.random() \* (max - min) + min;
}
```

### 得到一个两数之间的随机整数

这个例子返回了一个在指定值之间的随机整数。这个值不小于 `min` （如果 `min` 不是整数，则不小于 `min` 的向上取整数），且小于（不等于）`max`。

```js
function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() \* (max - min)) + min; //不含最大值，含最小值
}
```

**备注：** 也许很容易想到用 `Math.round()` 来实现，但是这会导致你的随机数处于一个不均匀的分布，这可能不符合你的需求。

### 得到一个两数之间的随机整数，包括两个数在内

上一个例子提到的函数 `getRandomInt()` 结果范围包含了最小值，但不含最大值。如果你的随机结果需要同时包含最小值和最大值，怎么办呢？`getRandomIntInclusive()` 函数可以实现。

```js
function getRandomIntInclusive(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() \* (max - min + 1)) + min; //含最大值，含最小值
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.random |

浏览器兼容性
------

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

参见
--

* `window.crypto.getRandomValues()`


Math.log10() - JavaScript

Math.log10()
============

概述
--

**`Math.log10()`** 函数返回一个数字以 10 为底的对数。

语法
--
```

Math.log10(x)
```

### 参数

`x`

任意数字。

描述
--

如果传入的参数小于 0，则返回 NaN.

示例
--

```js
Math.log10(10); // 1
Math.log10(100); // 2
Math.log10("100"); // 2
Math.log10(1); // 0
Math.log10(0); // -Infinity
Math.log10(-2); // NaN
Math.log10("foo"); // NaN
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.log10 |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Math.log10` 的 polyfill
* `Math.exp()`
* `Math.log()`
* `Math.log1p()`
* `Math.log2()`
* `Math.pow()`


Math.acosh() - JavaScript

Math.acosh()
============

**`Math.acosh()`** 函数返回一个数的反双曲余弦值，即：

∀
x
≥
1
,

Math.acosh
(
x
)

=
arcosh
(
x
)
=
 the unique

y
≥
0

such that

cosh
(
y
)
=
x

\forall x \geq 1, \mathtt{\operatorname{Math.acosh}(x)} = \operatorname{arcosh}(x) = \text{ 唯一的} ; y \geq 0 ; \text{使得} ; \cosh(y) = x

尝试一下
----

语法
--

```js
Math.acosh(x)
```

### 参数

`x`

一个数字。

### 返回值

返回给定数的反双曲余弦值，如果该数小于 **1** 则返回 `NaN`。

描述
--

因为 `acosh()` 是 `Math` 的静态方法，所以你应该通过 `Math.acosh()` 调用，而不是作为你创建的 `Math` 对象的方法（`Math` 不是构造函数）。

示例
--

### 使用 `Math.acosh()`

```js
Math.acosh(-1); // NaN
Math.acosh(0); // NaN
Math.acosh(0.5); // NaN
Math.acosh(1); // 0
Math.acosh(2); // 1.3169578969248166
```

当参数小于 1 时，`Math.acosh()` 将返回 `NaN`。

向下兼容
----

当

x
≥
1

x \geq 1

 时，都有

arcosh
(
x
)
=
ln

(

x
+

x
2

-
1

)

\operatorname {arcosh} (x) = \ln \left(x + \sqrt{x^{2} - 1} \right)

 ，因此可以使用以下函数实现：

```js
Math.acosh =
  Math.acosh ||
  function (x) {
    return Math.log(x + Math.sqrt(x \* x - 1));
  };
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.acosh |

浏览器兼容性
------

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

参见
--

* `Math.asinh()`
* `Math.atanh()`
* `Math.cosh()`
* `Math.sinh()`
* `Math.tanh()`


Math.cosh() - JavaScript

Math.cosh()
===========

**`Math.cosh()`** 函数返回数值的双曲余弦函数，可用 constant e 表示：

Math.cosh(x)

=

e
x

+

e

-
x

2

\mathtt{\operatorname{Math.cosh(x)}} = \frac{e^x + e^{-x}}{2}

语法
--
```

Math.cosh(x)
```

### 参数

`x`

数值。

描述
--

由于 `cosh()` 是 Math 的静态函数，只需通过 `Math.cosh()` 调用，而不用通过创建 Math 对象来调用。

示例
--

### 使用 `Math.cosh()`

```js
Math.cosh(0); // 1
Math.cosh(1); // 1.5430806348152437
Math.cosh(-1); // 1.5430806348152437
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.cosh |

浏览器兼容性
------

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

参见
--

* `core-js` 中 `Math.cosh` 的 polyfill
* `Math.acosh()`
* `Math.asinh()`
* `Math.atanh()`
* `Math.sinh()`
* `Math.tanh()`


Math.max() - JavaScript

Math.max()
==========

**`Math.max()`** 函数返回作为输入参数的最大数字，如果没有参数，则返回 -`Infinity`。

尝试一下
----

语法
--

```js
Math.max()
Math.max(value0)
Math.max(value0, value1)
Math.max(value0, value1, /\* … ,\*/ valueN)
```

### 参数

`value1`, `value2`, … , `valueN`

0 个或多个数字，将在其中选择，并返回最大的值。

### 返回值

给定数值中最大的数。如果任一参数不能转换为数值，则返回 `NaN`。如果没有提供参数，返回 -`Infinity`。

描述
--

因为 `max()` 是 `Math` 的静态方法，所以你应始终使用 `Math.max()`，而不是作为你创建的 `Math` 对象的方法（`Math` 不是构造函数）。

`Math.max.length` 是 2，这从某种程度上表明了它旨在处理至少两个参数。

示例
--

### 使用 Math.max()

```js
Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20
```

### 获取数组的最大元素

`Array.prototype.reduce()` 可以用来查找最大值元素，通过比较每个值：

```js
const arr = [1, 2, 3];
const max = arr.reduce((a, b) => Math.max(a, b), -Infinity);
```

下面的方法使用 `Function.prototype.apply()` 来获取数组的最大值。`getMaxOfArray([1, 2, 3])` 相当于 `Math.max(1, 2, 3)`，但是你可以使用 `getMaxOfArray()` 作用于任意长度的数组上。这应该只用于元素相对较少的数组。

```js
function getMaxOfArray(numArray) {
  return Math.max.apply(null, numArray);
}
```

展开语法是编写 `apply` 解决方案的一种更简短的方法，可以最大限度地利用数组：

```js
const arr = [1, 2, 3];
const max = Math.max(...arr);
```

但是，如果数组有太多的元素，展开语法（`...`）和 `apply` 都将失败或返回错误的结果，因为它们试图将数组元素作为函数形参传递。参见使用 apply 和内置函数了解更多细节。`reduce` 解决方案不存在这个问题。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.max |

浏览器兼容性
------

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

参见
--

* `Math.min()`


Math.min() - JavaScript

Math.min()
==========

**`Math.min()`** 函数返回作为输入参数的数字中最小的一个，如果没有参数，则返回 `Infinity`。

尝试一下
----

语法
--

```js
Math.min()
Math.min(value0)
Math.min(value0, value1)
Math.min(value0, value1, /\* … ,\*/ valueN)
```

### 参数

`value1`, …, `valueN`

0 个或多个数字，将在其中选择，并返回最小值。

### 返回值

给定数值中最小的数。如果任一参数不能转换为数值，则返回 `NaN`。如果没有提供参数，返回 `Infinity`。

描述
--

因为 `min()` 是 `Math` 的静态方法，所以你应始终使用 `Math.min()`，而不是作为你创建的 `Math` 对象的方法（`Math` 不是构造函数）。

`Math.min.length` 是 2，这从某种程度上表明了它旨在处理至少两个参数。

示例
--

### 使用 Math.min()

下例找出 `x` 和 `y` 的最小值，并把它赋值给 `z`：

```js
const x = 10;
const y = -20;
const z = Math.min(x, y); // -20
```

### 使用 Math.min() 裁剪值

`Math.min()` 经常用于裁剪一个值，以便使其总是小于或等于某个边界值。例如：

```js
let x = f(foo);

if (x > boundary) {
  x = boundary;
}
```

可以写成：

```js
const x = Math.min(f(foo), boundary);
```

`Math.max()` 可以以类似的方式用于在另一端裁剪一个值。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.min |

浏览器兼容性
------

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

参见
--

* `Math.max()`


Math.sqrt() - JavaScript

Math.sqrt()
===========

**`Math.sqrt()`** 函数返回一个数的平方根，即：

∀
x
≥
0
,

M
a
t
h
.
s
q
r
t
(
x
)

=

x

=
the unique

y
≥
0

such that

y
2

=
x

\forall x \geq 0, \mathtt{Math.sqrt(x)} = \sqrt{x} = \text{the unique} ; y \geq 0 ; \text{such that} ; y^2 = x

尝试一下
----

语法
--
```

Math.sqrt(x)
```

### 参数

`x`

一个数值

描述
--

如果参数 `number` 为负值，则 `sqrt` 返回`NaN`。

由于 `sqrt` 是 `Math` 的静态方法，所以应该像这样使用：`Math.sqrt()`，而不是作为你创建的 `Math` 实例的方法。

示例
--

### 使用 `Math.sqrt`
```

Math.sqrt(9); // 3
Math.sqrt(2); // 1.414213562373095

Math.sqrt(1);  // 1
Math.sqrt(0);  // 0
Math.sqrt(-1); // NaN
Math.sqrt(-0); // -0
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-math.sqrt |

浏览器兼容性
------

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

参见
--

* `Math.cbrt()`
* `Math.exp()`
* `Math.log()`
* `Math.pow()`


Atomics.isLockFree() - JavaScript

Atomics.isLockFree()
====================

**`Atomics.isLockFree()`** 静态方法用于判断 `Atomics` 在将具有给定字节大小的元素应用于类型化数组时是否会使用锁或原子硬件操作。如果给定的大小不是整数类型化数组类型的 BYTES\_PER\_ELEMENT 属性之一，则返回 `false`。

尝试一下
----

语法
--

```js
Atomics.isLockFree(size)
```

### 参数

`size`

要检查的大小（以字节为单位）。

### 返回值

`true` 或 `false`，指示操作字节是否不涉及锁。

示例
--

### 使用 isLockFree()

```js
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
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-atomics.islockfree |

浏览器兼容性
------

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

参见
--

* `Atomics`


Atomics.load() - JavaScript

Atomics.load()
==============

**`Atomics.load()`** 静态方法返回数组中指定位置的值。

尝试一下
----

语法
--

```js
Atomics.load(typedArray, index)
```

### 参数

`typedArray`

一个整数类型数组。`Int8Array`、`Uint8Array`、`Int16Array`、`Uint16Array`、`Int32Array`、`Uint32Array`、`BigInt64Array` 或 `BigUint64Array` (en-US) 之一。

`index`

`typedArray` 中的要加载的位置。

### 返回值

给定位置的值（`typedArray[index]`）。

### 异常

`TypeError`

如果 `typedArray` 不是允许的整数类型数组之一，则抛出该异常。

`RangeError`

如果 `index` 超出 `typedArray` 的范围，则抛出该异常。

示例
--

### 使用 load()

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

Atomics.add(ta, 0, 12);
Atomics.load(ta, 0); // 12
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-atomics.load |

浏览器兼容性
------

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

参阅
--

* `Atomics`
* `Atomics.store()`


Atomics.add() - JavaScript

Atomics.add()
=============

**`Atomics.add()`** 静态方法会将给定的值加到数组里的指定位置上，并返回该位置的旧值。此原子操作保证在修改后的值写回之前不会发生其他写操作。

尝试一下
----

语法
--

```js
Atomics.add(typedArray, index, value)
```

### 参数

`typedArray`

一个整数类型数组。`Int8Array`、`Uint8Array`、`Int16Array`、`Uint16Array`、`Int32Array`、`Uint32Array`、`BigInt64Array` 或 `BigUint64Array` (en-US) 之一。

`index`

`typedArray` 中的要加上 `value` 的位置。

`value`

要增加的数字。

### 返回值

给定位置的旧值（`typedArray[index]`）。

### 异常

`TypeError`

如果 `typedArray` 不是允许的整数类型数组之一，则抛出该异常。

`RangeError`

如果 `index` 超出 `typedArray` 的范围，则抛出该异常。

示例
--

### 使用 add()

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

Atomics.add(ta, 0, 12); // 返回 0，即旧的值
Atomics.load(ta, 0); // 12
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-atomics.add |

浏览器兼容性
------

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

参见
--

* `Atomics`
* `Atomics.sub()`


Atomics.waitAsync() - JavaScript

Atomics.waitAsync()
===================

**`Atomics.waitAsync()`** 静态方法异步等待共享内存的特定位置并返回一个 `Promise`。

与 `Atomics.wait()` 不同，`waitAsync` 是非阻塞的且可用于主线程。

**备注：** 此操作仅适用于基于 `SharedArrayBuffer` 的 `Int32Array` 或 `BigInt64Array` 视图。

语法
--

```js
Atomics.waitAsync(typedArray, index, value)
Atomics.waitAsync(typedArray, index, value, timeout)
```

### 参数

`typedArray`

基于 `SharedArrayBuffer` 的 `Int32Array` 或 `BigInt64Array`。

`index`

`typedArray` 中要等待的位置。

`value`

要测试的期望值。

`timeout` 可选

等待时间，以毫秒为单位。`NaN`（以及会被转换为 `NaN` 的值，例如 `undefined`）会被转换为 `Infinity`。负值会被转换为 `0`。

### 返回值

一个 `Object`，包含以下属性：

`async`

一个布尔值，指示 `value` 属性是否为 `Promise`。

`value`

如果 `async` 是 `false`，它将是一个内容为 `"not-equal"` 或 `"timed-out"` 的字符串（仅当 `timeout` 参数为 `0` 时）。如果 `async` 是 `true`，它将会是一个 `Promise`，其兑现值为一个内容为 `"ok"` 或 `"timed-out"` 的字符串。这个 promise 永远不会被拒绝。

### 异常

`TypeError`

如果 `typedArray` 不是一个基于 `SharedArrayBuffer` 的 `Int32Array` 或 `BigInt64Array`，则抛出该异常。

`RangeError`

如果 `index` 超出 `typedArray` 的范围，则抛出该异常。

示例
--

### 使用 waitAsync()

给定一个共享的 `Int32Array`。

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

令一个读取线程休眠并在位置 0 处等待，预期该位置的值为 0。`result.value` 将是一个 promise。

```js
const result = Atomics.waitAsync(int32, 0, 0, 1000);
// { async: true, value: Promise {<pending>} }
```

在该读取线程或另一个线程中，对内存位置 0 调用以令该 promise 解决为 `"ok"`。

```js
Atomics.notify(int32, 0);
// { async: true, value: Promise {<fulfilled>: 'ok'} }
```

如果它没有解决为 `"ok"`，则共享内存该位置的值不符合预期（`value` 将是 `"not-equal"` 而不是一个 promise）或已经超时（该 promise 将解决为 `"time-out"`）。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-atomics.waitasync |

浏览器兼容性
------

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

参见
--

* `Atomics`
* `Atomics.wait()`
* `Atomics.notify()`


Atomics.exchange() - JavaScript

Atomics.exchange()
==================

**`Atomics.exchange()`** 静态方法会将给定的值替换数组上指定位置的值，并返回该位置的旧值。此原子操作保证在修改后的值写回之前不会发生其他写操作。

尝试一下
----

语法
--

```js
Atomics.exchange(typedArray, index, value)
```

### 参数

`typedArray`

一个整数类型数组。`Int8Array`、`Uint8Array`、`Int16Array`、`Uint16Array`、`Int32Array`、`Uint32Array`、`BigInt64Array` 或 `BigUint64Array` (en-US) 之一。

`index`

`typedArray` 中的要替换为 `value` 的位置。

`value`

要替换的数字。

### 返回值

给定位置的旧值（`typedArray[index]`）。

### 异常

`TypeError`

如果 `typedArray` 不是允许的整数类型数组之一，则抛出该异常。

`RangeError`

如果 `index` 超出 `typedArray` 的范围，则抛出该异常。

示例
--

### 使用 exchange()

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

Atomics.exchange(ta, 0, 12); // 返回 0，即旧的值
Atomics.load(ta, 0); // 12
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-atomics.exchange |

浏览器兼容性
------

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

参见
--

* `Atomics`
* `Atomics.compareExchange()`


Atomics.notify() - JavaScript

Atomics.notify()
================

**`Atomics.notify()`** 静态方法唤醒一些在等待队列中休眠的代理。

**备注：** 此操作仅适用于基于 `SharedArrayBuffer` 的 `Int32Array` 或 `BigInt64Array` 视图。对于非共享的 `ArrayBuffer` 对象，其将返回 `0`。

语法
--

```js
Atomics.notify(typedArray, index, count)
```

### 参数

`typedArray`

基于 `SharedArrayBuffer` 的 `Int32Array` 或 `BigInt64Array`。

`index`

`typedArray` 中要唤醒的位置。

`count` 可选

要唤醒的休眠代理的数量。默认为 `Infinity`。

### 返回值

* 返回唤醒的代理数量。
* 如果在非共享的 `ArrayBuffer` 上调用则返回 `0`。
### 异常

`TypeError`

如果 `typedArray` 不是一个基于 `SharedArrayBuffer` 的 `Int32Array` 或 `BigInt64Array`，则抛出该异常。

`RangeError`

如果 `index` 超出 `typedArray` 的范围，则抛出该异常。

示例
--

### 使用 notify()

给定一个共享的 `Int32Array`：

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

令一个读取线程休眠并在位置 0 处等待，预期该位置的值为 0。只要条件一直为真，则将不会继续运行。然而，一旦写入线程存储了一个新的值，它将被读取线程唤醒并返回新的值（123）。

```js
Atomics.wait(int32, 0, 0);
console.log(int32[0]); // 123
```

写入线程存储一个新的值并在写入后唤醒等待的线程：

```js
console.log(int32[0]); // 0;
Atomics.store(int32, 0, 123);
Atomics.notify(int32, 0, 1);
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-atomics.notify |

浏览器兼容性
------

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

参见
--

* `Atomics`
* `Atomics.wait()`
* `Atomics.waitAsync()`


Atomics.compareExchange() - JavaScript

Atomics.compareExchange()
=========================

如果给定的预期值等于旧值，**`Atomics.exchange()`** 静态方法会用给定的值替换数组上指定位置的值，并返回该位置的旧值，无论其是否等于预期的值。此原子操作保证在修改后的值写回之前不会发生其他写操作。

尝试一下
----

语法
--

```js
Atomics.compareExchange(typedArray, index, expectedValue, replacementValue)
```

### 参数

`typedArray`

一个整数类型数组。`Int8Array`、`Uint8Array`、`Int16Array`、`Uint16Array`、`Int32Array`、`Uint32Array`、`BigInt64Array` 或 `BigUint64Array` (en-US) 之一。

`index`

`typedArray` 中的要替换为 `replacementValue` 的位置。

`expectedValue`

用于检查相等性的值。

`replacementValue`

要替换的值。

### 返回值

给定位置的旧值（`typedArray[index]`）。

### 异常

`TypeError`

如果 `typedArray` 不是允许的整数类型数组之一，则抛出该异常。

`RangeError`

如果 `index` 超出 `typedArray` 的范围，则抛出该异常。

示例
--

### 使用 compareExchange()

```js
const sab = new SharedArrayBuffer(1024);
const ta = new Uint8Array(sab);
ta[0] = 7;

Atomics.compareExchange(ta, 0, 7, 12); // 返回 7，即旧的值
Atomics.load(ta, 0); // 12
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-atomics.compareexchange |

浏览器兼容性
------

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

参见
--

* `Atomics`
* `Atomics.exchange()`


Atomics.and() - JavaScript

Atomics.and()
=============

**`Atomics.and()`** 静态方法会将给定的值与数组指定位置上的值进行按位与运算，并返回该位置的旧值。此原子操作保证在修改后的值写回之前不会发生其他写操作。

尝试一下
----

语法
--

```js
Atomics.and(typedArray, index, value)
```

### 参数

`typedArray`

一个整数类型数组。`Int8Array`、`Uint8Array`、`Int16Array`、`Uint16Array`、`Int32Array`、`Uint32Array`、`BigInt64Array` 或 `BigUint64Array` (en-US) 之一。

`index`

`typedArray` 中要进行按位与运算的位置。

`value`

要进行按位与运算的值。

### 返回值

给定位置的旧值（`typedArray[index]`）。

### 异常

`TypeError`

如果 `typedArray` 不是允许的整数类型数组之一，则抛出该异常。

`RangeError`

如果 `index` 超出 `typedArray` 的范围，则抛出该异常。

描述
--

当且仅当 `a` 和 `b` 都为 1 时，按位与运算结果为 1。与运算的真值表如下：

| `a` | `b` | `a & b` |
| --- | --- | --- |
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |

例如，`5 & 1` 按位与运算的结果是 `0001`，也就是十进制的 1。
```

5  0101
1  0001
   ----

1  0001
```

示例
--

### 使用 and()

```js
const sab = new SharedArrayBuffer(1024);
const ta = new Uint8Array(sab);
ta[0] = 5;

Atomics.and(ta, 0, 1); // 返回 5，即旧的值
Atomics.load(ta, 0); // 1
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-atomics.and |

浏览器兼容性
------

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

参见
--

* `Atomics`
* `Atomics.or()`
* `Atomics.xor()`


Atomics.store() - JavaScript

Atomics.store()
===============

**`Atomics.store()`** 静态方法将给定的值存储在数组中的指定位置，并返回该值。

尝试一下
----

语法
--

```js
Atomics.store(typedArray, index, value)
```

### 参数

`typedArray`

一个整数类型数组。`Int8Array`、`Uint8Array`、`Int16Array`、`Uint16Array`、`Int32Array`、`Uint32Array`、`BigInt64Array` 或 `BigUint64Array` (en-US) 之一。

`index`

`typedArray` 中的要存储 `value` 的位置。

`value`

要存储的数字。

### 返回值

已存储的值。

### 异常

`TypeError`

如果 `typedArray` 不是允许的整数类型数组之一，则抛出该异常。

`RangeError`

如果 `index` 超出 `typedArray` 的范围，则抛出该异常。

示例
--

### 使用 store()

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

Atomics.store(ta, 0, 12); // 12
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-atomics.store |

浏览器兼容性
------

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

参见
--

* `Atomics`
* `Atomics.load()`


Atomics.wait() - JavaScript

Atomics.wait()
==============

**`Atomics.wait()`** 静态方法验证共享内存特定位置是否仍然包含给定值，如果是则休眠，直到被唤醒或超时。其返回一个内容为 `"ok"`、`"not-equal"` 或 `"timed-out"` 的字符串。

**备注：** 此操作仅适用于基于 `SharedArrayBuffer` 的 `Int32Array` 或 `BigInt64Array` 视图，并且在主线程中可能不可用。有关此方法的非阻塞异步版本，请参见 `Atomics.waitAsync()`。

语法
--

```js
Atomics.wait(typedArray, index, value)
Atomics.wait(typedArray, index, value, timeout)
```

### 参数

`typedArray`

基于 `SharedArrayBuffer` 的 `Int32Array` 或 `BigInt64Array`。

`index`

`typedArray` 中要等待的位置。

`value`

要测试的期望值。

`timeout` 可选

等待时间，以毫秒为单位。`NaN`（以及会被转换为 `NaN` 的值，例如 `undefined`）会被转换为 `Infinity`。负值会被转换为 `0`。

### 返回值

一个内容为 `"ok"`、`"not-equal"` 或 `"timed-out"` 的字符串。

### 异常

`TypeError`

有下列情况之一，则抛出该异常：

* 如果 `typedArray` 不是一个基于 `SharedArrayBuffer` 的 `Int32Array` 或 `BigInt64Array`。
* 如果当前线程无法被阻塞（例如主线程）。

`RangeError`

如果 `index` 超出 `typedArray` 的范围，则抛出该异常。

示例
--

### 使用 wait()

给定一个共享的 `Int32Array`：

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

令一个读取线程休眠并在位置 0 处等待，预期该位置的值为 0。只要条件一直为真，则将不会继续运行。然而，一旦写入线程存储了一个新的值，它将被读取线程唤醒并返回新的值（123）。

```js
Atomics.wait(int32, 0, 0);
console.log(int32[0]); // 123
```

写入线程存储一个新的值并在写入后唤醒等待的线程：

```js
console.log(int32[0]); // 0;
Atomics.store(int32, 0, 123);
Atomics.notify(int32, 0, 1);
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-atomics.wait |

浏览器兼容性
------

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

参见
--

* `Atomics`
* `Atomics.waitAsync()`
* `Atomics.notify()`