String.prototype.isWellFormed() - JavaScript

String.prototype.isWellFormed()
===============================

`String` 值的 **`isWellFormed()`** 方法返回一个表示该字符串是否包含单独代理项的布尔值。

语法
--

```js
isWellFormed()
```

### 返回值

如果字符串不包含单独代理项，返回 `true`，否则返回 `false`。

描述
--

JavaScript 中的字符串是 UTF-16 编码的。UTF-16 编码中有*代理对*的概念，这一概念在 UTF-16 字符、Unicode 码位和字素簇部分有详细介绍。

`isWellFormed()` 让你能够测试一个字符串是否是格式正确的（即不包含单独代理项）。由于引擎能够直接访问字符串的内部表示，与自定义实现相比 `isWellFormed()` 更高效。如果你需要将字符串转换为格式正确的字符串，可以使用 `toWellFormed()` 方法。`isWellFormed()` 让你可以对格式正确和格式错误的字符串进行不同的处理，比如抛出一个错误或将其标记为无效。

示例
--

### 使用 isWellFormed()

```js
const strings = [
  // 单独的前导代理
  "ab\uD800",
  "ab\uD800c",
  // 单独的后尾代理
  "\uDFFFab",
  "c\uDFFFab",
  // 格式正确
  "abc",
  "ab\uD83D\uDE04c",
];

for (const str of strings) {
  console.log(str.isWellFormed());
}
// 输出：
// false
// false
// false
// false
// true
// true
```

### 避免 encodeURI() 错误

如果传递的字符串格式不正确， `encodeURI` 会抛出错误。可以通过使用 `isWellFormed()` 在将字符串传递给 `encodeURI()` 之前测试字符串来避免这种情况。

```js
const illFormed = "https://example.com/search?q=\uD800";

try {
  encodeURI(illFormed);
} catch (e) {
  console.log(e); // URIError: URI malformed
}

if (illFormed.isWellFormed()) {
  console.log(encodeURI(illFormed));
} else {
  console.warn("Ill-formed strings encountered."); // Ill-formed strings encountered.
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-string.prototype.iswellformed |

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

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

参见
--

* `core-js` 中 `String.prototype.isWellFormed` 的 polyfill
* `String.prototype.toWellFormed()`
* `String.prototype.normalize()`


String.prototype.match() - JavaScript

String.prototype.match()
========================

**`match()`** 方法检索字符串与正则表达式进行匹配的结果。

尝试一下
----

语法
--

```js
match(regexp)
```

### 参数

`regexp`

一个正则表达式对象或者任何具有 `Symbol.match` 方法的对象。

如果 `regexp` 不是 `RegExp` 对象并且对象上无 `Symbol.match` 方法，则会使用 `new RegExp(regexp)` 将其隐式地转换为 `RegExp`。

如果你没有给出任何参数并直接使用 `match()` 方法，你将会得到一个包含空字符串的数组：`[""]`，因为这等价于 `match(/(?:)/)`。

### 返回值

一个 `Array`，其内容取决于是否存在全局（`g`）标志，如果没有匹配，则返回 `null`。

* 如果使用 `g` 标志，则将返回与完整正则表达式匹配的所有结果，但不会返回捕获组。
* 如果没有使用 `g` 标志，则只返回第一个完整匹配及其相关捕获组。在这种情况下，`match()` 方法将返回与 `RegExp.prototype.exec()` 相同的结果（一个带有一些额外属性的数组）。
描述
--

`String.prototype.match` 方法本身的实现非常简单，它只是使用字符串作为第一个参数调用了参数的 `Symbol.match` 方法。实际的实现来自于 `RegExp.prototype[@@match]()`。

* 如果你需要知道一个字符串是否与一个正则表达式 `RegExp` 匹配，请使用 `RegExp.prototype.test()`。
* 如果你只想获取第一个匹配项，你可能需要使用 `RegExp.prototype.exec()`。
* 如果你想要获取捕获组，并且全局标志已设置，你需要使用 `RegExp.prototype.exec()` 或 `String.prototype.matchAll()`。

有关传入正则表达式时 `match()` 方法的语义更多信息，请参阅 `RegExp.prototype[@@match]()`。

示例
--

### 使用 match()

在下例中，使用 `match` 查找 `"Chapter"` 紧跟着 1 个或多个数值字符，再紧跟着一个小数点和数值字符 0 次或多次。正则表达式包含 `i` 标志，因此大小写会被忽略。

```js
const str = "For more information, see Chapter 3.4.5.1";
const re = /see (chapter \d+(\.\d)\*)/i;
const found = str.match(re);

console.log(found);
// [
// 'see Chapter 3.4.5.1',
// 'Chapter 3.4.5.1',
// '.1',
// index: 22,
// input: 'For more information, see Chapter 3.4.5.1',
// groups: undefined
// ]
```

在上面的匹配结果中，`'see Chapter 3.4.5.1'` 是整个匹配。`'Chapter 3.4.5.1'` 被 `(chapter \d+(\.\d)*)` 捕获。`.1` 是由 `(\.\d)` 最后捕获的值。`index` 属性 (`22`) 是整个匹配的零基索引。`input` 属性是解析的原始字符串。

### 将全局标志和忽略大小写标志与 match() 一起使用

下面的示例演示了在 `match()` 中使用全局标志和忽略大小写标志。所有从 `A` 到 `E` 和从 `a` 到 `e` 的字母都将作为数组中的一个元素返回。

```js
const str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const regexp = /[A-E]/gi;
const matches = str.match(regexp);

console.log(matches);
// ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']
```

**备注：** 参见 `String.prototype.matchAll()` 和通过标志进行高级搜索。

### 使用命名捕获组

在支持命名捕获组的浏览器中，以下代码将 `"fox"` 或 `"cat"` 捕获到一个名为 `animal` 的组中：

```js
const paragraph = "The quick brown fox jumps over the lazy dog. It barked.";

const capturingRegex = /(?<animal>fox|cat) jumps over/;
const found = paragraph.match(capturingRegex);
console.log(found.groups); // {animal: "fox"}
```

### 不传参数使用 match()

```js
const str = "空即是空";

str.match(); // 返回 [""]
```

### 使用实现了 @@match 的非 RegExp 对象调用 match()

如果一个对象有一个名为 `Symbol.match` 的方法，那么它可以被用作自定义匹配器。`Symbol.match` 的返回值将成为 `match()` 方法的返回值。

```js
const str = "Hmm, this is interesting.";

str.match({
  [Symbol.match](str) {
    return ["Yes, it's interesting."];
  },
}); // returns ["Yes, it's interesting."]
```

### 将非正则表达式对象作为参数

当 `regexp` 参数是一个字符串或一个数字，它会使用 `new RegExp(regexp)` 来隐式转换成一个 `RegExp`。

```js
const str1 =
  "NaN 表示不是一个数字。在 JavaScript 中 Infinity 包括了 -Infinity 和 +Infinity。";
const str2 = "我的爷爷已经 65 岁了，我的奶奶已经 63 岁";
const str3 = "该合同被声明为 null 且 void。";
str1.match("数字"); // “数字”是一个字符串。返回 ["数字"]
str1.match(NaN); // NaN 的类型是数字。返回 ["NaN"]
str1.match(Infinity); // Infinity 的类型是数字。返回 ["Infinity"]
str1.match(+Infinity); // 返回 ["Infinity"]
str1.match(-Infinity); // 返回 ["-Infinity"]
str2.match(65); // 返回 ["65"]
str2.match(+65); // 带正号的数字。返回 ["65"]
str3.match(null); // 返回 ["null"]
```

如果特殊字符没有被正确转义，这可能会导致意想不到的结果。

```js
console.log("123".match("1.3")); // [ "123" ]
```

这是一个匹配，因为正则表达式中的 `.` 可以匹配任何字符。为了仅匹配一个点字符，需要对输入进行转义。

```js
console.log("123".match("1\\.3")); // null
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-string.prototype.match |

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

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

参见
--

* 在 `core-js` 中实现 `String.prototype.match` 的 polyfill，包括修复和实现现代行为，例如 `Symbol.match` 支持
* `String.prototype.matchAll()`
* `RegExp`
* `RegExp.prototype.exec()`
* `RegExp.prototype.test()`


String.prototype.codePointAt() - JavaScript

String.prototype.codePointAt()
==============================

`String` 的 **`codePointAt()`** 方法返回一个非负整数，该整数是从给定索引开始的字符的 Unicode 码位值。请注意，索引仍然基于 UTF-16 码元，而不是 Unicode 码位。

尝试一下
----

语法
--

```js
codePointAt(index)
```

### 参数

`index`

需要返回的字符的（从零开始的）索引。会被转换为整数——`undefined` 会转换为 0。

### 返回值

一个非负整数，表示给定 `index` 处字符的码位值。

* 如果 `index` 超出了 `0` – `str.length - 1` 的范围，`codePointAt()` 返回 `undefined`。
* 如果 `index` 处的元素是一个 UTF-16 前导代理（leading surrogate），则返回代理*对*的码位。
* 如果 `index` 处的元素是一个 UTF-16 后尾代理（trailing surrogate），则*只*返回后尾代理的码元。
描述
--

字符串中的字符从左到右进行索引。第一个字符的索引为 `0`，而字符串 `str` 中最后一个字符的索引为 `str.length - 1`。

Unicode 码位范围从 `0` 到 `1114111`（`0x10FFFF`）。在 UTF-16 中，每个字符串索引是一个取值范围为 `0` – `65535` 的码元。较高的码位由一个由*一对* 16 位代理伪字符表示。因此，`codePointAt()` 返回的码位可能跨越两个字符串索引。有关 Unicode 的信息，请参阅 UTF-16 字符、Unicode 码位和字素簇。

示例
--

### 使用 codePointAt()

```js
"ABC".codePointAt(0); // 65
"ABC".codePointAt(0).toString(16); // 41

"😍".codePointAt(0); // 128525
"\ud83d\ude0d".codePointAt(0); // 128525
"\ud83d\ude0d".codePointAt(0).toString(16); // 1f60d

"😍".codePointAt(1); // 56845
"\ud83d\ude0d".codePointAt(1); // 56845
"\ud83d\ude0d".codePointAt(1).toString(16); // de0d

"ABC".codePointAt(42); // undefined
```

### 在循环中使用 codePointAt()

因为使用字符串索引进行循环会导致同一码位被访问两次（一次是前导代理，一次是后尾代理），而第二次调用 `codePointAt()` 时*只*返回后尾代理项，所以最好避免使用索引进行循环。

```js
const str = "\ud83d\udc0e\ud83d\udc71\u2764";

for (let i = 0; i < str.length; i++) {
  console.log(str.codePointAt(i).toString(16));
}
// '1f40e'、'dc0e'、'1f471'、'dc71'、'2764'
```

相反，可以使用 `for...of` 语句或字符串展开语法，这两种方法都会调用字符串的 `@@iterator`，从而按照码位进行迭代。然后，可以使用 `codePointAt(0)` 获取每个元素的码位值。

```js
for (const codePoint of str) {
  console.log(codePoint.codePointAt(0).toString(16));
}
// '1f40e'、'1f471'、'2764'

[...str].map((cp) => cp.codePointAt(0).toString(16));
// ['1f40e', '1f471', '2764']
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-string.prototype.codepointat |

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

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

参见
--

* `core-js` 中 `String.prototype.codePointAt` 的 polyfill
* `String.fromCodePoint()`
* `String.fromCharCode()`
* `String.prototype.charCodeAt()`
* `String.prototype.charAt()`


String.prototype.concat() - JavaScript

String.prototype.concat()
=========================

**`concat()`** 方法将字符串参数连接到调用的字符串，并返回一个新的字符串。

尝试一下
----

语法
--

```js
concat(str1)
concat(str1, str2)
concat(str1, str2, /\* …, \*/ strN)
```

### 参数

`strN`

要连接到 `str` 的一个或多个字符串。

### 返回值

一个包含所提供的多个字符串文本组合的新字符串。

描述
--

`concat()` 函数将字符串参数连接到调用的字符串并返回一个新字符串。对原字符串或返回的字符串所做的更改不会影响另一个字符串。

如果参数不是字符串类型，它们在连接之前将会被转换成字符串。

`concat()` 方法与加号/字符串连接运算符（`+`，`+=`）非常相似，不同之处在于 `concat()` 直接将其参数强制转换为字符串进行连接，而加号运算符首先将其操作数强制转换为原始值，然后再进行连接。有关更多信息，请参阅 `+` 运算符的参考页面。

示例
--

### 使用 concat()

下面的示例将多个字符串组合为一个新字符串。

```js
const hello = "Hello, ";
console.log(hello.concat("Kevin", ". Have a nice day."));
// Hello, Kevin. Have a nice day.

const greetList = ["Hello", " ", "Venkat", "!"];
"".concat(...greetList); // "Hello Venkat!"

"".concat({}); // "[object Object]"
"".concat([]); // ""
"".concat(null); // "null"
"".concat(true); // "true"
"".concat(4, 5); // "45"
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-string.prototype.concat |

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

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

参见
--

* `Array.prototype.concat()`
* 加法运算符


String.prototype.substr() - JavaScript

String.prototype.substr()
=========================

**已弃用:** 不再推荐使用该特性。虽然一些浏览器仍然支持它，但也许已从相关的 web 标准中移除，也许正准备移除或出于兼容性而保留。请尽量不要使用该特性，并更新现有的代码；参见本页面底部的兼容性表格以指导你作出决定。请注意，该特性随时可能无法正常工作。

`String` 值的 **`substr()`** 方法返回该字符串的一部分，从指定的索引开始，然后扩展到给定数量的字符。

**备注：** `substr()` 不属于 ECMAScript 主要规范——它在附件 B: Web 浏览器的附加 ECMAScript 功能中定义，这是非浏览器运行时的可选标准。因此，建议人们使用标准的 `String.prototype.substring()` 和 `String.prototype.slice()` 方法，以便使他们的代码能够更好地、最大程度地跨平台。`String.prototype.substring()` 页面对这三种方法进行了一些比较。

尝试一下
----

语法
--

```js
substr(start)
substr(start, length)
```

### 参数

`start`

返回子字符串中要包含的第一个字符的索引。

`length` 可选

要提取的字符数。

### 返回值

一个包含给定字符串指定部分的新字符串。

描述
--

字符串的 `substr()` 方法从字符串中提取 `length` 字符，从 `start` 索引开始计数。

* 如果 `start >= str.length`，则返回空字符串。
* 如果 `start < 0`，则索引从字符串末尾开始计数。更准确地说，在这种情况下，子字符串从 `max(start + str.length, 0)` 开始。
* 如果省略 `start` 或其值为 `undefined`，则将其视为 `0`。
* 如果省略 `length` 或其值为 `undefined`，或者如果 `start + length >= str.length`，则 `substr()` 会提取字符到字符串末尾。
* 如果 `length < 0`，则返回空字符串。
* 对于 `start` 和 `length`，`NaN` 被视为 `0`。

尽管我们建议你避免使用 `substr()`，但是没有简单的方法可以将遗留代码中的 `substr()` 迁移到 `slice()` 或 `substring()`，而无需为 `substr()` 编写一个 polyfill。例如，当 `str = "01234", a = 1, l = -2` 时，`str.substr(a, l)`、`str.slice(a, a + l)` 和 `str.substring(a, a + l)` 都有不同的结果——`substr()` 返回空字符串，`slice()` 返回 `"123"`，而 `substring()` 返回 `"0"`。实际的重构路径取决于对 `a` 和 `l` 范围的了解。

示例
--

### 使用 substr()

