recursal/MDN huggingface dataset:
RegExp.prototype.hasIndices
===========================

**`hasIndices`** 访问器属性指示 `d` 标志是否与正则表达式一起使用。

尝试一下
----

描述
--

如果 `d` 标志被使用，则 `RegExp.prototype.hasIndices` 的值是 `true`；否则是 `false`。`d` 标志表示正则表达式匹配的结果应该包含每个捕获组子字符串开始和结束的索引。它不会以任何方式改变正则表达式的解释或匹配行为，它只在匹配的结果中提供额外的信息。

`hasIndices` 的 set 访问器是 `undefined`。你不能直接修改此属性。

示例
--

### 使用 hasIndices


```js
const str1 = "foo bar foo";

const regex1 = /foo/dg;

console.log(regex1.hasIndices); // Output: true

console.log(regex1.exec(str1).indices[0]); // Output: Array [0, 3]
console.log(regex1.exec(str1).indices[0]); // Output: Array [8, 11]

const str2 = "foo bar foo";

const regex2 = /foo/;

console.log(regex2.hasIndices); // Output: false

console.log(regex2.exec(str2).indices); // Output: undefined
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.hasIndices |

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

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

参见
--

* `RegExp.prototype.lastIndex`
* `RegExp.prototype.exec()`
* `RegExp.prototype.dotAll`
* `RegExp.prototype.global`
* `RegExp.prototype.ignoreCase`
* `RegExp.prototype.multiline`
* `RegExp.prototype.source`
* `RegExp.prototype.sticky`
* `RegExp.prototype.unicode`
RegExp.lastParen ($+)
=====================

**非标准:** 该特性是非标准的，请尽量不要在生产环境中使用它！

**lastParen** 非标准属性是正则表达式的静态和只读属性，包含匹配到的最后一个子串（如果存在）。`RegExp.$+`是这一属性的别名。

语法
--
```