```js
const aString = "Mozilla";

console.log(aString.substr(0, 1)); // 'M'
console.log(aString.substr(1, 0)); // ''
console.log(aString.substr(-1, 1)); // 'a'
console.log(aString.substr(1, -1)); // ''
console.log(aString.substr(-3)); // 'lla'
console.log(aString.substr(1)); // 'ozilla'
console.log(aString.substr(-20, 2)); // 'Mo'
console.log(aString.substr(20, 2)); // ''
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-string.prototype.substr |

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

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

参见
--

* `core-js` 中 `String.prototype.substr` 的 Polyfill
* `String.prototype.slice()`
* `String.prototype.substring()`


TypedArray.prototype.find() - JavaScript

TypedArray.prototype.find()
===========================

如果某个元素满足所提供的测试函数，**`find()`** 方法返回类型化数组中的**值**，否则返回 `undefined`。*TypedArray* 是这里的类型化数组类型之一。

同时请参见 `findIndex()` 方法，它返回了类型化数组中所发现元素的**下标**，而不是它的值。

语法
--

```js
find(callbackFn)
find(callbackFn, thisArg)
```

### 参数

`callback`

用于在类型化数组中的每个元素上执行的函数，接受三个参数：

`element`

要处理的类型化数组的当前元素。

`index`

要处理的当前元素在类型化数组中的下标

`array`

`find` 在其上调用的类型化数组

`thisArg`

可选，执行`callback`时的`this`值。

### 返回值

如果元素通过了测试，则为该元素，否则为`undefined`。

描述
--

`find` 方法对类型化数组中的每个元素执行一次 `callback` 函数，直到它找到一个使 `callback` 返回 *true*的元素。如果发现了一个这样的元素，`find` 方法将会立即返回该元素的值。否则，`find` 方法会返回`undefined`。`callback` 只会对那些已经被赋值的索引调用。不会对那些被删除或从来没被赋值的索引调用。

`callback` 以三个参数调用：元素的值，元素索引，以及要遍历的数组对象。

如果将`thisArg`参数提供给`find`，它会在调用时传递给`callback`，作为它的 `this`值。如果没有提供，会使用`undefined`。

`find` 不修改在其上调用的类型化数组。

由 `find`处理的元素范围在`callback`调用之前就确定了。在 `find`调用之后添加到数组的元素不会由 `callback`访问。如果类型化数组的现有元素被改变，或被删除，它们传给`callback`的值是`find` 访问它们时候的值。已删除的元素不会被访问。

示例
--

### 在类型化数组中寻找质数

下面的示例在类型化数组中寻找质数（如果没有质数则返回 `undefined`）。

```js
function isPrime(element, index, array) {
  var start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false;
    }
  }
  return element > 1;
}

var uint8 = new Uint8Array([4, 5, 8, 12]);
console.log(uint8.find(isPrime)); // 5
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.find |

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

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

另见
--

* `TypedArray.prototype.findIndex()`
* `TypedArray.prototype.every()`


TypedArray.prototype.some() - JavaScript

TypedArray.prototype.some()
===========================

这个 **`some()`** 方法检测 *TypedArray* 的一些元素是否通过所提供函数的测试。这个方法和 `Array.prototype.some()` *相同。* *TypedArray* 是 typed array types 之一。

尝试一下
----

语法
--

```js
some(callbackFn)
some(callbackFn, thisArg)
```

### 参数

`callback`

一个测试每个元素的函数，有 3 个参数：

`currentValue`

在 typed array 中，正在被测试的元素。

`index`

在 typed array 中，正在被测试元素的索引。

`array`

正在被调用的 typed array 本身。

`thisArg`

可选的。`callback` 回调函数的 `this` 值 .

### 返回值

**`true`** 如果 callback 函数以任一数组元素为参数调用时，返回 truthy; 否则，**`false`**.

描述
--

对于 typed array 中的每个元素，`some`方法执行一次 `callback`，直到找到一个`callback` 返回 true 的元素。如果一个元素被找到，`some` 立即返回 `true`. 否则，`some` 返回 `false`.

`callback` 期望 3 个参数：元素的值，元素的索引，和被遍历的数组对象。

如果 `some` 提供 `thisArg`, 那么`thisArg`会作为 `callback` 调用时的`this 值`. 否则，`callback` 调用时的 `this` 是 `undefined`. `callback` 最终可观测的`this` 是根据 确定函数 this 的通常规则 所确定的。

`some` 被调用不会改变 typed array .

### 示例

### 测试类型化数组所有元素的大小

以下示例测试 typed array 中的所有元素都大于 10.

```js
function isBiggerThan10(element, index, array) {
  return element > 10;
}
new Uint8Array([2, 5, 8, 1, 4]).some(isBiggerThan10); // false
new Uint8Array([12, 5, 8, 1, 4]).some(isBiggerThan10); // true
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.some |

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

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

参见
--

* `core-js` 中 `TypedArray.prototype.some` 的 polyfill
* JavaScript 类型化数组指南
* `TypedArray`
* `TypedArray.prototype.every()`
* `TypedArray.prototype.forEach()`
* `TypedArray.prototype.find()`
* `TypedArray.prototype.includes()`
* `Array.prototype.some()`


TypedArray.prototype.reverse() - JavaScript

TypedArray.prototype.reverse()
==============================

**`reverse()`** 方法原地翻转类型化数组。类型化数组的第一个元素变为最后一个，最后一个变为第一个。这个方法的算法和 `Array.prototype.reverse()` 相同。*TypedArray* 是这里的类型化数组类型之一。

语法
--

```js
reverse()
```

### 返回值

翻转的数组。

示例
--

```js
var uint8 = new Uint8Array([1, 2, 3]);
uint8.reverse();

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

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.reverse |

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

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

另见
--

* `Array.prototype.reverse()`


TypedArray.prototype.keys() - JavaScript

TypedArray.prototype.keys()
===========================

**`keys()`** 方法返回新的 `Array Iterator` 对象，包含数组中每个下标的键。

语法
--

```js
keys()
```

### 返回值

新的 **`Array Iterator`** 对象

示例
--

### 使用`for...of`循环的迭代

```js
var arr = new Uint8Array([10, 20, 30, 40, 50]);
var eArray = arr.keys();
// 你的浏览器必须支持 for..of 循环
// 以及 for 循环中的 let 区域变量
for (let n of eArray) {
  console.log(n);
}
```

### 备选的迭代

```js
var arr = new Uint8Array([10, 20, 30, 40, 50]);
var eArr = arr.keys();
console.log(eArr.next().value); // 0
console.log(eArr.next().value); // 1
console.log(eArr.next().value); // 2
console.log(eArr.next().value); // 3
console.log(eArr.next().value); // 4
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.keys |

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

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

另见
--

* JavaScript 类型化数组
* `TypedArray`
* `TypedArray.prototype.entries()`
* `TypedArray.prototype.values()`
* `TypedArray.prototype[@@iterator]()`
* for...of
* 迭代协议


TypedArray.prototype.every() - JavaScript

TypedArray.prototype.every()
============================

**`every()`** 方法测试类型化数组的所有元素是否都能够通过由提供函数实现的测试。这个方法的算法与 `Array.prototype.every()`相同。*TypedArray* 是这里的 类型化数组类型 之一。

语法
--

```js
every(callbackFn)
every(callbackFn, thisArg)
```

### 参数

`callback`

用于测试每个元素的函数，接受三个参数：

`currentValue`

要处理的类型化数组的当前元素。

`index`

要处理的当前元素在类型化数组中的下标

`array`

every 在其上调用的类型化数组

`thisArg`

可选，执行 `callback` 时的 `this` 值。

### 返回值

如果函数对数组每个元素返回 truthy ，则为\*\*`true`\*\*，否则为 **`false`**。

描述
--

`every` 方法为类型化数组中的每个元素执行一次 `callback` 函数，直到它找到一个使 `callback` 返回 *false*（表示可转换为布尔值 false 的值）的元素。如果发现了一个这样的元素，`every` 方法将会立即返回 `false`。否则，`callback` 为每一个元素返回 `true`，`every` 就会返回 `true`。`callback` 只会为那些已经被赋值的索引调用。不会为那些被删除或从来没被赋值的索引调用。

`callback` 以三个参数调用：元素的值，元素索引，以及要遍历的数组对象。

如果将 `thisArg` 参数提供给 `every`，它会在调用时传递给 `callback`，作为它的 `this` 值。否则，会传递 `undefined` 作为它的 `this` 值。`callback` 最终观测到的 `this` 值由用于决定函数可见的 `this` 值的一般规则来决定。

`every` 不修改在其上调用的类型化数组。

示例
--

### 测试类型化数组所有元素的大小

下面的示例测试了类型化数组所有元素是否大于 10。

```js
function isBigEnough(element, index, array) {
  return element >= 10;
}
new Uint8Array([12, 5, 8, 130, 44]).every(isBigEnough); // false
new Uint8Array([12, 54, 18, 130, 44]).every(isBigEnough); // true
```

### 使用箭头函数测试类型化数组的元素

箭头函数为相同测试提供了更短的语法。

```js
new Uint8Array([12, 5, 8, 130, 44]).every((elem) => elem >= 10); // false
new Uint8Array([12, 54, 18, 130, 44]).every((elem) => elem >= 10); // true
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.every |

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

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

另见
--

* `TypedArray.prototype.some()`
* `Array.prototype.every()`


TypedArray.BYTES_PER_ELEMENT - JavaScript

TypedArray.BYTES\_PER\_ELEMENT
==============================

概要
--

**`TypedArray.BYTES_PER_ELEMENT`** 属性代表了强类型数组中每个元素所占用的字节数。

| `TypedArray.BYTES_PER_ELEMENT` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

语法
--
```

TypedArray.BYTES_PER_ELEMENT;
```

描述
--

强类型数组对象用来解释为单个元素的字节数是不一样的。常量 `BYTES_PER_ELEMENT` 表示了特定强类型数组中每个元素所占用的字节数。

示例
--

```js
Int8Array.BYTES\_PER\_ELEMENT; // 1
Uint8Array.BYTES\_PER\_ELEMENT; // 1
Uint8ClampedArray.BYTES\_PER\_ELEMENT; // 1
Int16Array.BYTES\_PER\_ELEMENT; // 2
Uint16Array.BYTES\_PER\_ELEMENT; // 2
Int32Array.BYTES\_PER\_ELEMENT; // 4
Uint32Array.BYTES\_PER\_ELEMENT; // 4
Float32Array.BYTES\_PER\_ELEMENT; // 4
Float64Array.BYTES\_PER\_ELEMENT; // 8
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-typedarray.bytes\_per\_element |

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

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

参见
--

* JavaScript 强类型数组
* `TypedArray`


TypedArray.prototype.indexOf() - JavaScript

TypedArray.prototype.indexOf()
==============================

**`indexOf()`** 方法返回在类型数组中可以找到给定元素的第一个索引，如果不存在，则返回 -1。方法具有与 `Array.prototype.indexOf()` 相同的算法。TypedArray 是这里的类型化数组类型之一。

语法
--

```js
indexOf(searchElement)
indexOf(searchElement, fromIndex)
```

### 参数

`searchElement`

需要在类型化数组中定位的元素

`fromIndex`

搜索的起始下标。如果下标大于等于类型化数组长度，则返回 -1，意思是类型化数组不会被搜索。如果提供的下标值是负数，则被当做距离类型化数组尾部的偏移。注：如果提供的下标是负数，类型化数组仍然从前到后搜索。如果计算出来的下标小于 0，则会搜索整个类型化数组。默认为 0（搜索整个类型化数组）。

### 返回值

数组中元素的第一个下标；没有找到则返回\*\*-1\*\* 。

描述
--

`indexOf`使用严格相等 (en-US) （由 === 或三等号运算符使用的相同方法）比较`searchElement`和类型化数组的元素。

示例
--

```js
let uint8 = new Uint8Array([2, 5, 9]);
uint8.indexOf(2); // 0
uint8.indexOf(7); // -1
uint8.indexOf(9, 2); // 2
uint8.indexOf(2, -1); // -1
uint8.indexOf(2, -3); // 0
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.indexof |

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

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

另见
--

* `TypedArray.prototype.lastIndexOf()`
* `Array.prototype.indexOf()`


TypedArray.of() - JavaScript

TypedArray.of()
===============

`TypedArray.of()` 方法创建一个具有可变数量参数的新类型数组。此方法几乎与 `Array.of()` 相同。

语法
--

```js
TypedArray.of(element0)
TypedArray.of(element0, element1)
TypedArray.of(element0, element1, /\* ... ,\*/ elementN)
```

### 参数

`elementN`

创建类型数组的元素。

### 返回值

一个新的 `TypedArray` 实例。

描述
--

`Array.of()` 和 `TypedArray.of()` 之间的一些细微区别：

* 如果传递给 TypedArray.of 的这个值不是构造函数，TypedArray.of 将抛出一个`TypeError` ，其中 Array.of 默认创建一个新的 `Array`。
* `TypedArray.of` 使用 [[Put]] 其中 Array.of 使用 [[DefineProperty]]。因此，当使用`Proxy` 对象时，它调用 `handler.set` 创建新的元素，而不是 `handler.defineProperty`。
范例
--

```js
Uint8Array.of(1); // Uint8Array [ 1 ]
Int8Array.of("1", "2", "3"); // Int8Array [ 1, 2, 3 ]
Float32Array.of(1, 2, 3); // Float32Array [ 1, 2, 3 ]
Int16Array.of(undefined); // IntArray [ 0 ]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.of |

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

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

参见
--

* `TypedArray.from()`
* `Array.of()`


TypedArray.prototype.forEach() - JavaScript

TypedArray.prototype.forEach()
==============================

**`forEach()`** 方法对类型化数组的每个元素调用提供的函数。这个方法的算法和 `Array.prototype.forEach()` 相同。*TypedArray* 是这里的类型化数组类型之一。

语法
--

```js
forEach(callbackFn)
forEach(callbackFn, thisArg)
```

### 参数

`callback`

产生新的类型化数组的元素的函数，接受三个函数：

`currentValue`

类型化数组中要处理的当前元素

`index`

类型化数组中要处理的当前元素的下标

`array`

`forEach()`在其上调用的类型化数组

`thisArg`

可选，执行`callback`时作为`this`的值。

### 返回值

`undefined`.

描述
--

`forEach`方法对类型化数组中的元素按升序调用提供的 `callback`函数。它不会对删除或者省略的下标调用，但是会对存在并且值为`undefined`的元素调用。

`callback` 以 **三个参数**调用：

* the **元素的值**
* the **元素下标**
* the **被遍历的类型化数组**

如果将 `thisArg` 参数提供给 `forEach`，它会在调用时传递给 `callback`，作为它的 `this` 值。否则，会传递 `undefined` 作为它的 `this` 值。`callback`最终观测到的 `this` 值由用于决定函数可见的 `this` 值的一般规则来决定。

由 `forEach`处理的元素范围在`callback`调用之前就确定了。在 `forEach`调用之后添加到数组的元素不会由 `callback`访问。如果类型化数组的现有元素被改变，或被删除，它们传给`callback`的值是`forEach` 访问它们时候的值。已删除的元素不会被访问。

`forEach()`对每个数组元素执行一次`callback` 函数；不像 `every()` 和`some()`，它始终返回 `undefined`。

示例
--

### 记录类型化数组的内容

下面的代码为数组中的每个元素记录一行日志：

```js
function logArrayElements(element, index, array) {
  console.log("a[" + index + "] = " + element);
}

new Uint8Array([0, 1, 2, 3]).forEach(logArrayElements);
// 日志：
// a[0] = 0
// a[1] = 1
// a[2] = 2
// a[3] = 3
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.foreach |

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

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

另见
--

* `TypedArray.prototype.map()`
* `TypedArray.prototype.every()`
* `TypedArray.prototype.some()`
* `Array.prototype.forEach()`


TypedArray.prototype.byteOffset - JavaScript

TypedArray.prototype.byteOffset
===============================

**`byteOffset`** 访问器属性表示类型化数组距离其`ArrayBuffer`起始位置的偏移（字节数）。

语法
--
```

typedarray.byteOffset
```

描述
--

`byteOffset` 是一个访问器属性，它的 set 访问器函数是`undefined`，意思是你只能够读取这个属性。它的值在*TypedArray*构造时建立，不能被修改。*TypedArray* 是这里的 TypedArray 对象之一。

示例
--

### 使用`byteOffset` 属性

```js
var buffer = new ArrayBuffer(8);

var uint8 = new Uint8Array(buffer);
uint8.byteOffset; // 0 (没有指定 oddfet)

var uint8 = new Uint8Array(buffer, 3);
uint8.byteOffset; // 3 (在构造 Uint8Array 时指定)
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-%typedarray%.prototype.byteoffset |

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

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

另见
--

* JavaScript 类型化数组
* `TypedArray`


TypedArray.prototype.length - JavaScript

TypedArray.prototype.length
===========================

**`length`** 访问器属性表示类型化数组的长度（元素数）。

尝试一下
----

描述
--

`length` 是一个访问器属性，它的 set 访问器函数是`undefined`，意思是你只能够读取这个属性。它的值在*TypedArray*构造时建立，不能被修改。如果 *TypedArray* 没有指定`byteOffset` 或者 `length`，会返回所引用的`ArrayBuffer` 的`length`。*TypedArray* 是这里的 TypedArray 对象之一。

示例
--

### 使用`length` 属性

```js
var buffer = new ArrayBuffer(8);

var uint8 = new Uint8Array(buffer);
uint8.length; // 8 (符合 buffer 的 length)

var uint8 = new Uint8Array(buffer, 1, 5);
uint8.length; // 5 (在 Uint8Array 构造时指定)

var uint8 = new Uint8Array(buffer, 2);
uint8.length; // 6 (根据被构造的 Uint8Array 的 offset)
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-%typedarray%.prototype.length |

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

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

另见
--

* JavaScript 类型化数组
* `TypedArray`


TypedArray.prototype.toLocaleString() - JavaScript

TypedArray.prototype.toLocaleString()
=====================================

**`toLocaleString()`** 方法返回一个字符串，表示该类型化数组的元素。这些元素被转化为字符串并由一个区域设置指定的分隔符（例如逗号“,”）分隔。这个方法与 `Array.prototype.toLocaleString()` 拥有相同的算法。同时，由于类型化数组的元素都是数字，将每个元素转化为字符串的算法与 `Number.prototype.toLocaleString()` 是相同的。*类型化数组*需要是类型化数组类型中的一种类型。

语法
--

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

### 参数

`locales` 和 `options` 参数用于自定义函数的行为，并让应用程序指定应该使用的格式约定的语言。在忽略 `locales` 和 `options` 参数的实现中，使用的语言环境和返回的字符串形式完全取决于实现。

 参见 `Intl.NumberFormat()` (en-US)
 构造函数，以了解这些参数的详细信息，以及如何使用它们。

### 返回值

一个字符串，表示该类型化数组内的元素。

示例
--

### 使用 toLocaleString

```js
const uint = new Uint32Array([2000, 500, 8123, 12, 4212]);

uint.toLocaleString();
// 如果在 de-DE 区域设置下运行
// "2.000,500,8.123,12,4.212"

uint.toLocaleString("en-US");
// "2,000,500,8,123,12,4,212"

uint.toLocaleString("ja-JP", { style: "currency", currency: "JPY" });
// "￥2,000,￥500,￥8,123,￥12,￥4,212"
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.tolocalestring |

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

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

参见
--

* `Array.prototype.toLocaleString()`
* `Number.prototype.toLocaleString()`


TypedArray.prototype.join() - JavaScript

TypedArray.prototype.join()
===========================

**`join()`** 方法将数组中所有元素连接为一个字符串。这个方法的算法和 `Array.prototype.join()` 相同。*TypedArray* 是这里的类型化数组类型之一。

语法
--

```js
join()
join(separator)
```

### 参数

`separator`

可选。指定分隔每个元素的字符串。分隔符按需转换为字符串。如果没有，类型化数组的元素会以逗号 (",") 分隔。

### 返回值

所有元素连接后的字符串。

示例
--

```js
var uint8 = new Uint8Array([1, 2, 3]);
uint8.join(); // '1,2,3'
uint8.join(" / "); // '1 / 2 / 3'
uint8.join(""); // '123'
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.join |

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

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

参见
--

* `core-js` 中 `TypedArray.prototype.join` 的 polyfill
* JavaScript 类型化数组指南
* `TypedArray`
* `TypedArray.prototype.toString()`
* `Array.prototype.join()`
* `String.prototype.split()`


TypedArray.prototype.values() - JavaScript

TypedArray.prototype.values()
=============================

**`values()`** 返回新的 `Array Iterator` 对象，包含数组中每个下标处的值。

语法
--
```

arr.values()
```

### 返回值

新的 **`Array Iterator`** 对象。

示例
--

### 使用`for...of` 循环的迭代

```js
var arr = new Uint8Array([10, 20, 30, 40, 50]);
var eArray = arr.values();
// 你的浏览器必须支持 for..of 循环
// 以及 for 循环中的 let 区域变量
for (let n of eArray) {
  console.log(n);
}
```

### 备选迭代

```js
var arr = new Uint8Array([10, 20, 30, 40, 50]);
var eArr = arr.values();
console.log(eArr.next().value); // 10
console.log(eArr.next().value); // 20
console.log(eArr.next().value); // 30
console.log(eArr.next().value); // 40
console.log(eArr.next().value); // 50
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.values |

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

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

另见
--

* JavaScript 类型化数组
* `TypedArray`
* `TypedArray.prototype.entries()`
* `TypedArray.prototype.keys()`
* `TypedArray.prototype[@@iterator]()`


TypedArray.prototype.fill() - JavaScript

TypedArray.prototype.fill()
===========================

`fill() 方法将`类型化数组中的从起始索引到终止索引内的全部元素。这个方法的算法和 `Array.prototype.fill()` 相同。*TypedArray* 是这里的类型化数组类型之一。

语法
--

```js
fill(value)
fill(value, start)
fill(value, start, end)
```

### 参数

`value`

用来填充类型化数组元素的值。

`start`

可选参数。起始索引，默认值为 0。

`end`

可选参数。终止索引（填充范围不包含此索引），默认值为 `this.length`。

### 返回值

修改后的类型化数组。

描述
--

将被元素填充的区间是 [`start`, `end`)。

**`fill`** 方法接受三个参数 `value`，`start` 以及 `end`。`start` 和 `end` 参数是可选的，默认值分别为 `0` 和 `this.length`。

如果 `start` 参数是负值，它会被视为 `length+start`，其中 `length` 是类型化数组的长度。如果 `end` 参数是负值，它会被视为 `length+end`。

示例
--

```js
new Uint8Array([1, 2, 3]).fill(4); // Uint8Array [4, 4, 4]
new Uint8Array([1, 2, 3]).fill(4, 1); // Uint8Array [1, 4, 4]
new Uint8Array([1, 2, 3]).fill(4, 1, 2); // Uint8Array [1, 4, 3]
new Uint8Array([1, 2, 3]).fill(4, 1, 1); // Uint8Array [1, 2, 3]
new Uint8Array([1, 2, 3]).fill(4, -3, -2); // Uint8Array [4, 2, 3]
```

兼容实现
----

由于并没有一个名为 *TypedArray* 的全局变量，我们必须“按需添加”兼容实现。请配合`Array.prototype.fill()`的兼容实现使用以下的“兼容实现”

```js
// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.fill
if (!Uint8Array.prototype.fill) {
  Uint8Array.prototype.fill = Array.prototype.fill;
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.fill |

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

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

相关
--

* `Array.prototype.fill()`


TypedArray.prototype.filter() - JavaScript

TypedArray.prototype.filter()
=============================

**`filter()`** 创建新的类型化数组，含有所有通过了测试的元素，测试由提供的函数实现。这个方法的算法和 `Array.prototype.filter()` 相同。*TypedArray* 是这里的类型化数组类型之一。

语法
--

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

### 参数

`callback`

测试类型化数组每个元素的函数，以参数 `(element, index, typedarray)`调用。如果返回 `true`则保留该元素，如果返回`false`则相反。

`thisArg 可选`

可选，执行`callback`时作为`this`的值。

### 返回值

新的类型化数组，含有通过测试的元素

描述
--

`filter`方法对类型化数组中的元素调用提供的 `callback`函数，并且会为`callback`返回 true 的那些元素构造新的类型化数组。 `callback` 只对拥有值的类型化数组下标调用。它不会对未定义的，被删除的或者没有赋值的下标调用。没有传给`callback`的类型化数组的元素只是简单跳过，不会包含在新数组中。

`callback`以三个参数调用：

1. 元素的值
2. 元素下标
3. 被遍历的类型化数组对象

如果将 `thisArg` 参数提供给 `filter`，它会在调用时传递给 `callback`，作为它的 `this` 值。否则，会传递 `undefined` 作为它的 `this` 值。`callback` 最终观测到的 `this` 值由用于决定函数可见的 `this` 值的一般规则来决定。

`filter()`不改变在其上调用的类型化数组。

由 `filter`处理的元素范围在`callback`调用之前就确定了。在 `filter`调用之后添加到数组的元素不会由 `callback`访问。如果类型化数组的现有元素被改变，或被删除，它们传给`callback`的值是`filter` 访问它们时候的值。已删除的元素不会被访问。

示例
--

### 过滤所有较小的值

下面的示例使用了 `filter()` 来创建过滤后的类型化数组，小于 10 的元素都被移除了。

```js
function isBigEnough(element, index, array) {
  return element >= 10;
}
new Uint8Array([12, 5, 8, 130, 44]).filter(isBigEnough);
// Uint8Array [ 12, 130, 44 ]
```

### 使用箭头函数过滤类型化数组的元素

箭头函数 为相同测试提供了更短的语法。

```js
new Uint8Array([12, 5, 8, 130, 44]).filter((elem) => elem >= 10);
// Uint8Array [ 12, 130, 44 ]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.filter |

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

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

另见
--

* `TypedArray.prototype.every()`
* `TypedArray.prototype.some()`
* `Array.prototype.filter()`


TypedArray.prototype.lastIndexOf() - JavaScript

TypedArray.prototype.lastIndexOf()
==================================

**`lastIndexOf()`** 方法返回在类型数组中可以找到给定元素的最后一个索引，如果不存在，则返回 -1。方法具有与 `Array.prototype.lastIndexOf()` 相同的算法。TypedArray 是这里的类型化数组类型之一。

语法
--

```js
lastIndexOf(searchElement)
lastIndexOf(searchElement, fromIndex)
```

### 参数

`searchElement`

需要在类型化数组中定位的元素

`fromIndex`

可选。反向搜索的起始下标。默认为数组的长度，即会搜索整个类型化数组。如果下标大于等于类型化数组长度，会搜索整个类型化数组。如果是负数，则被当做距离类型化数组尾部的偏移。注：如果提供的下标是负数，类型化数组仍然从后到前搜索。如果计算出来的下标小于 0，则会返回 -1，即不会搜索类型化数组。

### 返回值

数组中元素的最后一个下标；没有找到则返回 **-1** 。

描述
--

`lastIndexOf`使用严格相等 (en-US) （由 === 或三等号运算符使用的相同方法）比较`searchElement`和类型化数组的元素。

示例
--

```js
var uint8 = new Uint8Array([2, 5, 9, 2]);
uint8.lastIndexOf(2); // 3
uint8.lastIndexOf(7); // -1
uint8.lastIndexOf(2, 3); // 3
uint8.lastIndexOf(2, 2); // 0
uint8.lastIndexOf(2, -2); // 0
uint8.lastIndexOf(2, -1); // 3
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.lastindexof |

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

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

另见
--

* `TypedArray.prototype.indexOf()`
* `Array.prototype.lastIndexOf()`


TypedArray.prototype.set() - JavaScript

TypedArray.prototype.set()
==========================

**`set()`** 方法用于从指定数组中读取值，并将其存储在类型化数组中。

语法
--

```js
set(array)
set(array, targetOffset)

set(typedarray)
set(typedarray, targetOffset)
```

### 参数

`array`

拷贝数据的源数组，源数组的所有值都会被复制到目标数组中，除非源数组的长度加上偏移量超过目标数组的长度，而在这种情况下会抛出异常。参数 array 是源数组，指定从哪里拷贝值。源数组中的所有值都会被拷贝到目标数组中去。如果源数组的长度加上偏移值 offset 的结果超过目标数组的长度，则会抛出异常错误。

`typedarray`

如果源数组是一个类型化数组（typed array），则源数组和目标数组可以共享同一个底层的`ArrayBuffer`；JavaScript 引擎会智能地将 buffer 的指定区段拷贝到目标区段中去。

`offset` 可选

偏移量参数 offset 指定从什么地方开始使用源数组 `array` 的值进行写入操作。如果忽略该参数，则默认为 0（也就是说，从目标数组的下标为 0 处开始，使用源数组 `array` 的值覆盖重写）。

### 异常

`RangeError`

如果指定的偏移量超出了类型化数组的范围，则该异常会被抛出。

示例
--

### 使用 `set()`

```js
var buffer = new ArrayBuffer(8);
var uint8 = new Uint8Array(buffer);

uint8.set([1, 2, 3], 3);

console.log(uint8); // Uint8Array [ 0, 0, 0, 1, 2, 3, 0, 0 ]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.set |

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

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

另见
--

* JavaScript typed arrays
* `TypedArray`
* `ArrayBuffer`


TypedArray.prototype.byteLength - JavaScript

TypedArray.prototype.byteLength
===============================

**`byteLength`** 访问器属性表示类型化数组的长度（字节数）。

语法
--
```

typedarray.byteLength
```

描述
--

`byteLength` 是一个访问器属性，它的 set 访问器函数是 `undefined`，意思是你只能够读取这个属性。它的值在 *TypedArray* 构造时建立，不能被修改。如果 *TypedArray* 没有指定 `byteOffset` 或者 `length`，会返回所引用的 `ArrayBuffer` 的 `length`。*TypedArray* 是这里的 TypedArray 对象之一。

示例
--

### 使用 `byteLength` 属性

```js
var buffer = new ArrayBuffer(8);

var uint8 = new Uint8Array(buffer);
uint8.byteLength; // 8 (符合 buffer 的 byteLength)

var uint8 = new Uint8Array(buffer, 1, 5);
uint8.byteLength; // 5 (在 Uint8Array 构造时指定)

var uint8 = new Uint8Array(buffer, 2);
uint8.byteLength; // 6 (根据被构造的 Uint8Array 的 offset)
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-%typedarray%.prototype.bytelength |

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

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

另见
--

* JavaScript 类型化数组
* `TypedArray`


TypedArray.prototype.reduceRight() - JavaScript

TypedArray.prototype.reduceRight()
==================================

**`reduceRight()`** 在累加器和类型化数组的每个元素上（从右到左）调用函数，使其归约为单一的值。这个方法的算法和 `Array.prototype.reduceRight()` 相同。*TypedArray* 是这里的类型化数组类型之一。

语法
--

```js
reduceRight(callbackFn)
reduceRight(callbackFn, initialValue)
```

### 参数

`callback`

对类型数组的每一个值应用的函数，它接受四个参数：

`previousValue`

回调函数上一次调用所返回的值，或者是提供的 `initialValue`。

`currentValue`

类型化数组中当前要处理的值。

`index`

类型化数组中要处理的当前元素的下标

`array`

`reduceRight` 在其上调用的类型化数组

`initialValue`

可选。用作 `callback` 首次调用的第一个参数的对象。

### 返回值

由归约返回的结果。

描述
--

`reduceRight`方法对类型化数组中出现的每个元素执行`callback`函数，除了类型化数组的空隙。它接受四个参数：初始值（或者来自之前`callback`调用的值），当前元素的值，当前下标，以及被遍历的类型化数组。

`reduceRight`回调函数的调用是这样：

```js
typedarray.reduceRight(
  function (previousValue, currentValue, index, typedarray) {
    // ...
  },
);
```

第一次调用回调函数的时候， `previousValue` 和 `currentValue` 可以是两个值之一。如果 `initialValue` 在`reduce`的调用中提供， `previousValue` 会等于`initialValue` 并且`currentValue` 会等于类型化数组的最后一个值。如果 `initialValue` 没有提供，则`previousValue`等于类型化数组的最后一个值，`currentValue`会等于倒数第二个值。

如果类型化数组为空并且没有提供 `initialValue`，会抛出 `TypeError` 。如果类型化数组中只有一个元素（无论位置）并且没有提供`initialValue` ，或者如果提供了`initialValue` 但是类型化数组为空，会返回唯一的值，但不会调用 `callback`。

示例
--

### 累加数组中的所有值

```js
var total = new Uint8Array([0, 1, 2, 3]).reduceRight(function (a, b) {
  return a + b;
});
// total == 6
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.reduceright |

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

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

另见
--

* `TypedArray.prototype.reduce()`
* `Array.prototype.reduceRight()`


TypedArray.prototype.slice() - JavaScript

TypedArray.prototype.slice()
============================

**`slice()`** 方法将一个类型化数组的一部分浅拷贝到一个新的类型化数组对象中并返回。此方法采用与 `Array.prototype.slice()` 相同的算法。*TypedArray* 指类型化数组的类型中的一员。

尝试一下
----

语法
--

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

参数
--

`begin` 可选

从 0 开始的索引位置。可以使用负值索引，表示从数组末尾往前的偏移量。`slice(-2)` 表示提取数组中的末尾两个元素。如果没有设定起始位置，则将从开始位置开始截取。

`end` 可选

从 0 开始到尾元素前的索引值。 `slice` 取出的元素到此位置之前，不包含该位置。例，`slice(1,4)` 表示读取第 2 个元素到第 4 个元素 (元素索引：1, 2, 3)。可以使用负值索引，表示从数组末尾往前的偏移量。 `slice(2,-1)` 表示取出数组中的第 3 个到倒数第 2 个元素。如果没有设定结束位置，则将从开始位置截取到序列尾部。(默认值为`typedarray.length`).

### 返回值

包含取出元素的新 typed array。

描述
--

`slice`方法并不会改变原数组的内容，它只是返回从原数组中取出的元素的浅复制集合。

如果一个新元素被添加到它们任何一个数组中去，另外一个数组不会受到影响。

示例
--

### 返回已存在类型数组的一部分片段

```js
const uint8 = new Uint8Array([1, 2, 3]);
uint8.slice(1); // Uint8Array [ 2, 3 ]
uint8.slice(2); // Uint8Array [ 3 ]
uint8.slice(-2); // Uint8Array [ 2, 3 ]
uint8.slice(0, 1); // Uint8Array [ 1 ]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.slice |

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

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

参见
--

* `core-js` 中 `TypedArray.prototype.slice` 的 polyfill
* JavaScript 类型化数组指南
* `TypedArray`
* `Array.prototype.slice()`
* `String.prototype.slice()`


TypedArray.prototype.buffer - JavaScript

TypedArray.prototype.buffer
===========================

**`buffer`** 访问器属性表示由 *TypedArray* 在构造期间引用的 `ArrayBuffer`。

语法
--
```

typedArray.buffer
```

描述
--

`buffer` 属性是一个访问器属性，它的 set 访问器函数是 `undefined`，意思是你只能够读取这个属性。它的值在 *TypedArray* 构造时建立，不能被修改。*TypedArray* 是这里的类型化数组之一。

示例
--

### 使用 `buffer` 属性

```js
var buffer = new ArrayBuffer(8);
var uint16 = new Uint16Array(buffer);
uint16.buffer; // ArrayBuffer { byteLength: 8 }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-%typedarray%.prototype.buffer |

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

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

另见
--

* JavaScript 类型化数组
* `TypedArray`


TypedArray.from() - JavaScript

TypedArray.from()
=================

`TypedArray.from()` 方法 从一个类数组或者可迭代对象中创建一个新类型数组。这个方法和 `Array.from()` 类似。

语法
--

```js
TypedArray.from(arrayLike, mapFn)
TypedArray.from(arrayLike, mapFn, thisArg)
```

上面代码中的 `TypedArray` 需要替换为下面的任何一个构造函数：

* `Int8Array`
* `Uint8Array`
* `Uint8ClampedArray`
* `Int16Array`
* `Uint16Array`
* `Int32Array`
* `Uint32Array`
* `Float32Array`
* `Float64Array`
* `BigInt64Array`
* `BigUint64Array` (en-US)
### 参数

*`source`*

想要转换为类型数组的类数组或者可迭代对象。

*`mapFn`*

可选参数。如果指定了该参数，则最后生成的类型数组会经过该函数的加工处理后再返回。

*`thisArg`*

可选参数。执行 `mapFn` 函数时 `this` 的值。

### 返回值

一个新的 `TypedArray` 实例。

描述
--

`TypedArray.from()` 允许你从下面两者来创建数组：

* 类数组对象（拥有一个 `length` 属性和若干索引属性的任意对象）
* 可迭代对象（你可以从它身上迭代出若干个元素的对象，比如有 `Map` 和 `Set` 等）。

`TypedArray.from()` 方法有一个可选参数 `mapFn`, 让你可以在最后生成的类型数组上再执行一次 `map` 方法后再返回。也就是说以下两种形式是等价的：

* `TypedArray.from(obj, mapFn, thisArg)`
* `TypedArray.from(Array.prototype.map.call(obj, mapFn, thisArg))`

`from()` 的 `length` 属性值为 `1`。

`Array.from()` 和 `TypedArray.from()` 之间有一些微妙的区别：

* 如果 `|this|` 的值传递给 `TypedArray.from` 不是一个构造器，`TypedArray.from` 将抛出{jsxref("TypeError")}}, 而 `Array.from` 默认将创建一个 `Array`.
* `TypedArray.from` 使用`[Put]` 而 `rray.from` 使用`[DefineProperty]]`. 因此，当和 `Proxy` 对象一起时，它调用 `handler.set` 创建一个新的元素而非 `handler.defineProperty`.
* 当 `from` 获得一个迭代器时，`TypedArray` 一开始收集迭代器中的所有值，此时创建一个 `|this|` 的实例用于计数，然后在实例中设置值。 `Array.from` 设置每个从迭代器其中获取的值，最后设置它的长度。
* 当 `Array.from` 获得一个不可迭代的类数组时，it respects holes, 而 `TypedArray.from` 将确保结果是 dense.
示例
--

```js
// 使用 Set (可迭代对象)
var s = new Set([1, 2, 3]);
Uint8Array.from(s);
// Uint8Array [ 1, 2, 3 ]