RegExp.lastParen
RegExp['$+']
```

描述
--

`lastParen` 属性是静态的，不是正则表达式独立对象的属性。反之，你应始终将其使用为 `RegExp.lastParen` 或者 `RegExp['$+']`。

`lastParen` 属性的值是只读的，并且会在匹配成功时修改。

你不能使用属性访问器 (`RegExp.$+`) 来使用简写的别名，因为解析器在这里会将 "+" 看做表达式，并抛出 `SyntaxError` 。使用 方括号符号来访问属性。

示例
--

### 使用 `lastParen` 和 `$+`


```js
var re = /(hi)/g;
re.test("hi there!");
RegExp.lastParen; // "hi"
RegExp["$+"]; // "hi"
```

规范
--

非标准。并不是任何现行规范的一部分。

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

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

另见
--

* 非标准
 `RegExp.input ($_)`
* 非标准
 `RegExp.lastMatch ($&)`
* 非标准
 `RegExp.leftContext ($`)`
* 非标准
 `RegExp.rightContext ($')`
* 非标准
 `RegExp.$1-$9`
RegExp.prototype.ignoreCase
===========================

概述
--

**`ignoreCase`** 属性表明正则表达式是否使用了 "`i`" 标志。`ignoreCase` 是正则表达式实例的只读属性。

| `RegExp.prototype.ignoreCase` 的属性特性 |
| --- |
| 可写 | 否 |
| 可枚举 | 否 |
| 可配置 | 否 |

描述
--

`ignoreCase` 的值是布尔对象，如果使用了"`i`" 标志，则返回 `true`；否则，返回 `false`。"`i`" 标志意味着在字符串进行匹配时，应该忽略大小写。

你无法直接更改此属性。

示例
--

### 示例：使用 `ignoreCase`


```js
var regex = new RegExp("foo", "i");

console.log(regex.ignoreCase); // true
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.ignorecase |

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

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

参见
--

* `RegExp.prototype.global`
* `RegExp.prototype.lastIndex`
* `RegExp.prototype.multiline`
* `RegExp.prototype.source`
* `RegExp.prototype.sticky`
RegExp.prototype[@@split]()
===========================

**`[@@split]()`** 方法切割 `String` 对象为一个其子字符串的数组。

语法
--
```

regexp[Symbol.split](str[, limit])
```

### 参数

`str`

切割操作的目标字符串

`limit`

可选。一个为了限制切割数量的特定整数。 `[@@split]()` 防范仍会切割每个匹配正则模式的匹配项，直到切割数量达到该限制数，除非提前切割完字符串。

### 返回值

包含其子字符串的`Array` 。

描述
--

如果切割器是一个`RegExp`对象，这个方法就将在 `String.prototype.split()` 的内部调用。例如，下面的两个方法返回相同结果。


```js
"a-b-c".split(/-/);

/-/[Symbol.split]("a-b-c");
```


这个方法为自定义 `RegExp` 子类中的匹配行为而存在。

如果 str 参数不是一个`RegExp` 对象，`String.prototype.split()` 就不会调用该方法，也不会创建一个 `RegExp` 对象。示例

### 直接调用

这个方法的使用方式和 `String.prototype.split()` 相同，不同之处是 `this` 和参数顺序。


```js
var re = /-/g;
var str = "2016-01-02";
var result = re[Symbol.split](str);
console.log(result); // ["2016", "01", "02"]
```

### 在子类中使用 `@@split`

`RegExp` 的子类可以覆写 `[@@split]()`方法来修改默认行为。


```js
class MyRegExp extends RegExp {
  [Symbol.split](str, limit) {
    var result = RegExp.prototype[Symbol.split].call(this, str, limit);
    return result.map((x) => "(" + x + ")");
  }
}

var re = new MyRegExp("-");
var str = "2016-01-02";
var result = str.split(re); // String.prototype.split calls re[@@split].
console.log(result); // ["(2016)", "(01)", "(02)"]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-regexp.prototype-@@split |

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

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

另见
--

* `String.prototype.split()`
* `RegExp.prototype[@@match]()`
* `RegExp.prototype[@@replace]()`
* `RegExp.prototype[@@search]()`
* `RegExp.prototype.exec()`
* `RegExp.prototype.test()`
RegExp.leftContext ($`)
=======================

**非标准:** 该特性是非标准的，请尽量不要在生产环境中使用它！

**leftContext** 非标准属性是正则表达式的静态和只读属性，含有最新匹配的左侧子串。 `RegExp.$`` 是这个属性的别名。

语法
--
```

RegExp.leftContext
RegExp['$`']
```

描述
--

`leftContext` 属性是静态的，不是正则表达式独立对象的属性。反之，你应始终将其使用为 `RegExp.leftContext` 或者 `RegExp['$`']`。

`leftContext` 属性的值是只读的，并且会在匹配成功时修改。

你不能使用属性访问器 (`RegExp.$``) 来使用简写的别名，因为解析器在这里会将其看做模板字符串的开始，并抛出 `SyntaxError` 。使用 方括号符号来访问属性。

示例
--

### 使用 `leftContext` 和 `$``


```js
var re = /world/g;
re.test("hello world!");
RegExp.leftContext; // "hello "
RegExp["$`"]; // "hello "
```

规范
--

非标准。并不是任何现行规范的一部分。

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

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

另见
--

* 非标准
 `RegExp.input ($_)`
* 非标准
 `RegExp.lastMatch ($&)`
* 非标准
 `RegExp.lastParen ($+)`
* 非标准
 `RegExp.rightContext ($')`
* 非标准
 `RegExp.$1-$9`
RegExp.prototype.test()
=======================

**`test()`** 方法执行一个检索，用来查看正则表达式与指定的字符串是否匹配。返回 `true` 或 `false`。

尝试一下
----

语法
--
```

regexObj.test(str)
```

### 参数

`str`

用来与正则表达式匹配的字符串

### 返回值

如果正则表达式与指定的字符串匹配，返回`true`；否则`false`。

描述
--

当你想要知道一个正则表达式是否与指定的字符串匹配时，就可以使用 `test()`（类似于 `String.prototype.search()` 方法），差别在于 test 返回一个布尔值，而 search 返回索引（如果找到）或者 -1（如果没找到）；若想知道更多信息（然而执行比较慢），可使用`exec()` 方法（类似于 `String.prototype.match()` 方法）。和 `exec()` (或者组合使用),一样，在相同的全局正则表达式实例上多次调用`test`将会越过之前的匹配。

示例
--

### 使用 `test()`

一个简单的例子，测试 "hello" 是否包含在字符串的最开始，返回布尔值。


```js
let str = "hello world!";
let result = /^hello/.test(str);
console.log(result);
// true
```


下例打印一条信息，该信息内容取决于是否成功通过指定测试：


```js
function testinput(re, str) {
  var midstring;
  if (re.test(str)) {
    midstring = " contains ";
  } else {
    midstring = " does not contain ";
  }
  console.log(str + midstring + re.source);
}
```

### 当设置全局标志的正则使用`test()`

如果正则表达式设置了全局标志，`test()` 的执行会改变正则表达式 `lastIndex`属性。连续的执行`test()`方法，后续的执行将会从 lastIndex 处开始匹配字符串，(`exec()` 同样改变正则本身的 `lastIndex 属性值`).

下面的实例表现了这种行为：


```js
var regex = /foo/g;

// regex.lastIndex is at 0
regex.test("foo"); // true

// regex.lastIndex is now at 3
regex.test("foo"); // false
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-regexp.prototype.test |

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

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

参见
--

* JavaScript 指南的正则表达式章节
* `RegExp`
RegExp.prototype.compile()
==========================

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

已废弃的 **`compile()`** 方法被用于在脚本执行过程中（重新）编译正则表达式。与 `RegExp` 构造函数基本一样。

语法
--
```

regexObj.compile(pattern, flags)
```

### 参数

`pattern`

正则表达式的文本。

`flags`

如果指定，标志可以具有以下值的任意组合：

`g`

全局匹配

`i`

忽略大小写

`m`

多行;让开始和结束字符（^ 和 $）工作在多行模式工作（例如，^ 和 $ 可以匹配字符串中每一行的开始和结束（行是由 \n 或 \r 分割的），而不只是整个输入字符串的最开始和最末尾处。

`y`

黏度; 在目标字符串中，只从正则表达式的 lastIndex 属性指定的显示位置开始匹配（并且不试图从任何之后的索引匹配）。


描述
--

不推荐 `compile` 方法。你可以使用 `RegExp` 构造函数来得到相同效果。

示例
--

### `使用 compile()`

以下展示如何用新模式和新标志来重新编译正则表达式。


```js
var regexObj = new RegExp("foo", "gi");
regexObj.compile("new foo", "g");
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-regexp.prototype.compile |

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

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

参见
--

* `RegExp`
RegExp.input ($\_)
==================

**非标准:** 该特性是非标准的，请尽量不要在生产环境中使用它！

**`input`** 非标准属性是正则表达式静态属性，含有正则表达式所匹配的字符串。`RegExp.$_`是这个属性的别名。

语法
--
```

RegExp.input
RegExp.$_
```

描述
--

`input` 属性是静态的，并不是正则表达式独立对象的属性。反之，你应始终将其使用为 `RegExp.input` 或者 `RegExp.$_`。

当正则表达式上搜索的字符串发生改变，并且字符串匹配时，**`input`** 属性的值会修改。

示例
--

### 使用 `input` 和 `$_`


```js
var re = /hi/g;
re.test("hi there!");
RegExp.input; // "hi there!"
re.test("foo"); // 新测试，不匹配
RegExp.$_; // "hi there!"
re.test("hi world!"); // 新测试，匹配
RegExp.$_; // "hi world!"
```

规范
--

非标准。并不是任何现行规范的一部分。

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

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

另见
--

* 非标准
 `RegExp.lastMatch ($&)`
* 非标准
 `RegExp.lastParen ($+)`
* 非标准
 `RegExp.leftContext ($`)`
* 非标准
 `RegExp.rightContext ($')`
* 非标准
 `RegExp.$1-$9`
RegExp.prototype[@@matchAll]()
==============================

\*\*`[@@matchAll]`\*\*方法返回对字符串使用正则表达式的所有匹配项。

{{EmbedInteractiveExample("pages/js/regexp-prototype-@@matchall.html")}}

语法
--
```

regexp[Symbol.matchAll](str)
```

### 参数

`str`

一个`String`的匹配对象。

### 返回值

一个迭代器。

描述
--

本方法在`String.prototype.matchAll()`中被内部调用。例如，以下两个示例返回相同的结果。


```js
"abc".matchAll(/a/);

/a/[Symbol.matchAll]("abc");
```


本方法用于自定义`RegExp`子类中的匹配行为。

示例
--

### 直接调用

本方法的使用方法几乎与`String.prototype.matchAll()`相同，除了`this` 的不同以及参数顺序的的差异。


```js
var re = /[0-9]+/g;
var str = "2016-01-02";
var result = re[Symbol.matchAll](str);

console.log(Array.from(result, (x) => x[0]));
// ["2016", "01", "02"]
```

### 在子类中使用 `@@matchAll`

`RegExp` 的子类可以重写 `[@@matchAll]()` 方法来修改默认行为。例如，返回一个数组而不是迭代器：


```js
class MyRegExp extends RegExp {
  [Symbol.matchAll](str) {
    var result = RegExp.prototype[Symbol.matchAll].call(this, str);
    if (!result) {
      return null;
    } else {
      return Array.from(result);
    }
  }
}

var re = new MyRegExp("([0-9]+)-([0-9]+)-([0-9]+)", "g");
var str = "2016-01-02|2019-03-07";
var result = str.matchAll(re);
console.log(result[0]); // [ "2016-01-02", "2016", "01", "02" ]
console.log(result[1]); // [ "2019-03-07", "2019", "03", "07" ]
```

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

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

参见
--

* `String.prototype.matchAll()`
* `Symbol.matchAll`
Array.prototype.push()
======================

**`push()`** 方法将指定的元素添加到数组的末尾，并返回新的数组长度。

尝试一下
----

语法
--


```js
push()
push(element0)
push(element0, element1)
push(element0, element1, /\* … ,\*/ elementN)
```

### 参数

`elementN`

添加到数组末尾的元素。

### 返回值

调用方法的对象的新 `length` 属性。

描述
--

`push()` 方法将值追加到一个数组中。

`Array.prototype.unshift()` 有着和 `push()` 相似的行为，但是其作用于数组的开头。

`push()` 方法是一个修改方法。它改变了 `this` 的内容和长度。如果你希望 `this` 的值保持不变，但返回一个末尾追加了元素的新数组，你可以使用 `arr.concat([element0, element1, /* ... ,*/ elementN])` 来代替。请注意，这些元素需要被包装在一个额外的数组中——否则，如果元素本身是一个数组，由于 `concat()` 的行为，它将被展开而不是作为单个元素添加到原数组的末尾。

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

示例
--

### 在数组中添加元素

接下来的代码中将会生成包含两个元素的 `sports` 数组，然后向其添加两个元素。`total` 变量将会记录数组的新长度。


```js
const sports = ["soccer", "baseball"];
const total = sports.push("football", "swimming");

console.log(sports); // ['soccer', 'baseball', 'football', 'swimming']
console.log(total); // 4
```

### 合并两个数组

这个示例使用展开语法来将第二个数组的所有元素添加到第一个数组中。


```js
const vegetables = ["parsnip", "potato"];
const moreVegs = ["celery", "beetroot"];

// 合并第二个数组到第一个数组中
vegetables.push(...moreVegs);

console.log(vegetables); // ['parsnip', 'potato', 'celery', 'beetroot']
```


也可以通过使用 `concat()` 方法来合并两个数组。

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

`push()` 方法会读取 `this` 的 `length` 属性。然后，它将 `this` 的每个索引从 `length` 开始设置，并将参数传递给 `push()`。最后，它将 `length` 设置成之前的长度加上已添加元素的数量。


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

const plainObj = {};
// 这里没有长度属性，所以长度为 0
Array.prototype.push.call(plainObj, 1, 2);
console.log(plainObj);
// { '0': 1, '1': 2, length: 2 }
```

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

如上所述，`push` 被有意设计为通用的，我们可以利用这一点。就像这个例子所展示的，`Array.prototype.push` 可以很好的处理对象。

注意，我们没有创建一个数组来存储对象集合。相反，我们将集合存储在对象本身上，并通过 `Array.prototype.push` 的 `call` 来调用该方法，让它认为我们正在处理一个数组——归功于 JavaScript 允许我们以任何我们想要的方式建立执行上下文的方式，这样是可行的。


```js
const obj = {
  length: 0,

  addElem(elem) {
    // obj.length 在每次添加元素时自动增加
    [].push.call(this, elem);
  },
};

// 让我们添加一些空对象来说明
obj.addElem({});
obj.addElem({});
console.log(obj.length); // 2
```


注意，尽管 `obj` 不是一个数组，`push` 方法仍成功地增加了 `obj` 的 `length` 属性，就像我们处理一个真正的数组一样。

规范
--

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

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

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

参见
--

* `core-js` 中 `Array.prototype.push` 的 Polyfill，并对此方法进行了修复
* 索引集合类
* `Array`
* `Array.prototype.pop()`
* `Array.prototype.shift()`
* `Array.prototype.unshift()`
* `Array.prototype.concat()`
* `Array.prototype.splice()`
Array.prototype.copyWithin()
============================

**`copyWithin()`** 方法浅复制数组的一部分到同一数组中的另一个位置，并返回它，不会改变原数组的长度。

尝试一下
----

语法
--


```js
copyWithin(target)
copyWithin(target, start)
copyWithin(target, start, end)
```

### 参数

`target`

序列开始替换的目标位置，以 0 为起始的下标表示，且将被转换为整数

* 负索引将从数组末尾开始计数——如果 `target < 0`，则实际是 `target + array.length`。
* 如果 `target < -array.length`，则使用 `0`。
* 如果 `target >= array.length`，则不会拷贝任何内容。
* 如果 `target` 位于 `start` 之后，则复制只会持续到 `array.length` 结束（换句话说，`copyWithin()` 永远不会扩展数组）。

`start` 可选

要复制的元素序列的起始位置，以 0 为起始的下标表示，且将被转换为整数

* 负索引将从数组末尾开始计数——如果 `start < 0`，则实际是 `start + array.length`。
* 如果省略 `start` 或 `start < -array.length`，则默认为 `0`。
* 如果 `start >= array.length`，则不会拷贝任何内容。

`end` 可选

要复制的元素序列的结束位置，以 0 为起始的下标表示，且将被转换为整数。`copyWithin` 将会拷贝到该位置，但不包括 `end` 这个位置的元素。

* 负索引将从数组末尾开始计数——如果 `end < 0`，则实际是 `end + array.length`。
* 如果 `end < -array.length`，则使用`0`。
* 如果省略 `end` 或 `end >= array.length`，则默认为 `array.length`，这将导致直到数组末尾的所有元素都被复制。
* 如果 `end` 位于 `start` 之前，则不会拷贝任何内容。

### 返回值

改变后的数组。

描述
--

`copyWithin()` 方法的工作原理类似于 C 和 C++ 的 `memmove`，是一种移动数组数据的高性能方法，与 `TypedArray` 的同名方法类似。序列在一次中操作被复制和粘贴；即使复制和粘贴区域重叠，粘贴的序列也将具有复制值。

`copyWithin()` 是修改方法。它不会改变 `this` 指向的对象（数组或类数组）的长度，但会更改其的内容，并在必要时创建新属性或删除现有属性。

`copyWithin()` 方法保留空槽。如果要复制的区域是稀疏的，则原来的空槽会被删除并被替换为拷贝的空槽。

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

示例
--

### 使用 copyWithin()


```js
console.log([1, 2, 3, 4, 5].copyWithin(-2));
// [1, 2, 3, 1, 2]

console.log([1, 2, 3, 4, 5].copyWithin(0, 3));
// [4, 5, 3, 4, 5]

console.log([1, 2, 3, 4, 5].copyWithin(0, 3, 4));
// [4, 2, 3, 4, 5]

console.log([1, 2, 3, 4, 5].copyWithin(-2, -3, -1));
// [1, 2, 3, 3, 4]
```

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

`copyWithin()` 将保留空插槽。


```js
console.log([1, , 3].copyWithin(2, 1, 2)); // [1, empty, empty]
```

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

`copyWithin()` 方法读取 `this` 的 `length` 属性，然后操作所涉及的整数索引。


```js
const arrayLike = {
  length: 5,
  3: 1,
};
console.log(Array.prototype.copyWithin.call(arrayLike, 0, 3));
// { '0': 1, '3': 1, length: 5 }
console.log(Array.prototype.copyWithin.call(arrayLike, 3, 1));
// { '0': 1, length: 5 }
// '3' 属性被删除，因为在复制的源中是一个空槽
```

规范
--

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

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

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

参见
--

* `core-js` 中 `Array.prototype.copyWithin` 的 polyfill
* 索引集合类
* `Array`
* `TypedArray.prototype.copyWithin()`
Array.prototype.keys()
======================

**`keys()`** 方法返回一个新的*数组迭代器*对象，其中包含数组中每个索引的键。

尝试一下
----

语法
--


```js
keys()
```

### 返回值

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

描述
--

当用于稀疏数组时，`keys()` 方法迭代空槽，就像它们的值为 `undefined` 一样。

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

示例
--

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

与 `Object.keys()` 只包含数组中实际存在的键不同，`keys()` 迭代器不会忽略缺失属性的键。


```js
const arr = ["a", , "c"];
const sparseKeys = Object.keys(arr);
const denseKeys = [...arr.keys()];
console.log(sparseKeys); // ['0', '2']
console.log(denseKeys); // [0, 1, 2]
```

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

`keys()` 方法读取 `this` 的 `length` 属性，然后生成 0 到 `length - 1` 之间的所有整数索引。实际并不会访问索引。


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

规范
--

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

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

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

参见
--

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

**`findLastIndex()`** 方法反向迭代数组，并返回满足所提供的测试函数的第一个元素的索引。若没有找到对应元素，则返回 -1。

另请参见 `findLast()` 方法，该方法返回最后一个满足测试函数的元素的值（而不是它的索引）。

尝试一下
----

语法
--


```js
findLastIndex(callbackFn)
findLastIndex(callbackFn, thisArg)
```

### 参数

`callbackFn`

对数组中的每个元素执行的函数。回调必须返回一个真值，表示已找到匹配的元素，否则返回一个假值。函数在被调用时会传递以下参数：

`element`

当前遍历到的元素。

`index`

当前正在处理的元素的索引。

`array`

调用 `findLastIndex()` 的数组本身。


`thisArg` 可选

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

### 返回值

数组中通过测试的最后一个（索引最大）元素的索引。如果没有找到任何匹配的元素，则返回 -1。

描述
--

`findLastIndex()` 方法是一个迭代方法。它为数组中的每个元素按索引降序调用一次提供的 `callbackFn` 函数，直到 `callbackFn` 返回一个真值。然后 `findLastIndex()` 返回元素的索引并且停止遍历数组。如果 `callbackFn` 没有返回一个真值，则 `findLastIndex()` 返回 `-1`。

`callbackFn` 会为数组中的*每个*元素调用，而不仅仅是那些被赋值的元素，这意味着对于稀疏数组来说，空槽的行为和 `undefined` 相同。

`findLastIndex()` 方法不会改变调用它的数组，但是提供的 `callbackFn` 可以。但是请注意，数组的长度是在第一次调用 `callbackFn` *之前*保存的。因此：

* `callbackFn` 不会访问在调用 `findLastIndex()` 开始后才添加到数组中的任何元素。
* 对已访问索引的更改不会导致对它们再次调用 `callbackFn` 函数。
* 如果 `callbackFn` 更改了数组中现有的、尚未访问的元素，它传递给`callbackFn` 的值将是该元素被访问时的值。已删除元素被当作 `undefined` 来访问。

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

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

示例
--

### 查找数组中最后一个素数的索引

下面的示例返回数组中作为素数的最后一个元素的索引，如果没有素数，则返回 `-1`。


```js
function isPrime(element) {
  if (element % 2 === 0 || element < 2) {
    return false;
  }
  for (let factor = 3; factor <= Math.sqrt(element); factor += 2) {
    if (element % factor === 0) {
      return false;
    }
  }
  return true;
}

console.log([4, 6, 8, 12].findLastIndex(isPrime)); // -1，没有找到
console.log([4, 5, 7, 8, 9, 11, 12].findLastIndex(isPrime)); // 5
```

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

你可以在稀疏数组中搜索 `undefined` 并获得空槽的索引。


```js
console.log([1, , 3].findLastIndex((x) => x === undefined)); // 1
```

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

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


```js
const arrayLike = {
  length: 3,
  0: 2,
  1: 7.3,
  2: 4,
};
console.log(
  Array.prototype.findLastIndex.call(arrayLike, (x) => Number.isInteger(x)),
); // 2
```

规范
--

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

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

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

参见
--

* `core-js` 中 `Array.prototype.findIndex` 的 polyfill
* `Array`
* `Array.prototype.find()`
* `Array.prototype.findIndex()`
* `Array.prototype.findLast()`
* `Array.prototype.indexOf()`
* `Array.prototype.lastIndexOf()`
* `TypedArray.prototype.findLastIndex()` (en-US)
Array.prototype.concat()
========================

**`concat()`** 方法用于合并两个或多个数组。此方法不会更改现有数组，而是返回一个新数组。

尝试一下
----

语法
--


```js
concat()
concat(value0)
concat(value0, value1)
concat(value0, value1, /\* … ,\*/ valueN)
```

### 参数

`valueN` 可选

数组和/或值，将被合并到一个新的数组中。如果省略了所有 `valueN` 参数，则 `concat` 会返回调用此方法的现存数组的一个浅拷贝。详情请参阅下文描述。

### 返回值

新的 `Array` 实例。

描述
--

`concat` 方法创建一个新数组。该数组将首先由调用它的对象中的元素填充。然后，对于每个参数，它的值将被连接到数组中——对于普通对象或基元，参数本身将成为最终数组的一个元素；对于属性`Symbol.isConcatSpreadable`设置为真的数组或类数组对象，参数的每个元素都将是独立地添加到最终数组中。`concat` 方法不会递归到嵌套数组参数中。

`concat()` 方法是一种复制方法。它不会更改 `this` 或作为参数提供的任何数组，而是返回包含与原始数组中的元素相同的元素的浅拷贝。

如果任何源数组是稀疏数组，`concat()` 方法会保留空槽。

`concat()` 方法是通用的。`this` 值的处理方式与其他参数相同（除了它会先转换为对象），这意味着普通对象将直接添加到结果数组中，而 `@@isConcatSpreadable` 属性为真值的类数组对象将展开并添加到数组中。

示例
--

### 连接两个数组

以下代码将两个数组合并为一个新数组：


```js
const letters = ["a", "b", "c"];
const numbers = [1, 2, 3];

const alphaNumeric = letters.concat(numbers);
console.log(alphaNumeric);
// results in ['a', 'b', 'c', 1, 2, 3]
```

### 连接三个数组

以下代码将三个数组合并为一个新数组：


```js
const num1 = [1, 2, 3];
const num2 = [4, 5, 6];
const num3 = [7, 8, 9];

const numbers = num1.concat(num2, num3);

console.log(numbers);
// results in [1, 2, 3, 4, 5, 6, 7, 8, 9]
```

### 将值连接到数组

以下代码将三个值连接到数组：


```js
const letters = ["a", "b", "c"];

const alphaNumeric = letters.concat(1, [2, 3]);

console.log(alphaNumeric);
// results in ['a', 'b', 'c', 1, 2, 3]
```

### 合并嵌套数组

以下代码合并数组并保留引用：


```js
const num1 = [[1]];
const num2 = [2, [3]];

const numbers = num1.concat(num2);

console.log(numbers);
// [[1], 2, [3]]

// 修改 num1 的第一个元素
num1[0].push(4);

console.log(numbers);
// [[1, 4], 2, [3]]
```

### 使用 Symbol.isConcatSpreadable 合并类数组对象

`concat` 默认情况下不会将类数组对象视作数组——仅在 `Symbol.isConcatSpreadable` 被设置为真值（例如，`true`）时才会将类数组对象视作数组。


```js
const obj1 = { 0: 1, 1: 2, 2: 3, length: 3 };
const obj2 = { 0: 1, 1: 2, 2: 3, length: 3, [Symbol.isConcatSpreadable]: true };
console.log([0].concat(obj1, obj2));
// [ 0, { '0': 1, '1': 2, '2': 3, length: 3 }, 1, 2, 3 ]
```

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

如果任何源数组是稀疏的，则结果数组也将是稀疏的：


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

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

如果 `this` 值不是数组，它会被转换为一个对象，然后以与 `concat()` 的参数相同的方式处理。在这种情况下，返回值始终是一个普通的新数组。


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

规范
--

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

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

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

参见
--

* 在 `core-js` 中实现 `Array.prototype.concat` 的 Polyfill，修复其中的问题并实现新特性，例如支持 `Symbol.isConcatSpreadable`
* 索引集合类
* `Array`
* `Array.prototype.push()`
* `Array.prototype.unshift()`
* `Array.prototype.splice()`
* `String.prototype.concat()`
* `Symbol.isConcatSpreadable`