// 使用字符串
Int16Array.from("123");
// Int16Array [ 1, 2, 3 ]

// 使用箭头函数对数组元素进行映射
Float32Array.from([1, 2, 3], (x) => x + x);
// Float32Array [ 2, 4, 6 ]

// 生成一个数字序列
Uint8Array.from({ length: 5 }, (v, k) => k);
// Uint8Array [ 0, 1, 2, 3, 4 ]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.from |

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

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

参见
--

* `core-js` 中 `TypedArray.from` 的 polyfill
* JavaScript 类型化数组指南
* `TypedArray`
* `TypedArray.of()`
* `TypedArray.prototype.map()`
* `Array.from()`


TypedArray.prototype.copyWithin() - JavaScript

TypedArray.prototype.copyWithin()
=================================

**`copyWithin()`** 方法将数组中元素的序列复制到以 `target` 起始的位置。拷贝的副本取自第二个参数（`start`）和第三个参数（`end`）的下标位置。`end` 参数是可选的，默认为数组长度。该方法与 `Array.prototype.copyWithin` 的算法相同。*TypedArray* 指的是这里的 类型化数组类型 之一。

语法
--
```

typedarray.copyWithin(target, start[, end = this.length])
```

### 参数

`target`

目标起始位置的下标，复制元素到这里。

`start`

源起始位置的下标，在这里开始复制元素。

`end 可选`

可选。源终止位置的下标，在这里停止复制元素。

### 返回值

修改后的类型化数组。

描述
--

更多信息请见 `Array.prototype.copyWithin`。

这个方法取代了实验性的 `TypedArray.prototype.move()`。

示例
--

```js
var buffer = new ArrayBuffer(8);
var uint8 = new Uint8Array(buffer);
uint8.set([1, 2, 3]);
console.log(uint8); // Uint8Array [ 1, 2, 3, 0, 0, 0, 0, 0 ]
uint8.copyWithin(3, 0, 3);
console.log(uint8); // Uint8Array [ 1, 2, 3, 1, 2, 3, 0, 0 ]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.copywithin |

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

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

另见
--

* `TypedArray`


TypedArray.prototype.toString() - JavaScript

TypedArray.prototype.toString()
===============================

**`toString()`** 方法返回一个表示指定数组及其元素的字符串。这个方法的算法和 `Array.prototype.toString()` 一样。*TypedArray* 在这是typed array types 之一。

语法
--

```js
values()
```

### 返回值

一个字符串，表示类型数组 (typed array) 的元素。

描述
--

`TypedArray` 对象重写了`Object`的 `toString`方法。对 TypedArray 对象来说，`toString` 方法联结了数组，并返回一个字符串，它包含由逗号分隔的数组元素。例如，下面的代码创建了一个类型数组，使用`toString` 将数组转化为字符串。

```js
var numbers = new Uint8Array([2, 5, 8, 1, 4]);
numbers.toString(); // "2,5,8,1,4"
```

当一个类型数组表示为文本值，或者当一个数组被用于字符串连接，则 JavaScript 将自动调用 `toString` 方法。

### 兼容性

如果浏览器还不支持`TypedArray.prototype.toString()` 方法，JavaScript 将调用`Object`的 `toString` 方法：

```js
var numbers = new Uint8Array([2, 5, 8, 1, 4]);
numbers.toString(); // "[object Uint8Array]"
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.tostring |

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

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

参见
--

* `TypedArray.prototype.join()`


TypedArray.prototype.entries() - JavaScript

TypedArray.prototype.entries()
==============================

**`entries()`** 返回新的 `Array Iterator` 对象，包含数组每个下标处的键值对。

语法
--
```

arr.entries()
```

### 返回值

新的 **`Array Iterator`** 对象。

示例
--

### `使用 for...of` 循环的迭代

```js
var arr = new Uint8Array([10, 20, 30, 40, 50]);
var eArray = arr.entries();
// 你的浏览器必须支持 for..of 循环
// 以及 for 循环中的 let 区域变量
for (let n of eArray) {
  console.log(n);
}
```

### 备选迭代

```js
var arr = new Uint8Array([10, 20, 30, 40, 50]);
var eArr = arr.entries();
console.log(eArr.next().value); // [0, 10]
console.log(eArr.next().value); // [1, 20]
console.log(eArr.next().value); // [2, 30]
console.log(eArr.next().value); // [3, 40]
console.log(eArr.next().value); // [4, 50]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.entries |

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

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

另见
--

* JavaScript 类型化数组
* `TypedArray`
* `TypedArray.prototype.keys()`
* `TypedArray.prototype.values()`
* `TypedArray.prototype[@@iterator]()`


get TypedArray[@@species] - JavaScript

get TypedArray[@@species]
=========================

**`TypedArray[@@species]`** 访问器属性返回类型化数组的构造器。

语法
--
```

TypedArray[Symbol.species]

其中 TypedArray 是下列类型之一：

Int8Array
Uint8Array
Uint8ClampedArray
Int16Array
Uint16Array
Int32Array
Uint32Array
Float32Array
Float64Array
```

描述
--

`species` 访问器属性返回类型化数组对象的构造器。子类的构造器可能会覆盖它来修改构造器的赋值。

示例
--

`species` 属性返回默认的构造器函数，对于给定的类型化数组对象，它是类型化数组构造器之一：

```js
Int8Array[Symbol.species]; // function Int8Array()
Uint8Array[Symbol.species]; // function Uint8Array()
Float32Array[Symbol.species]; // function Float32Array()
```

在派生的集合对象中（也就是你自己定义的类型化数组`MyTypedArray`）， `MyTypedArray` 的 species 是 `MyTypedArray` 构造器。但是，你可能希望覆盖它，以便在你的派生类方法中返回类型化数组的基类对象：

```js
class MyTypedArray extends Uint8Array {
  // 将 MyTypedArray species 覆盖为 Uint8Array 基类构造器
  static get [Symbol.species]() {
    return Uint8Array;
  }
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-%typedarray%-@@species |

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

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

另见
--

* `TypedArray`
* `Symbol.species`


TypedArray.prototype.map() - JavaScript

TypedArray.prototype.map()
==========================

**`map()`** 方法对类型化数组的每个元素调用提供的函数，并使用结果来创建新的类型化数组。这个方法的算法和 `Array.prototype.map()` 相同。*TypedArray* 是这里的类型化数组类型之一。

语法
--

```js
map(callbackFn)
map(callbackFn, thisArg)
```

### 参数

`callback`

产生新的类型化数组的元素的函数，接受三个函数：

`currentValue`

类型化数组中要处理的当前元素

`index`

类型化数组中要处理的当前元素的下标

`array`

`map`在其上调用的类型化数组

`thisArg`

可选，执行`callback`时作为`this`的值。

### 返回值

新的类型化数组

描述
--

`map`方法对类型化数组中的元素调用提供的 `callback`函数，按照顺序，并且会从结果构造新的类型化数组。 `callback` 只对拥有值的类型化数组下标调用。它不会对未定义的，被删除的或者没有赋值的下标调用。

`callback` 以三个参数调用：元素的值，元素下标，和被遍历的类型化数组。

如果将 `thisArg` 参数提供给 `map`，它会在调用时传递给 `callback`，作为它的 `this` 值。否则，会传递 `undefined` 作为它的 `this` 值。`callback` 最终观测到的 `this` 值由用于决定函数可见的 `this` 值的一般规则来决定。

`map` 不改变在其上调用的类型化数组（虽然如果调用了`callback`可能会这样做）。

由 `map`处理的元素范围在`callback`调用之前就确定了。在 `map`调用之后添加到数组的元素不会由 `callback`访问。如果类型化数组的现有元素被改变，或被删除，它们传给`callback`的值是`map` 访问它们时候的值。已删除的元素不会被访问。

示例
--

### 将类型数组映射被平方根的类型数组

下面的代码接受一个类型数组，并创建一个新的类型数组，含有第一个类型数组中元素的平方根。

```js
var numbers = new Uint8Array([1, 4, 9]);
var roots = numbers.map(Math.sqrt);
// roots is now: Uint8Array [1, 2, 3],
// numbers is still Uint8Array [1, 4, 9]
```

### 使用含有参数的函数来映射类型数组

下面的代码展示了，当使用需要一个参数的函数时，`map`的工作方式。在`map`遍历原始数组的过程中，参数会自动赋值为类型化数组的每个元素。

```js
var numbers = new Uint8Array([1, 4, 9]);
var doubles = numbers.map(function (num) {
  return num \* 2;
});
// doubles is now Uint8Array [2, 8, 18]
// numbers is still Uint8Array [1, 4, 9]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.map |

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

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

另见
--

* `TypedArray.prototype.filter()`
* `Array.prototype.map()`


TypedArray.prototype[@@iterator]() - JavaScript

TypedArray.prototype[@@iterator]()
==================================

@@iterator 的初始值是和 `values` 属性的初始值相同的对象。

尝试一下
----

语法
--
```

arr[Symbol.iterator]()
```

### 返回值

数组的 **迭代器** 函数，通常是 `values()`函数。

示例
--

### 使用`for...of` 循环的迭代

```js
var arr = new Uint8Array([10, 20, 30, 40, 50]);
// 你的浏览器必须支持 for..of 循环
// 以及 for 循环中的 let 区域变量
for (let n of arr) {
  console.log(n);
}
```

### 备选迭代

```js
var arr = new Uint8Array([10, 20, 30, 40, 50]);
var eArr = arr[Symbol.iterator]();
console.log(eArr.next().value); // 10
console.log(eArr.next().value); // 20
console.log(eArr.next().value); // 30
console.log(eArr.next().value); // 40
console.log(eArr.next().value); // 50
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype-@@iterator |

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

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

See also
--------

* JavaScript typed arrays
* `TypedArray`
* `TypedArray.prototype.entries()`
* `TypedArray.prototype.keys()`
* `TypedArray.prototype.values()`


TypedArray.prototype.findIndex() - JavaScript

TypedArray.prototype.findIndex()
================================

如果某个元素满足所提供的测试函数，**`findIndex()`** 方法返回类型化数组中的**下标**，否则返回 -1。*TypedArray* 是这里的类型化数组类型之一。

同时请参见 `find()` 方法，它返回了类型化数组中所发现元素的**值**，而不是它的下标。

语法
--

```js
findIndex(callbackFn)
findIndex(callbackFn, thisArg)
```

### 参数

`callback`

用于在类型化数组中的每个元素上执行的函数，接受三个参数：

`element`

要处理的类型化数组的当前元素。

`index`

要处理的当前元素在类型化数组中的下标

`array`

`find` 在其上调用的类型化数组

`thisArg`

可选，执行`callback`时的`this`值。

### 返回值

如果元素通过了测试，则为数组下标，否则为 -1。

描述
--

`findIndex` 方法对类型化数组中的每个元素执行一次 `callback` 函数，直到它找到一个使 `callback` 返回 *true*的元素。如果发现了一个这样的元素，`find` 方法将会立即返回该元素的下标。否则，`findIndex` 方法会返回 -1。`callback` 只会对那些已经被赋值的索引调用。不会对那些被删除或从来没被赋值的索引调用。

`callback` 以三个参数调用：元素的值，元素索引，以及要遍历的数组对象。

如果将`thisArg`参数提供给`findIndex`，它会在调用时传递给`callback`，作为它的 `this`值。如果没有提供，会使用`undefined`。

`findIndex` 不修改在其上调用的类型化数组。

由 `findIndex`处理的元素范围在`callback`调用之前就确定了。在 `findIndex`调用之后添加到数组的元素不会由 `callback`访问。如果类型化数组的现有元素被改变，或被删除，它们传给`callback`的值是`findIndex` 访问它们时候的值。已删除的元素不会被访问。

示例
--

### 在类型化数组中寻找质数的下标

下面的示例在类型化数组中寻找质数元素的下标（如果没有质数则返回 -1）.

```js
function isPrime(element, index, array) {
  var start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false;
    }
  }
  return element > 1;
}

var uint8 = new Uint8Array([4, 6, 8, 12]);
var uint16 = new Uint16Array([4, 6, 7, 12]);

console.log(uint8.findIndex(isPrime)); // -1，未发现
console.log(uint16.findIndex(isPrime)); // 2
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.findindex |

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

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

参见
--

* `core-js` 中 `TypedArray.prototype.findIndex` 的 polyfill
* JavaScript 类型化数组指南
* `TypedArray`
* `TypedArray.prototype.find()`
* `TypedArray.prototype.findLast()` (en-US)
* `TypedArray.prototype.findLastIndex()` (en-US)
* `TypedArray.prototype.indexOf()`
* `TypedArray.prototype.lastIndexOf()`
* `Array.prototype.findIndex()`


TypedArray.prototype.sort() - JavaScript

TypedArray.prototype.sort()
===========================

**`sort()`** 方法*原地*排序类型化数组的元素，并且返回类型化数组。这个方法的算法和`Array.prototype.sort()` 相同。*TypedArray* 是这里的类型化数组类型 之一。

语法
--

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

### 参数

`compareFunction` 可选

指定定义排序顺序的函数

### 返回值

排序后的类型化数组。

示例
--

更多示例请参考 `Array.prototype.sort()` 方法。

```js
var numbers = new Uint8Array([40, 1, 5, 200]);
numbers.sort();
// Uint8Array [ 1, 5, 40, 200 ]
// 在这里，按数值排序数值时，
// 不需要比较函数。

var numbers = [40, 1, 5, 200];
numbers.sort();
// 将元素作为字符串来排序。
// [1, 200, 40, 5]

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

numbers.sort(compareNumbers);
// [ 1, 5, 40, 200 ]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.sort |

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

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

另见
--

* `Array.prototype.sort()`


TypedArray.prototype.reduce() - JavaScript

TypedArray.prototype.reduce()
=============================

**`reduce()`** 方法接受一个函数作为参数，这个函数作为一个累加器，从左到右遍历整个类型数组，最后返回一个单一的值。这个方法和`Array.prototype.reduce()`使用了同样的算法。*TypedArray* 是一个 类型数组.

语法
--

```js
reduce(callbackFn)
reduce(callbackFn, initialValue)
```

### 参数

`callback`

对类型数组的每一个值应用的函数，它接受以下参数：

`previousValue`

在上一次迭代中，调用 callback 的返回值，或者是提供的 `initialValue`。

`currentValue`

类型化数组中当前要处理的值。

`index`

类型化数组中要处理的当前元素的下标

`array`

`reduce` 在其上调用的类型化数组。

`initialValue`

可选。用作 `callback` 首次调用`的第一个参数的对象。

### 返回值

由归约返回的结果。

描述
--

`reduce`方法对类型化数组中出现的每个元素执行`callback`函数，除了类型化数组的空隙。它接受四个参数：初始值（或者来自之前`callback`调用的值），当前元素的值，当前下标，以及被遍历的类型化数组。

第一次调用回调函数的时候， `previousValue` 和 `currentValue` 可以是两个值之一。如果 `initialValue` 在`reduce`的调用中提供， `previousValue` 会等于`initialValue` 并且`currentValue` 会等于类型化数组的第一个值。如果 `initialValue` 没有提供，则`previousValue`等于类型化数组的第一个值，`currentValue`会等于第二个值。

如果类型化数组为空并且没有提供 `initialValue`，会抛出 `TypeError` 。如果类型化数组中只有一个元素（无论位置）并且没有提供`initialValue` ，或者如果提供了`initialValue` 但是类型化数组为空，会返回唯一的值，但不会调用 `callback`。

示例
--

### 累加数组中的所有值

```js
var total = new Uint8Array([0, 1, 2, 3]).reduce(function (a, b) {
  return a + b;
});
// total == 6
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.reduce |

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

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

另见
--

* `TypedArray.prototype.reduceRight()`
* `Array.prototype.reduce()`


TypedArray.prototype.includes() - JavaScript

TypedArray.prototype.includes()
===============================

**`includes()`** 方法判断类型化数组中是否含有特定元素，并相应返回 `true` 或者 `false`，这个方法的算法和 `Array.prototype.includes()` 相同。*TypedArray* 是这里的类型化数组类型之一。

语法
--

```js
includes(searchElement)
includes(searchElement, fromIndex)
```

### 参数

`searchElement`

要搜索的元素。

`fromIndex`

可选，数组中的位置，在这里开始搜索 `searchElement`；默认为 0。

### 返回值

`Boolean`。

示例
--

```js
var uint8 = new Uint8Array([1, 2, 3]);
uint8.includes(2); // true
uint8.includes(4); // false
uint8.includes(3, 3); // false

// NaN 的处理（仅仅对 Float32 和 Float64 为 true）
new Uint8Array([NaN]).includes(NaN); // false，因为 NaN 传递给构造器时转换为 0
new Float32Array([NaN]).includes(NaN); // true;
new Float64Array([NaN]).includes(NaN); // true;
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.includes |

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

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

另见
--

* `Array.prototype.includes()`
* `String.prototype.includes()`
* `TypedArray.prototype.indexOf()`


TypedArray.prototype.subarray() - JavaScript

TypedArray.prototype.subarray()
===============================

`subarray()` 返回一个新的、基于相同 `ArrayBuffer`、元素类型也相同的的 *TypedArray*。开始的索引将会被包括，而结束的索引将不会被包括。*TypedArray* 是指 typed array types 的其中之一。尝试一下
----

用法
--

```js
subarray()
subarray(begin)
subarray(begin, end)
```

### 参数

begin 可选

元素开始的索引，开始索引的元素将会被包括。若该值没有传入，将会返回一个拥有全部元素的数组。

end 可选

元素结束的索引，结束索引的元素将**不会**被包括。若该值没有传入，从 `begin` 所指定的那一个元素到数组末尾的所有元素都将会被包含进新数组中。

### 返回值

一个新的 `TypedArray` 对象。

说明
--

* 被 `begin` 和 `end` 指定的范围将会收束与当前数组的有效索引
* 若计算后得出的长度是负数，将会被收束成 0
* 若 `begin` 或 `end` 是负数，将会被当做成是从数组末端读取的索引

需要注意的是，使用该方法返回的新数组还是建立在原有的 Buffer 之上的，所以，改动数组的内容将会影响到原数组，反之亦然。

Examples
--------

### Using the `subarray` method

```js
var buffer = new ArrayBuffer(8);
var uint8 = new Uint8Array(buffer);
uint8.set([1, 2, 3]);

console.log(uint8); // Uint8Array [ 1, 2, 3, 0, 0, 0, 0, 0 ]

var sub = uint8.subarray(0, 4);

console.log(sub); // Uint8Array [ 1, 2, 3, 0 ]
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-%typedarray%.prototype.subarray |

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

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

See also
--------

* JavaScript typed arrays
* `TypedArray`
* `ArrayBuffer`


Object.prototype.toString() - JavaScript

Object.prototype.toString()
===========================

**`toString()`** 方法返回一个表示该对象的字符串。该方法旨在重写（自定义）派生类对象的类型转换的逻辑。

尝试一下
----

语法
--

```js
toString()
```

### 参数

默认情况下，`toString()` 不接受任何参数。然而，继承自 `Object` 的对象可能用它们自己的实现重写它，这些实现可以接受参数。例如，`Number.prototype.toString()` 和 `BigInt.prototype.toString()` 方法接受一个可选的 `radix` 参数。

### 返回值

一个表示该对象的字符串。

描述
--

JavaScript 调用 `toString` 方法将对象转换为一个原始值。你很少需要自己去调用 `toString` 方法；当遇到需要原始值的对象时，JavaScript 会自己调用它。

该方法由字符串转换优先调用，但是数字的强制转换和原始值的强制转换会优先调用 `valueOf()`。然而，因为基本的 `valueOf()` 方法返回一个对象，`toString()` 方法通常在结束时调用，除非对象重写了 `valueOf()`。例如，`+[1]` 返回 `1`，因为它的 `toString()` 方法返回 `"1"`，然后将其转换为数字。

所有继承自 `Object.prototype` 的对象（即，除了 `null`-prototype 对象之外的对象）都继承 `toString()` 方法。当你创建一个自定义对象时，你可以重写 `toString()` 以调用自定义方法，以便将自定义对象转换为一个字符串。或者，你可以增加一个 `@@toPrimitive` 方法，该方法允许对转换过程有更多的控制，并且对于任意的类型转换，且总是优先于 `valueOf` 或 `toString`。

要将基本的 `Object.prototype.toString()` 用于重写的对象（或者在 `null` 或 `undefined` 上调用它），你需要在它上面调用 `Function.prototype.call()` 或者 `Function.prototype.apply()`，将要检查的对象作为第一个参数传递（称为 `thisArg`）。

```js
const arr = [1, 2, 3];

arr.toString(); // "1,2,3"
Object.prototype.toString.call(arr); // "[object Array]"
```

`Object.prototype.toString()` 返回 `"[object Type]"`，这里的 `Type` 是对象的类型。如果对象有 `Symbol.toStringTag` 属性，其值是一个字符串，则它的值将被用作 `Type`。许多内置的对象，包括 `Map` 和 `Symbol`，都有 `Symbol.toStringTag`。一些早于 ES6 的对象没有 `Symbol.toStringTag`，但仍然有一个特殊的标签。它们包括（标签与下面给出的类型名相同）：

* `Array`
* `Function`（它的 `typeof` 返回 `"function"`）
* `Error`
* `Boolean`
* `Number`
* `String`
* `Date`
* `RegExp`

`arguments` 对象返回 `"[object Arguments]"`。其他所有内容，包括用户自定义的类，除非有一个自定义的 `Symbol.toStringTag`，否则都将返回 `"[object Object]"`。

在 `null` 和 `undefined` 上调用 `Object.prototype.toString()` 分别返回 `[object Null]` 和 `[object Undefined]`。

示例
--

### 为自定义对象重写 toString

你可以创建一个要调用的函数来代替默认的 `toString()` 方法。你创建的 `toString()` 函数应该返回一个字符串值。如果它返回一个对象，并且在类型转换期间隐式调用它，那么忽略它的结果，并使用相关方法 `valueOf()` 的值，或者这些方法都不返回原始值，则抛出 `TypeError`。

以下代码定义了 `Dog` 类。

```js
class Dog {
  constructor(name, breed, color, sex) {
    this.name = name;
    this.breed = breed;
    this.color = color;
    this.sex = sex;
  }
}
```

如果你在 `Dog` 实例上显示或者隐式的调用 `toString()` 方法，它将返回从 `Object` 继承的默认值：

```js
const theDog = new Dog("Gabby", "Lab", "chocolate", "female");

theDog.toString(); // "[object Object]"
`${theDog}`; // "[object Object]"
```

以下代码重写了默认的 `toString()` 方法。这个方法生成一个包含该对象的 `name`、`breed`、`color` 和 `sex` 的字符串。

```js
class Dog {
  constructor(name, breed, color, sex) {
    this.name = name;
    this.breed = breed;
    this.color = color;
    this.sex = sex;
  }
  toString() {
    return `Dog ${this.name} is a ${this.sex} ${this.color} ${this.breed}`;
  }
}
```

有了前面的代码，每当 `Dog` 实例在字符串的上下文中使用，JavaScript 会自动调用 `toString()` 方法。

```js
const theDog = new Dog("Gabby", "Lab", "chocolate", "female");

`${theDog}`; // "Dog Gabby is a female chocolate Lab"
```

### 使用 toString() 去检查对象类

`toString()` 可以与每个对象一起使用，并且（默认情况下）允许你获得它的类。

```js
const toString = Object.prototype.toString;

toString.call(new Date()); // [object Date]
toString.call(new String()); // [object String]
// Math has its Symbol.toStringTag
toString.call(Math); // [object Math]

toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
```

以这种方式使用 `toString()` 是不可靠的；对象可以通过定义 `Symbol.toStringTag` 属性来更改 `Object.prototype.toString()` 的行为，从而导致意想不到的结果。例如：

```js
const myDate = new Date();
Object.prototype.toString.call(myDate); // [object Date]

myDate[Symbol.toStringTag] = "myDate";
Object.prototype.toString.call(myDate); // [object myDate]

Date.prototype[Symbol.toStringTag] = "prototype polluted";
Object.prototype.toString.call(new Date()); // [object prototype polluted]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.tostring |

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

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

参见
--

* `core-js` 中 `Object.prototype.toString` 的 Polyfill（支持 `Symbol.toStringTag`）
* `Object.prototype.valueOf()`
* `Number.prototype.toString()`
* `Symbol.toPrimitive`
* `Symbol.toStringTag`


Object.prototype.__defineSetter__() - JavaScript

Object.prototype.\_\_defineSetter\_\_()
=======================================

**已弃用:** 不再推荐使用该特性。虽然一些浏览器仍然支持它，但也许已从相关的 web 标准中移除，也许正准备移除或出于兼容性而保留。请尽量不要使用该特性，并更新现有的代码；参见本页面底部的兼容性表格以指导你作出决定。请注意，该特性随时可能无法正常工作。

**备注：** 此特性已弃用，建议使用对象初始化语法或 `Object.defineProperty()` API 来定义 setter。该方法的行为只针对 Web 兼容性进行了规定，在任何平台上都不需要实现该方法。它可能无法在所有地方正常工作。

**`__defineSetter__()`** 方法将一个对象的属性绑定到一个函数上，当该属性被赋值时，该函数将被调用。

语法
--

```js
\_\_defineSetter\_\_(prop, func)
```

### 参数

`prop`

`func` 所绑定的 setter 函数所对应的属性名称，以字符串形式表示。

`func`

当试图设置指定属性时要调用的函数。该函数接收以下参数：

`val`

试图赋给 `prop` 的值。

### 返回值

`undefined`。

### 异常

`TypeError`

如果 `func` 不是函数，则抛出。

描述
--

所有继承自 `Object.prototype` 的对象（也就是除了 `null` 原型对象的对象）都会继承 `__defineSetter__()` 方法。该方法允许在一个已存在的对象上定义一个 setter。这相当于使用 `Object.defineProperty(obj, prop, { set: func, configurable: true, enumerable: true })` 方法，这意味着该属性是可枚举和可配置的，而且如果存在，则保留任何现有的 getter。

`__defineSetter__()` 在规范中被定义为“可选规范”，这意味着不需要任何实现来实现它。然而，所有主要的浏览器都实现了它，并且由于它的持续使用，它不太可能被删除。如果一个浏览器实现了 `__defineSetter__()`，那么它还需要实现 `__lookupGetter__()`、`__lookupSetter__()` 和 `__defineGetter__()` 方法。

示例
--

### 使用 \_\_defineSetter\_\_()

```js
const o = {};
o.\_\_defineSetter\_\_("value", function (val) {
  this.anotherValue = val;
});
o.value = 5;
console.log(o.value); // undefined
console.log(o.anotherValue); // 5
```

### 以标准方式定义 setter 属性

在对象首次初始化时，你可以使用 `set` 语法来定义一个 setter。

```js
const o = {
  set value(val) {
    this.anotherValue = val;
  },
};
o.value = 5;
console.log(o.value); // undefined
console.log(o.anotherValue); // 5
```

你也可以使用 `Object.defineProperty()` 在对象创建后为其定义一个 setter。与 `__defineSetter__()` 相比，此方法允许你控制 setter 的可枚举性和可配置性，以及定义 symbol 属性。`Object.defineProperty()` 方法也适用于 `null` 原型对象，因为它们没有继承 `Object.prototype`，所以没有 `__defineSetter__()` 方法。

```js
const o = {};
Object.defineProperty(o, "value", {
  set(val) {
    this.anotherValue = val;
  },
  configurable: true,
  enumerable: true,
});
o.value = 5;
console.log(o.value); // undefined
console.log(o.anotherValue); // 5
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.\_\_defineSetter\_\_ |

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

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

参见
--

* `core-js` 中 `Object.prototype.__defineSetter__` 的 polyfill
* `Object.prototype.__defineGetter__()`
* `set` 语法
* `Object.defineProperty()`
* `Object.prototype.__lookupGetter__()`
* `Object.prototype.__lookupSetter__()`
* JS 指南：定义 Getter 和 Setter
* [博文] \_\_defineGetter\_\_ 和 \_\_defineSetter\_\_ 已被弃用
* Firefox bug 647423


Object.is() - JavaScript

Object.is()
===========

**`Object.is()`** 静态方法确定两个值是否为相同值。

尝试一下
----

语法
--

```js
Object.is(value1, value2)
```

### 参数

`value1`

要比较的第一个值。

`value2`

要比较的第二个值。

### 返回值

一个布尔值，指示两个参数是否为相同的值。

描述
--

`Object.is()` 确定两个值是否为相同值。如果以下其中一项成立，则两个值相同：

* 都是 `undefined`
* 都是 `null`
* 都是 `true` 或者都是 `false`
* 都是长度相同、字符相同、顺序相同的字符串
* 都是相同的对象（意味着两个值都引用了内存中的同一对象）
* 都是 BigInt 且具有相同的数值
* 都是 symbol 且引用相同的 symbol 值
* 都是数字且
    + 都是 `+0`
    + 都是 `-0`
    + 都是 `NaN`
    + 都有相同的值，非零且都不是 `NaN`

`Object.is()` 与 `==` 运算符并不等价。`==` 运算符在测试相等性之前，会对两个操作数进行类型转换（如果它们不是相同的类型），这可能会导致一些非预期的行为，例如 `"" == false` 的结果是 `true`，但是 `Object.is()` 不会对其操作数进行类型转换。

`Object.is()` 也*不*等价于 `===` 运算符。`Object.is()` 和 `===` 之间的唯一区别在于它们处理带符号的 0 和 `NaN` 值的时候。`===` 运算符（和 `==` 运算符）将数值 `-0` 和 `+0` 视为相等，但是会将 `NaN` 视为彼此不相等。

示例
--

### 使用 Object.is()

```js
// 案例 1：评估结果和使用 === 相同
Object.is(25, 25); // true
Object.is("foo", "foo"); // true
Object.is("foo", "bar"); // false
Object.is(null, null); // true
Object.is(undefined, undefined); // true
Object.is(window, window); // true
Object.is([], []); // false
const foo = { a: 1 };
const bar = { a: 1 };
const sameFoo = foo;
Object.is(foo, foo); // true
Object.is(foo, bar); // false
Object.is(foo, sameFoo); // true

// 案例 2: 带符号的 0
Object.is(0, -0); // false
Object.is(+0, -0); // false
Object.is(-0, -0); // true

// 案例 3: NaN
Object.is(NaN, 0 / 0); // true
Object.is(NaN, Number.NaN); // true
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.is |

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

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

参见
--

* `core-js` 中 `Object.is` 的 Polyfill
* JavaScript 中的相等性判断——三种内置相等性工具的比较


Object.groupBy() - JavaScript

Object.groupBy()
================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
**实验性:** **这是一项实验性技术**
在将其用于生产之前，请仔细检查浏览器兼容性表格。

**备注：** 在某些浏览器的某些版本中，此方法被实现为 `Array.prototype.group()` 方法。由于 web 兼容性问题，它现在以静态方法实现。参见浏览器兼容性表格以获取更多信息。

**`Object.groupBy()`** 静态方法根据提供的回调函数返回的字符串值对给定可迭代对象中的元素进行分组。返回的对象具有每个组的单独属性，其中包含组中的元素的数组。

当分组名称可以用字符串表示时，应使用此方法。如果你需要使用某个任意值作为键来对元素进行分组，请改用 `Map.groupBy()` 方法。

语法
--

```js
Object.groupBy(items, callbackFn)
```

### 参数

`items`

一个将进行元素分组的可迭代对象（例如 `Array`）。

`callbackFn`

对可迭代对象中的每个元素执行的函数。它应该返回一个值，可以被强制转换成属性键（字符串或 symbol），用于指示当前元素所属的分组。该函数被调用时将传入以下参数：

`element`

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

`index`

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

### 返回值

一个带有所有分组属性的 `null` 原型对象，每个属性都分配了一个包含相关组元素的数组。

描述
--

`Object.groupBy()` 为可迭代对象中的每个元素调用一次提供的 `callbackFn` 函数。回调函数应返回一个字符串或 symbol（不属于这两种类型的值会被强制转换为字符串），用于指示元素所属的分组。`callbackFn` 的返回值会被用作 `Map.groupBy()` 返回的对象的键。每个键都有一个相关联的数组，其中包含回调函数返回相同值的所有元素。

返回的对象中的元素和原始可迭代对象中的元素相同（不是深拷贝）。更改元素的内部结构将反映在原始可迭代对象和返回的对象中。

示例
--

### 使用 Object.groupBy()

首先，我们定义一个包含代表各种食品库存的对象的数组。每种食品都有一个 `type` 和一个 `quantity` 属性。

```js
const inventory = [
  { name: "芦笋", type: "蔬菜", quantity: 5 },
  { name: "香蕉", type: "水果", quantity: 0 },
  { name: "山羊", type: "肉", quantity: 23 },
  { name: "樱桃", type: "水果", quantity: 5 },
  { name: "鱼", type: "肉", quantity: 22 },
];
```

下面的代码根据元素的 `type` 属性的值对元素进行分组。

```js
const result = Object.groupBy(inventory, ({ type }) => type);

/\* 结果是：
{
 蔬菜: [
 { name: "芦笋", type: "蔬菜", quantity: 5 },
 ],
 水果: [
 { name: "香蕉", type: "水果", quantity: 0 },
 { name: "樱桃", type: "水果", quantity: 5 }
 ],
 肉: [
 { name: "山羊", type: "肉", quantity: 23 },
 { name: "鱼", type: "肉", quantity: 22 }
 ]
}
\*/
```

箭头函数每次被调用时都只返回每个数组元素的 `type` 属性。请注意，函数参数 `{ type }` 是一个函数参数的对象解构语法的基本示例。这会解构传递为参数的对象的 `type` 属性，并将其赋值给函数体中名为 `type` 的变量。这是一种非常简洁的访问函数中相关元素的值的方式。

我们还可以创建根据元素的一个或多个属性中的值推断的分组。下面是一个非常类似的示例，根据 `quantity` 字段的值将项目分为 `ok` 或 `restock` 组。

```js
function myCallback({ quantity }) {
  return quantity > 5 ? "ok" : "restock";
}

const result2 = Object.groupBy(inventory, myCallback);

/\* 结果是：
{
 restock: [
 { name: "芦笋", type: "蔬菜", quantity: 5 },
 { name: "香蕉", type: "水果", quantity: 0 },
 { name: "樱桃", type: "水果", quantity: 5 }
 ],
 ok: [
 { name: "山羊", type: "肉", quantity: 23 },
 { name: "鱼", type: "肉", quantity: 22 }
 ]
}
\*/
```

规范
--

| Specification |
| --- |
| Array Grouping # sec-object.groupby |

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

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

参见
--

* `core-js` 中 `Object.groupBy` 的 polyfill
* 索引集合类
* `Array.prototype.reduce()`
* `Object.fromEntries()`
* `Map.groupBy()`


Object.prototype.toLocaleString() - JavaScript

Object.prototype.toLocaleString()
=================================

**`toLocaleString()`** 方法返回一个表示对象的字符串。该方法旨在由派生对象重写，以达到其特定于语言环境的目的。

尝试一下
----

语法
--

```js
toLocaleString()
```

### 参数

没有参数。但是，重写此方法的所有对象最多只能接受两个参数，分别对应于 `locales` 和 `options`，例如 `Date.prototype.toLocaleString`。这些参数位置不应该用于任何其他目的。

### 返回值

调用 `this.toString()` 的返回值。

描述
--

所有继承 `Object.prototype`（也就是说，除了 `null` 原型对象）的对象都继承了 `toLocaleString()` 方法。`Object` 的 `toLocaleString` 返回调用 `this.toString()` 的结果。

提供此方法是为了给对象一个通用的 `toLocaleString` 方法，即使不是所有对象都会使用它。在核心语言中，这些内置对象重写了 `toLocaleString` 以提供特定于语言环境的格式：

* `Array`：`Array.prototype.toLocaleString()`
* `Number`：`Number.prototype.toLocaleString()`
* `Date`：`Date.prototype.toLocaleString()`
* `TypedArray`：`TypedArray.prototype.toLocaleString()`
* `BigInt`：`BigInt.prototype.toLocaleString()`
示例
--

### 使用基本的 toLocaleString() 方法

基本的 `toLocaleString()` 方法只是简单地调用 `toString()`。

```js
const obj = {
  toString() {
    return "My Object";
  },
};
console.log(obj.toLocaleString()); // "My Object"
```

### Array 重写的 toLocaleString()

`Array.prototype.toLocaleString()` 用于将数组值打印成字符串，通过调用每个元素的 `toLocaleString()` 方法，并使用特定于语言环境的分隔符拼接。例如：

```js
const testArray = [4, 7, 10];

const euroPrices = testArray.toLocaleString("fr", {
  style: "currency",
  currency: "EUR",
});
// "4,00 €,7,00 €,10,00 €"
```

### Date 重写的 toLocaleString()

`Date.prototype.toLocaleString()` 用于打印成更适合特定语言环境的日期显示。例如：

```js
const testDate = new Date();
// "Fri May 29 2020 18:04:24 GMT+0100 (British Summer Time)"

const deDate = testDate.toLocaleString("de");
// "29.5.2020, 18:04:24"

const frDate = testDate.toLocaleString("fr");
// "29/05/2020, 18:04:24"
```

### Number 重写的 toLocaleString()

`Number.prototype.toLocaleString()` 用于打印成更适合特定语言环境的数字显示，例如使用正确的分隔符。例如：

```js
const testNumber = 2901234564;
// "2901234564"

const deNumber = testNumber.toLocaleString("de");
// "2.901.234.564"

const frNumber = testNumber.toLocaleString("fr");
// "2 901 234 564"
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.tolocalestring |

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

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

参见
--

* `Object.prototype.toString()`


Object.getOwnPropertyDescriptor() - JavaScript

Object.getOwnPropertyDescriptor()
=================================

**`Object.getOwnPropertyDescriptor()`** 静态方法返回一个对象，该对象描述给定对象上特定属性（即直接存在于对象上而不在对象的原型链中的属性）的配置。返回的对象是可变的，但对其进行更改不会影响原始属性的配置。

尝试一下
----

语法
--

```js
Object.getOwnPropertyDescriptor(obj, prop)
```

### 参数

`obj`

要查找其属性的对象。

`prop`

要检索其描述的属性的名称或 `Symbol`。

### 返回值

如果指定的属性存在于对象上，则返回其属性描述符，否则返回 `undefined`。

描述
--

该方法允许查看属性的精确描述。在 JavaScript 中，一个*属性*由一个字符串值的名称或一个 `Symbol` 和一个属性描述符组成。关于属性描述符类型及其特性的更多信息可以在 `Object.defineProperty()` 中找到。

一个*属性描述符*是一个记录，具有以下一些特性：

`value`

与属性关联的值（仅限数据描述符）。

`writable`

当且仅当与属性关联的值可以更改时，为 `true`（仅限数据描述符）。

`get`

作为属性 getter 的函数，如果没有 getter 则为 `undefined`（仅限访问器描述符）。

`set`

作为属性 setter 的函数，如果没有 setter 则为 `undefined`（仅限访问器描述符）。

`configurable`

当且仅当此属性描述符的类型可以更改且该属性可以从相应对象中删除时，为 `true`。

`enumerable`

当且仅当此属性在相应对象的属性枚举中出现时，为 `true`。

示例
--

### 使用 Object.getOwnPropertyDescriptor()

```js
let o, d;

o = {
  get foo() {
    return 17;
  },
};
d = Object.getOwnPropertyDescriptor(o, "foo");
console.log(d);
// {
// configurable: true,
// enumerable: true,
// get: [Function: get foo],
// set: undefined
// }

o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
console.log(d);
// {
// configurable: true,
// enumerable: true,
// value: 42,
// writable: true
// }

o = { [Symbol.for("baz")]: 73 };
d = Object.getOwnPropertyDescriptor(o, Symbol.for("baz"));
console.log(d);
// {
// configurable: true,
// enumerable: true,
// value: 73,
// writable: true
// }

o = {};
Object.defineProperty(o, "qux", {
  value: 8675309,
  writable: false,
  enumerable: false,
});
d = Object.getOwnPropertyDescriptor(o, "qux");
console.log(d);
// {
// value: 8675309,
// writable: false,
// enumerable: false,
// configurable: false
// }
```

非对象强制转换
-------

在 ES5 中，如果该方法的第一个参数不是对象（而是一个基本类型值），则会导致 `TypeError`。在 ES2015 中，首先会将非对象的第一个参数强制转换为对象。

```js
Object.getOwnPropertyDescriptor("foo", 0);
// TypeError: "foo" is not an object // ES5 code

Object.getOwnPropertyDescriptor("foo", 0);
// Object returned by ES2015 code: {
// configurable: false,
// enumerable: true,
// value: "f",
// writable: false
// }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.getownpropertydescriptor |

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

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

参见
--

* `Object.defineProperty()`
* `Reflect.getOwnPropertyDescriptor()`


Object.hasOwn() - JavaScript

Object.hasOwn()
===============

如果指定的对象*自身*有指定的属性，则静态方法 **`Object.hasOwn()`** 返回 `true`。如果属性是继承的或者不存在，该方法返回 `false`。

**备注：** `Object.hasOwn()` 旨在取代 `Object.prototype.hasOwnProperty()`。

尝试一下
----

语法
--

```js
Object.hasOwn(obj, prop)
```

### 参数

`obj`

要测试的 JavaScript 实例对象。

`prop`

要测试属性的 `String` 类型的名称或者 Symbol。

### 返回值

如果指定的对象中直接定义了指定的属性，则返回 `true`；否则返回 `false`。

描述
--

如果指定的属性是该对象的直接属性——**`Object.hasOwn()`** 方法返回 `true`，即使属性值是 `null` 或 `undefined`。如果属性是继承的或者不存在，该方法返回 `false`。它不像 `in` 运算符，这个方法不检查对象的原型链中的指定属性。

建议使用此方法替代 `Object.prototype.hasOwnProperty()`，因为它适用于使用 `Object.create(null)` 创建的对象，以及重写了继承的 `hasOwnProperty()` 方法的对象。尽管可以通过在外部对象上调用 `Object.prototype.hasOwnProperty()` 解决这些问题，但是 `Object.hasOwn()` 更加直观。

示例
--

### 使用 hasOwn 去测试属性是否存在

以下代码展示了如何确定 `example` 对象中是否包含名为 `prop` 的属性。

```js
const example = {};
Object.hasOwn(example, "prop"); // false——目标对象的属性 'prop' 未被定义

example.prop = "exists";
Object.hasOwn(example, "prop"); // true——目标对象的属性 'prop' 已被定义

example.prop = null;
Object.hasOwn(example, "prop"); // true——目标对象本身的属性存在，值为 null

example.prop = undefined;
Object.hasOwn(example, "prop"); // true——目标对象本身的属性存在，值为 undefined
```

### 直接属性和继承属性

以下示例区分了直接属性和通过原型链继承的属性：

```js
const example = {};
example.prop = "exists";

// `hasOwn` 静态方法只会对目标对象的直接属性返回 true：
Object.hasOwn(example, "prop"); // 返回 true
Object.hasOwn(example, "toString"); // 返回 false
Object.hasOwn(example, "hasOwnProperty"); // 返回 false

// `in` 运算符对目标对象的直接属性或继承属性均会返回 true：
"prop" in example; // 返回 true
"toString" in example; // 返回 true
"hasOwnProperty" in example; // 返回 true
```

### 迭代对象的属性

要迭代对象的可枚举属性，你*应该*这样使用：

```js
const example = { foo: true, bar: true };
for (const name of Object.keys(example)) {
  // …
}
```

但是如果你使用 `for...in`，你应该使用 `Object.hasOwn()` 跳过继承属性：

```js
const example = { foo: true, bar: true };
for (const name in example) {
  if (Object.hasOwn(example, name)) {
    // …
  }
}
```

### 检查数组索引是否存在

`Array` 中的元素被定义为直接属性，所以你可以使用 `hasOwn()` 方法去检查一个指定的索引是否存在：

```js
const fruits = ["Apple", "Banana", "Watermelon", "Orange"];
Object.hasOwn(fruits, 3); // true ('Orange')
Object.hasOwn(fruits, 4); // false——没有定义的
```

### hasOwnProperty 的问题案例

本部分证明了影响 `hasOwnProperty` 的问题对 `hasOwn()` 是免疫的。首先，它可以与重新实现的 `hasOwnProperty()` 一起使用：

```js
const foo = {
  hasOwnProperty() {
    return false;
  },
  bar: "The dragons be out of office",
};

if (Object.hasOwn(foo, "bar")) {
  console.log(foo.bar); //true——重新实现 hasOwnProperty() 不会影响 Object
}
```

它也可以用于测试使用 `Object.create(null)` 创建的对象。这些对象不会继承自 `Object.prototype`，因此 `hasOwnProperty()` 方法是无法访问的。

```js
const foo = Object.create(null);
foo.prop = "exists";
if (Object.hasOwn(foo, "prop")) {
  console.log(foo.prop); //true——无论对象是如何创建的，它都可以运行。
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.hasown |

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

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

参见
--

* 在 `core-js` 中 `Object.hasOwn` 的 Polyfill
* `Object.hasOwnProperty()`
* 属性的可枚举性和所有权
* `Object.getOwnPropertyNames()`
* `for...in`
* `in`
* JavaScript 指南：重新审视继承


Object.prototype.isPrototypeOf() - JavaScript

Object.prototype.isPrototypeOf()
================================

**`isPrototypeOf()`** 方法用于检查一个对象是否存在于另一个对象的原型链中。

**备注：** `isPrototypeOf()` 与 `instanceof` 运算符不同。在表达式 `object instanceof AFunction` 中，会检查 `object` 的原型链是否与 `AFunction.prototype` 匹配，而不是与 `AFunction`本身匹配。

尝试一下
----

语法
--

```js
isPrototypeOf(object)
```

### 参数

`object`

要搜索其原型链的对象。

### 返回值

一个布尔值，指示调用 `isPrototypeOf()` 方法的对象（即 `this`）是否位于 `object` 的原型链中。当 `object` 不是一个对象（即基本类型）时，直接返回 `false`。

### 报错

`TypeError`

如果 `prototypeObj` 为 undefined 或 null，会抛出 `TypeError`。

描述
--

所有继承自 `Object.prototype` 的对象（即除了 `null` 原型对象之外的所有对象）都继承了 `isPrototypeOf()` 方法。该方法允许你检查对象是否存在于另一个对象的原型链中。如果作为参数的 `object` 不是对象（即基本类型），则该方法直接返回 `false`。否则，`this` 值被转换为对象，并且在 `object` 的原型链中搜索 `this` 值，直到到达链的末端或找到 `this` 值为止。

示例
--

### 使用 isPrototypeOf()

本示例展示了 `Baz.prototype`、`Bar.prototype`、`Foo.prototype` 和 `Object.prototype` 存在于对象 `baz` 的原型链中：

```js
class Foo {}
class Bar extends Foo {}
class Baz extends Bar {}

const foo = new Foo();
const bar = new Bar();
const baz = new Baz();

// 原型链：
// foo: Foo --> Object
// bar: Bar --> Foo --> Object
// baz: Baz --> Bar --> Foo --> Object
console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Baz.prototype.isPrototypeOf(bar)); // false
console.log(Baz.prototype.isPrototypeOf(foo)); // false
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(foo)); // false
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(bar)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true
```

`isPrototypeOf()` 方法以及 `instanceof` 运算符在处理从特定原型链继承的对象时非常有用，例如，为了保证该对象上存在特定的方法或属性。

例如，如果只有当 `baz` 对象的原型链中包含 `Foo.prototype` 时才能执行某些代码，可以这样实现：

```js
if (Foo.prototype.isPrototypeOf(baz)) {
  // 执行安全操作
}
```

然而，`Foo.prototype` 存在于 `baz` 的原型链中并不意味着 `baz` 是使用 `Foo` 作为其构造函数创建的。例如，`baz` 可以直接将 `Foo.prototype` 作为其原型。在这种情况下，如果你的代码从 `baz` 中读取 `Foo` 的私有属性，它仍然会失败：

```js
class Foo {
  #value = "foo";
  static getValue(x) {
    return x.#value;
  }
}

const baz = { \_\_proto\_\_: Foo.prototype };

if (Foo.prototype.isPrototypeOf(baz)) {
  console.log(Foo.getValue(baz)); // TypeError: Cannot read private member #value from an object whose class did not declare it
}
```

对于 `instanceof` 也是同样的情况。如果你需要以安全的方式读取私有属性，可以提供一个使用 `in` 运算符的特定类型检查（branded check）方法。

```js
class Foo {
  #value = "foo";
  static getValue(x) {
    return x.#value;
  }
  static isFoo(x) {
    return #value in x;
  }
}

const baz = { \_\_proto\_\_: Foo.prototype };

if (Foo.isFoo(baz)) {
  // 不会运行，因为 baz 不是 Foo
  console.log(Foo.getValue(baz));
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.isprototypeof |

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

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

参见
--

* `instanceof`
* `Object.getPrototypeOf()`
* `Object.setPrototypeOf()`
* 继承与原型链


Object.prototype.constructor - JavaScript

Object.prototype.constructor
============================

`Object` 实例的 **`constructor`** 数据属性返回一个引用，指向创建该实例对象的构造函数。注意，此属性的值是对*函数本身*的引用，而不是一个包含函数名称的字符串。

**备注：** 这是 JavaScript 对象的一个属性。关于类的 `constructor` 方法，请参见其参考页面。

值
-

对创建该实例对象的构造函数的引用。

| `Object.prototype.constructor` 的属性特性 |
| --- |
| 可写 | 是 |
| 可枚举 | 否 |
| 可配置 | 是 |

**备注：** 这个属性默认会在每个构造函数的 `prototype` 属性上创建，并由该构造函数创建的所有对象继承。

描述
--

除了 `null` 原型对象之外，任何对象都会在其 `[[Prototype]]` 上有一个 `constructor` 属性。使用字面量创建的对象也会有一个指向该对象构造函数类型的 `constructor` 属性，例如，数组字面量创建的 `Array` 对象和对象字面量创建的普通对象。

```js
const o1 = {};
o1.constructor === Object; // true

const o2 = new Object();
o2.constructor === Object; // true

const a1 = [];
a1.constructor === Array; // true

const a2 = new Array();
a2.constructor === Array; // true

const n = 3;
n.constructor === Number; // true
```

请注意，`constructor` 属性通常来自构造函数的 `prototype` 属性。如果你有一个更长的原型链，通常可以假定链中的每个对象都有一个 `constructor` 属性。

```js
const o = new TypeError(); // 继承关系：TypeError -> Error -> Object
const proto = Object.getPrototypeOf;
proto(o).constructor === TypeError; // true
proto(proto(o)).constructor === Error; // true
proto(proto(proto(o))).constructor === Object; // true
```

示例
--

### 打印对象的构造函数

下面这个示例创建一个构造函数（`Tree`），以及该类型的对象（`theTree`）。然后打印了 `theTree` 对象的 `constructor` 属性。

```js
function Tree(name) {
  this.name = name;
}

const theTree = new Tree("Redwood");
console.log(`theTree.constructor 是 ${theTree.constructor}`);
```

这个示例会打印以下输出：
```

theTree.constructor 是 function Tree(name) {
  this.name = name;
}
```

### 为对象的 constructor 属性赋值

可以为非基本类型对象的 `constructor` 属性赋值。

```js
const arr = [];
arr.constructor = String;
arr.constructor === String; // true
arr instanceof String; // false
arr instanceof Array; // true

const foo = new Foo();
foo.constructor = "bar";
foo.constructor === "bar"; // true

// 等等…
```

这不会覆盖旧的 `constructor` 属性——它实际上存在于实例的 `[[Prototype]]` 中，而不是作为其自有属性。

```js
const arr = [];
Object.hasOwn(arr, "constructor"); // false
Object.hasOwn(Object.getPrototypeOf(arr), "constructor"); // true

arr.constructor = String;
Object.hasOwn(arr, "constructor"); // true——实例属性会覆盖原型链上的同名属性
```

但是，即使对 `Object.getPrototypeOf(a).constructor` 重新赋值，它也不会改变对象的其他行为。例如，`instanceof` 的行为由 `Symbol.hasInstance` 控制，而不是由 `constructor` 控制：

```js
const arr = [];
arr.constructor = String;
arr instanceof String; // false
arr instanceof Array; // true
```

`constructor` 属性没有受到保护，可以被重新赋值或被覆盖，因此在检测变量类型时，通常应避免使用它，而应该使用更不易出错的方法，如对于对象使用 `instanceof` 和 `Symbol.toStringTag`，对于基本类型使用 `typeof`。

### 更改构造函数原型对象的 constructor 属性

每个构造函数都有一个 `prototype` 属性，当通过 `new` 运算符调用时，该属性将成为实例的 `[[Prototype]]`。因此，`ConstructorFunction.prototype.constructor` 将成为实例的 `[[Prototype]]` 上的属性，如前面所述。

然而，如果对 `ConstructorFunction.prototype` 重新赋值，`constructor` 属性将丢失。例如，以下是创建继承模式的常见方式：

```js
function Parent() {
  // …
}
Parent.prototype.parentMethod = function () {};

function Child() {
  Parent.call(this); // 确保所有内容都已正确初始化
}
// 将 Child.prototype 的 [[Prototype]] 指向 Parent.prototype
Child.prototype = Object.create(Parent.prototype);
```

由于重新赋值了 `Child.prototype`，`Child` 实例的 `constructor` 将是 `Parent`。

通常情况下，这不是什么大问题——JavaScript 几乎从不读取对象的 `constructor` 属性。唯一的例外是在使用 `@@species` 创建类的新实例时，但这种情况很少见，并且你应该使用 `extends` 语法来子类化内置对象。

然而，在某些调用使用 `constructor` 从实例中访问原始类时，确保 `Child.prototype.constructor` 总是指向 `Child` 本身非常重要。考虑这种情况：对象具有 `create()` 方法来创建自身。

```js
function Parent() {
  // …
}
function CreatedConstructor() {
  Parent.call(this);
}

CreatedConstructor.prototype = Object.create(Parent.prototype);

CreatedConstructor.prototype.create = function () {
  return new this.constructor();
};

new CreatedConstructor().create().create(); // TypeError: new CreatedConstructor().create().create is undefined，因为 constructor === Parent
```

在上面的示例中，会抛出一个异常，因为 `constructor` 链接到 `Parent`。为了避免这种情况，只需将其赋值为你将要使用的必要构造函数即可。

```js
function Parent() {
  // …
}
function CreatedConstructor() {
  // …
}

CreatedConstructor.prototype = Object.create(Parent.prototype, {
  // 将原始构造函数返回给 Child
  constructor: {
    value: CreatedConstructor,
    enumerable: false, // 使其不可枚举，这样它就不会出现在 `for...in` 循环中
    writable: true,
    configurable: true,
  },
});

CreatedConstructor.prototype.create = function () {
  return new this.constructor();
};

new CreatedConstructor().create().create(); // 跑起来没毛病
```

请注意，当手动添加 `constructor` 属性时，将属性设置为不可枚举非常重要，这将确保 `constructor` 就不会在 `for...in` 循环中被访问——尽管通常情况下不会被访问。

如果上面的代码看起来太死板，你也可以考虑使用 `Object.setPrototypeOf()` 来操作原型链。

```js
function Parent() {
  // …
}
function CreatedConstructor() {
  // …
}

Object.setPrototypeOf(CreatedConstructor.prototype, Parent.prototype);

CreatedConstructor.prototype.create = function () {
  return new this.constructor();
};

new CreatedConstructor().create().create(); // 在不重新创建 constructor 属性的情况下仍然有效
```

`Object.setPrototypeOf()` 存在潜在的性能缺陷，因为所有先前创建的涉及该原型链的对象都必须重新编译；但是，如果上述初始化代码发生在 `Parent` 或 `CreatedConstructor` 构造之前，其影响应该是很小的。

接下来，看另外一个相关示例。

```js
function ParentWithStatic() {}

ParentWithStatic.startPosition = { x: 0, y: 0 }; // 静态成员属性
ParentWithStatic.getStartPosition = function () {
  return this.startPosition;
};

function Child(x, y) {
  this.position = { x, y };
}

Child.prototype = Object.create(ParentWithStatic.prototype, {
  // 将原始构造函数返回给 Child
  constructor: {
    value: Child,
    enumerable: false,
    writable: true,
    configurable: true,
  },
});

Child.prototype.getOffsetByInitialPosition = function () {
  const position = this.position;
  // 使用 `this.constructor`，以期 `getStartPosition` 存在于一个静态方法中。
  const startPosition = this.constructor.getStartPosition();

  return {
    offsetX: startPosition.x - position.x,
    offsetY: startPosition.y - position.y,
  };
};

new Child(1, 1).getOffsetByInitialPosition();
// Error: this.constructor.getStartPosition is undefined，
// 因为构造函数是 Child，它没有 getStartPosition 静态方法
```

如果想要保证示例正常运行，我们需要让 `Parent` 作为构造函数，或给 `Child` 的构造分配静态属性：

```js
// …
Object.assign(Child, ParentWithStatic); // 注意，在创建 Child 的原型前我们先分配它的值
Child.prototype = Object.create(ParentWithStatic.prototype, {
  // 将原始构造函数返回给 Child
  constructor: {
    value: Child,
    enumerable: false,
    writable: true,
    configurable: true,
  },
});
// …
```

但更好的方法是，我们可以使构造函数本身相互继承，就像类的 `extends` 一样。

```js
function ParentWithStatic() {}

ParentWithStatic.startPosition = { x: 0, y: 0 }; // 静态成员属性
ParentWithStatic.getStartPosition = function () {
  return this.startPosition;
};

function Child(x, y) {
  this.position = { x, y };
}

// 正确地创建继承关系！
Object.setPrototypeOf(Child.prototype, ParentWithStatic.prototype);
Object.setPrototypeOf(Child, ParentWithStatic);

Child.prototype.getOffsetByInitialPosition = function () {
  const position = this.position;
  const startPosition = this.constructor.getStartPosition();

  return {
    offsetX: startPosition.x - position.x,
    offsetY: startPosition.y - position.y,
  };
};

console.log(new Child(1, 1).getOffsetByInitialPosition()); // { offsetX: -1, offsetY: -1 }
```

再次强调，使用 `Object.setPrototypeOf()` 可能会对性能产生不利影响，因此请确保它仅在必要时使用，并在构造函数声明后立即使用，并在创建任何实例之前使用，以避免对象被“污染”。

**备注：** 设置或更新构造函数可能会导致结果不同且令人困惑的结果。为了防止它，只需在特定情况下定义 `constructor`。多数情况，不使用 `constructor`，并且不需要重新对其赋值。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.constructor |

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

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

参见
--

* Class declaration
* Class constructor
* 术语：constructor


Object.isSealed() - JavaScript

Object.isSealed()
=================

**`Object.isSealed()`** 静态方法判断一个对象是否被密封。

尝试一下
----

语法
--

```js
Object.isSealed(obj)
```

### 参数

`obj`

要被检查的对象。

### 返回值

一个表示给定对象是否被密封的布尔值。

描述
--

如果这个对象是密封的，则返回 `true`，否则返回 `false`。密封对象是指那些不可扩展的，且所有自有属性都不可配置且因此不可删除（但不一定是不可写）的对象。

示例
--

### 使用 Object.isSealed()

```js
// 新建的对象默认不是密封的。
const empty = {};
Object.isSealed(empty); // false

// 如果你令一个空对象不可扩展，则它同时也会变成个密封对象。
Object.preventExtensions(empty);
Object.isSealed(empty); // true

// 但如果这个对象不是空对象，则它不会变成密封对象，因为密封对象的所有自身属性必须是不可配置的。
const hasProp = { fee: "fie foe fum" };
Object.preventExtensions(hasProp);
Object.isSealed(hasProp); // false

// 如果把这个属性变的不可配置，则这个属性也就成了密封对象。
Object.defineProperty(hasProp, "fee", {
  configurable: false,
});
Object.isSealed(hasProp); // true

// 密封一个对象最简单的方法当然是 Object.seal。
const sealed = {};
Object.seal(sealed);
Object.isSealed(sealed); // true

// 根据定义，密封对象是不可扩展的。
Object.isExtensible(sealed); // false

// 一个密封对象可能被冻结，但不一定。
Object.isFrozen(sealed); // true
//（所有属性也是不可写的）

const s2 = Object.seal({ p: 3 });
Object.isFrozen(s2); // false
//（'p' 仍然可写）

const s3 = Object.seal({
  get p() {
    return 0;
  },
});
Object.isFrozen(s3); // true
//（对于访问器属性，只有可配置性才有影响）
```

非对象参数
-----

在 ES5 中，如果该方法的参数不是一个对象（而是一个基本类型值），则会引发 `TypeError` 异常。在 ES2015 中，如果传递一个非对象参数，则该方法将返回 `true` 而不会产生任何错误，因为按照定义，基本类型值是不可变的。

```js
Object.isSealed(1);
// TypeError: 1 is not an object (ES5 code)

Object.isSealed(1);
// true (ES2015 code)
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.issealed |

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

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

参见
--

* `Object.seal()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.freeze()`
* `Object.isFrozen()`


Object.setPrototypeOf() - JavaScript

Object.setPrototypeOf()
=======================

**`Object.setPrototypeOf()`** 静态方法可以将一个指定对象的原型（即内部的 `[[Prototype]]` 属性）设置为另一个对象或者 `null`。

**警告：** 由于现代 JavaScript 引擎优化属性访问所带来的特性的关系，更改对象的 `[[Prototype]]` 在各个浏览器和 JavaScript 引擎上都是一个很慢的操作。此外，修改继承的影响是微妙和广泛的，并不仅限于在 `Object.setPrototypeOf(...)` 语句上的时间花费，而是可能扩展到*任何*访问已更改 `[[Prototype]]` 属性的对象的代码。你可以在 JavaScript 引擎基础知识：优化原型中了解更多信息。

由于这个特性是语言的一部分，因此引擎开发人员实现该特性的性能（理想情况下）仍然是一个负担。在引擎开发人员解决这个问题之前，如果你担心性能问题，应该避免设置对象的 `[[Prototype]]` 属性。而是使用 `Object.create()` 创建一个具有所需 `[[Prototype]]` 属性的新对象。

尝试一下
----

语法
--

```js
Object.setPrototypeOf(obj, prototype)
```

### 参数

`obj`

要设置其原型的对象。

`prototype`

该对象的新原型（一个对象或 `null`）。

### 返回值

指定的对象。

异常
--

`TypeError`

如果发生以下情况中的任何一个，则抛出该异常：

* `obj` 参数为 `undefined` 或 `null`。
* `obj` 参数是不可扩展的，或者它是一个不可修改原型的特异对象，例如 `Object.prototype` 或 `window`。但是，如果新原型与 `obj` 的原始原型具有相同的值，则不会抛出错误。
* `prototype` 参数不是对象或 `null`。

描述
--

通常，作为正确的方式，应该使用 `Object.setPrototypeOf()` 方法来设置对象的原型。因为 `Object.prototype.__proto__` 访问器已被弃用。

如果 `obj` 参数不是对象（例如数字、字符串等），则该方法不执行任何操作——无需将其强制转换为对象或尝试设置其原型——直接将 `obj` 作为原始值返回。如果 `prototype` 的值与 `obj` 的原型相同，则直接返回 `obj`，即使 `obj` 具有不可变的原型，也不会抛出 `TypeError` 错误。

出于安全考虑，某些内置对象的原型被设计为是*不可变的*。这可以防止原型污染攻击，尤其是与代理有关的攻击。核心语言仅指定 `Object.prototype` 是不可变原型的特异对象，其原型始终为 `null`。而在浏览器中，`window` 和 `location` 也是（常见的）不可变原型的特异对象。

```js
Object.isExtensible(Object.prototype); // true；你可以添加更多属性
Object.setPrototypeOf(Object.prototype, {}); // TypeError: Immutable prototype object '#<Object>' cannot have their prototype set
Object.setPrototypeOf(Object.prototype, null); // 没有错误；`Object.prototype` 的原型已经是 `null`
```

示例
--

### 使用 Object.setPrototypeOf() 实现伪类继承

JS 中可以这样实现类继承。

```js
class Human {}
class SuperHero extends Human {}

const superMan = new SuperHero();
```

但是，如果我们想要在不使用 `class` 的情况下实现子类，我们可以这么做：

```js
function Human(name, level) {
  this.name = name;
  this.level = level;
}

function SuperHero(name, level) {
  Human.call(this, name, level);
}

Object.setPrototypeOf(SuperHero.prototype, Human.prototype);

// 将 `SuperHero.prototype` 的 `[[Prototype]]` 设置为 `Human.prototype` 以设置原型继承链

Human.prototype.speak = function () {
  return `${this.name} says hello.`;
};

SuperHero.prototype.fly = function () {
  return `${this.name} is flying.`;
};

const superMan = new SuperHero("Clark Kent", 1);

console.log(superMan.fly());
console.log(superMan.speak());
```

上面的类继承（使用 class）和伪类继承（使用带有 `prototype` 属性的构造函数）的相似性已在继承与原型链中提到。

由于函数构造函数的 `prototype` 属性是可写的，因此你可以将其重新分配为一个使用 `Object.create()` 创建的新对象，以实现相同的继承链。但是，在使用 `create()` 时需要注意一些事项，例如记得重新添加 `constructor` 属性。

在下面的示例中，也使用了类，`SuperHero` 使用 `setPrototypeOf` 而不是 `extends` 来继承 `Human`。

**警告：** 由于性能和可读性的原因，不建议使用 `setPrototypeOf` 来代替 `extends`。

```js
class Human {}
class SuperHero {}

// 设置实例属性
Object.setPrototypeOf(SuperHero.prototype, Human.prototype);

// 连接静态属性
Object.setPrototypeOf(SuperHero, Human);

const superMan = new SuperHero();
```

ES-6 子类派生中提到了不使用 `extends` 的子类派生方法。

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.setprototypeof |

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

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

参见
--

* `core-js` 中关于 `Object.setPrototypeOf` 的 Polyfill
* `Reflect.setPrototypeOf()`
* `Object.prototype.isPrototypeOf()`
* `Object.getPrototypeOf()`
* `Object.prototype.__proto__`
* 继承与原型链
* ES-6 子类派生


Object.prototype.__lookupSetter__() - JavaScript

Object.prototype.\_\_lookupSetter\_\_()
=======================================

**已弃用:** 不再推荐使用该特性。虽然一些浏览器仍然支持它，但也许已从相关的 web 标准中移除，也许正准备移除或出于兼容性而保留。请尽量不要使用该特性，并更新现有的代码；参见本页面底部的兼容性表格以指导你作出决定。请注意，该特性随时可能无法正常工作。

**备注：** 该方法已被弃用，建议使用 `Object.getOwnPropertyDescriptor()` API。该方法的行为只针对 Web 兼容性进行了规定，在任何平台上都不需要实现该方法。它可能无法在所有地方正常工作。

**`__lookupGetter__()`** 方法返回绑定到指定属性的 setter 函数。

语法
--

```js
\_\_lookupSetter\_\_(prop)
```

### 参数

`prop`

包含应返回其 setter 的属性名称的字符串。

### 返回值

绑定到指定属性的 setter 函数。如果找不到这样的属性或者该属性是数据属性，则返回 `undefined`。

描述
--

所有继承自 `Object.prototype` 的对象（也就是除了 `null` 原型对象的对象）都会继承 `__lookupSetter__()` 方法。如果为对象的属性定义了一个 setter，则无法通过该属性引用 setter 函数，因为该属性引用该函数的返回值。`__lookupSetter__()` 可用于获取对 setter 函数的引用。

`__lookupSetter__()` 沿着原型链向上查找指定的属性。如果原型链上的任何对象具有指定的自有属性，则返回该属性的属性描述符的 `set` 属性。如果该属性是数据属性，则返回 `undefined`。如果在整个原型链上都找不到该属性，也同样返回 `undefined`。

`__lookupSetter__()` 在规范中被定义为“可选规范”，这意味着不需要任何实现来实现它。然而，所有主要的浏览器都实现了它，并且由于它的持续使用，它不太可能被删除。如果浏览器实现了 `__lookupSetter__()`，它还需要实现 `__lookupGetter__()`、`__defineGetter__()` 和 `__defineSetter__()` 方法。

示例
--

### 使用 \_\_lookupSetter\_\_()

```js
const obj = {
  set foo(value) {
    this.bar = value;
  },
};

obj.\_\_lookupSetter\_\_("foo");
// [Function: set foo]
```

### 以标准方式查找属性的 setter

你应该使用 `Object.getOwnPropertyDescriptor()` API 来查找属性的 setter。与 `__lookupSetter__()` 相比，该方法允许查找 Symbol 属性。`Object.getOwnPropertyDescriptor()` 方法还适用于 `null` 原型对象，它们不继承自 `Object.prototype`，因此没有 `__lookupSetter__()` 方法。如果 `__lookupSetter__()` 沿着原型链向上查找属性的行为很重要，则可以使用 `Object.getPrototypeOf()` 自行实现它。

```js
const obj = {
  set foo(value) {
    this.bar = value;
  },
};

Object.getOwnPropertyDescriptor(obj, "foo").set;
// [Function: set foo]
```

```js
const obj2 = {
  \_\_proto\_\_: {
    set foo(value) {
      this.bar = value;
    },
  },
};

function findSetter(obj, prop) {
  while (obj) {
    const desc = Object.getOwnPropertyDescriptor(obj, "foo");
    if (desc) {
      return desc.set;
    }
    obj = Object.getPrototypeOf(obj);
  }
}

console.log(findSetter(obj2, "foo")); // [Function: set foo]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.\_\_lookupSetter\_\_ |

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

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

参见
--

* `core-js` 中 `Object.prototype.__lookupSetter__` 的 polyfill
* `Object.prototype.__lookupGetter__()`
* `set` 语法
* `Object.getOwnPropertyDescriptor()` 和 `Object.getPrototypeOf()`
* `Object.prototype.__defineGetter__()`
* `Object.prototype.__defineSetter__()`
* JS 指南：定义 Getter 和 Setter


Object.seal() - JavaScript

Object.seal()
=============

**`Object.seal()`** 静态方法*密封*一个对象。密封一个对象会阻止其扩展并且使得现有属性不可配置。密封对象有一组固定的属性：不能添加新属性、不能删除现有属性或更改其可枚举性和可配置性、不能重新分配其原型。只要现有属性的值是可写的，它们仍然可以更改。`seal()` 返回传入的同一对象。

尝试一下
----

语法
--

```js
Object.seal(obj)
```

### 参数

`obj`

要密封的对象。

### 返回值

被密封的对象。

描述
--

密封一个对象等价于阻止其扩展，然后将现有的属性描述符更改为 `configurable: false`。这会使对象上的属性集固定。令对象的所有属性不可配置且可以防止它们从数据属性转换成访问器属性，反之亦然，但它不会防止数据属性的值被更改。尝试删除或者向密封对象添加属性，或者将数据属性和访问器属性互相转换，都将失败，可能会静默失败，也可能会抛出 `TypeError`（最常见的是在严格模式代码中，但不仅限于此）。

原型链保持不变。然而，由于扩展被阻止，`[[Prototype]]` 不能重新赋值。

不同于 `Object.freeze()` 的是，通过 `Object.seal()` 密封的对象可以更改其现有属性，只要它们是可写的。

示例
--

### 使用 Object.seal()

```js
const obj = {
  prop() {},
  foo: "bar",
};

// 可以添加新属性，可以更改或删除现有属性。
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;

const o = Object.seal(obj);

o === obj; // true
Object.isSealed(obj); // true

// 更改密封对象的属性值仍然有效。
obj.foo = "quux";

// 但不能将数据属性转换成访问者属性，反之亦然。
Object.defineProperty(obj, "foo", {
  get() {
    return "g";
  },
}); // 抛出 TypeError

// 现在，除了属性值之外的任何更改都将失败。
obj.quaxxor = "the friendly duck";
// 静默不添加属性
delete obj.foo;
// 静默不添删除属性

// ...且严格模式下，这种尝试将会抛出 TypeError。
function fail() {
  "use strict";
  delete obj.foo; // 抛出一个 TypeError
  obj.sparky = "arf"; // 抛出一个 TypeError
}
fail();

// 尝试通过 Object.defineProperty 添加属性也会抛出错误。
Object.defineProperty(obj, "ohai", {
  value: 17,
}); // 抛出 TypeError
Object.defineProperty(obj, "foo", {
  value: "eit",
}); // 更改现有属性值
```

### 非对象参数

在 ES5 中，如果该方法的参数不是一个对象（即基本类型），它将会抛出 `TypeError`。在 ES2015 中，非对象参数将按原样返回，不会有任何错误，因为根据定义，基本类型已经是不可变的。

```js
Object.seal(1);
// TypeError: 1 is not an object (ES5 code)

Object.seal(1);
// 1 (ES2015 code)
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.seal |

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

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

参见
--

* `Object.isSealed()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.freeze()`
* `Object.isFrozen()`


Object.isFrozen() - JavaScript

Object.isFrozen()
=================

**`Object.isFrozen()`** 静态方法判断一个对象是否被冻结。

尝试一下
----

语法
--

```js
Object.isFrozen(obj)
```

### 参数

`obj`

要检测的对象。

### 返回值

指示给定对象是否被冻结的布尔值。

描述
--

一个对象，当且仅当它不可拓展，且所有属性都是不可配置的，所有的数据属性（即不是有 getter 或 setter 的访问器属性的属性）都是不可写的时，它就是被冻结的。

示例
--

### 使用 Object.isFrozen()

```js
// 一个新对象是默认是可扩展的，所以它也是非冻结的。
Object.isFrozen({}); // false

// 一个不可扩展的空对象同时也是一个冻结对象。
const vacuouslyFrozen = Object.preventExtensions({});
Object.isFrozen(vacuouslyFrozen); // true

// 一个非空对象默认也是非冻结的。
const oneProp = { p: 42 };
Object.isFrozen(oneProp); // false

// 即使令对象不可扩展，它也不会被冻结，因为属性仍然是可配置的（而且可写的）。
Object.preventExtensions(oneProp);
Object.isFrozen(oneProp); // false

// 此时，如果删除了这个属性，则它会成为一个冻结对象。
delete oneProp.p;
Object.isFrozen(oneProp); // true

// 一个不可扩展的对象，拥有一个不可写但可配置的属性，则它仍然是非冻结的。
const nonWritable = { e: "plep" };
Object.preventExtensions(nonWritable);
Object.defineProperty(nonWritable, "e", {
  writable: false,
}); // 令其不可写
Object.isFrozen(nonWritable); // false

// 把这个属性改为不可配置，会让这个对象成为冻结对象。
Object.defineProperty(nonWritable, "e", {
  configurable: false,
}); // 令其不可配置
Object.isFrozen(nonWritable); // true

// 一个不可扩展的对象，拥有一个不可配置但可写的属性，则它也是非冻结的。
const nonConfigurable = { release: "the kraken!" };
Object.preventExtensions(nonConfigurable);
Object.defineProperty(nonConfigurable, "release", {
  configurable: false,
});
Object.isFrozen(nonConfigurable); // false

// 把这个属性改为不可写，会让这个对象成为冻结对象。
Object.defineProperty(nonConfigurable, "release", {
  writable: false,
});
Object.isFrozen(nonConfigurable); // true

// 一个不可扩展的对象，拥有一个访问器属性，则它仍然是非冻结的。
const accessor = {
  get food() {
    return "yum";
  },
};
Object.preventExtensions(accessor);
Object.isFrozen(accessor); // false

// 把这个属性改为不可配置，会让这个对象成为冻结对象。
Object.defineProperty(accessor, "food", {
  configurable: false,
});
Object.isFrozen(accessor); // true

// 使用 Object.freeze 是冻结一个对象最方便的方法。
const frozen = { 1: 81 };
Object.isFrozen(frozen); // false
Object.freeze(frozen);
Object.isFrozen(frozen); // true

// 根据定义，一个冻结对象是不可拓展的。
Object.isExtensible(frozen); // false

// 同样，根据定义，一个冻结对象也是密封对象。
Object.isSealed(frozen); // true
```

### 非对象参数

在 ES5 中，如果传递给此方法的参数不是一个对象（而是一个基本类型值），则会导致 `TypeError`。在 ES2015 中，如果传递了一个非对象类型的参数，它将返回 `true` 而不会出现错误，因为基本类型值在定义上是不可变的。

```js
Object.isFrozen(1);
// TypeError: 1 is not an object（ES5 代码）

Object.isFrozen(1);
// true （ES2015 代码）
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.isfrozen |

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

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

参见
--

* `Object.freeze()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.seal()`
* `Object.isSealed()`


Object.fromEntries() - JavaScript

Object.fromEntries()
====================

**`Object.fromEntries()`** 静态方法将键值对列表转换为一个对象。

尝试一下
----

语法
--

```js
Object.fromEntries(iterable)
```

### 参数

`iterable`

一个包含对象列表的可迭代对象，例如 `Array` 或者 `Map`。每个对象都要有两个属性：

`0`

表示属性键的字符串或者 Symbol。

`1`

属性值。

通常，该对象被实现为二元数组，第一个元素是属性键，第二个元素是属性值。

### 返回值

一个新对象，其属性由可迭代对象的条目给定。

描述
--

`Object.fromEntries()` 方法接收一个键值对列表，并返回一个新对象，该对象的属性由这些条目给定。`iterable` 参数应该是实现了 `@@iterator` 方法的可迭代对象。该方法返回一个可迭代对象，产生包含两个元素的类数组对象。第一个元素是将用作属性键的值，第二个元素是要与该属性键关联的值。

`Object.fromEntries()` 是 `Object.entries()` 的逆操作，只是 `Object.entries()` 只返回字符串键属性，而 `Object.fromEntries()` 还可以创建符号键属性。

**备注：** 与 `Array.from()` 不同的是，`Object.fromEntries()` 不使用 `this` 的值，因此在另一个构造函数上调用它不会创建该类型的对象。

示例
--

### 将 Map 转换成对象

通过 `Object.fromEntries`，你可以将 `Map` 转换成 `Object`：

```js
const map = new Map([
  ["foo", "bar"],
  ["baz", 42],
]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
```

### 将 Array 转换成对象

通过 `Object.fromEntries`，你可以将 `Array` 转换成 `Object`：

```js
const arr = [
  ["0", "a"],
  ["1", "b"],
  ["2", "c"],
];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }
```

### 对象转换

通过 `Object.fromEntries`、其逆操作 `Object.entries()` 和数组操作方法，你可以像这样转换对象：

```js
const object1 = { a: 1, b: 2, c: 3 };

const object2 = Object.fromEntries(
  Object.entries(object1).map(([key, val]) => [key, val \* 2]),
);

console.log(object2);
// { a: 2, b: 4, c: 6 }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.fromentries |

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

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

参见
--

* `core-js` 中 `Object.fromEntries` 的 Polyfill
* `Object.entries()`
* `Object.keys()`
* `Object.values()`
* `Object.prototype.propertyIsEnumerable()`
* `Object.create()`
* `Map.prototype.entries()`
* `Map.prototype.keys()`
* `Map.prototype.values()`