1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 18:32:22 +00:00

docs: update latest proposals

This commit is contained in:
ruanyf 2022-06-26 22:17:23 +08:00
parent 6880b36897
commit 41970f7db0
3 changed files with 147 additions and 7 deletions

View File

@ -595,9 +595,9 @@ i32a.copyWithin(0, 2);
// Int32Array [4, 2, 3, 4, 5] // Int32Array [4, 2, 3, 4, 5]
``` ```
## 实例方法find() 和 findIndex() ## 实例方法find()findIndex()findLast()findLastIndex()
数组实例的`find`方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为`true`的成员,然后返回该成员。如果没有符合条件的成员,则返回`undefined` 数组实例的`find()`方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为`true`的成员,然后返回该成员。如果没有符合条件的成员,则返回`undefined`
```javascript ```javascript
[1, 4, -5, 10].find((n) => n < 0) [1, 4, -5, 10].find((n) => n < 0)
@ -612,9 +612,9 @@ i32a.copyWithin(0, 2);
}) // 10 }) // 10
``` ```
上面代码中,`find`方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。 上面代码中,`find()`方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。
数组实例的`findIndex`方法的用法与`find`方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回`-1` 数组实例的`findIndex()`方法的用法与`find()`方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回`-1`
```javascript ```javascript
[1, 5, 10, 15].findIndex(function(value, index, arr) { [1, 5, 10, 15].findIndex(function(value, index, arr) {
@ -632,9 +632,9 @@ let person = {name: 'John', age: 20};
[10, 12, 26, 15].find(f, person); // 26 [10, 12, 26, 15].find(f, person); // 26
``` ```
上面的代码中,`find`函数接收了第二个参数`person`对象,回调函数中的`this`对象指向`person`对象。 上面的代码中,`find()`函数接收了第二个参数`person`对象,回调函数中的`this`对象指向`person`对象。
另外,这两个方法都可以发现`NaN`,弥补了数组的`indexOf`方法的不足。 另外,这两个方法都可以发现`NaN`,弥补了数组的`indexOf()`方法的不足。
```javascript ```javascript
[NaN].indexOf(NaN) [NaN].indexOf(NaN)
@ -644,7 +644,23 @@ let person = {name: 'John', age: 20};
// 0 // 0
``` ```
上面代码中,`indexOf`方法无法识别数组的`NaN`成员,但是`findIndex`方法可以借助`Object.is`方法做到。 上面代码中,`indexOf()`方法无法识别数组的`NaN`成员,但是`findIndex()`方法可以借助`Object.is()`方法做到。
`find()``findIndex()`都是从数组的0号位依次向后检查。[ES2022](https://github.com/tc39/proposal-array-find-from-last) 新增了两个方法`findLast()``findLastIndex()`,从数组的最后一个成员开始,依次向前检查,其他都保持不变。
```javascript
const array = [
{ value: 1 },
{ value: 2 },
{ value: 3 },
{ value: 4 }
];
array.findLast(n => n.value % 2 === 1); // { value: 3 }
array.findLastIndex(n => n.value % 2 === 1); // 2
```
上面示例中,`findLast()``findLastIndex()`从数组结尾开始,寻找第一个`value`属性为奇数的成员。结果,该成员是`{ value: 3 }`位置是2号位。
## 实例方法fill() ## 实例方法fill()
@ -863,6 +879,93 @@ sentence.at(-100) // undefined
sentence.at(100) // undefined sentence.at(100) // undefined
``` ```
## 实例方法toReversed()toSorted()toSpliced()with()
很多数组的传统方法会改变原数组,比如`push()``pop()``shift()``unshift()`等等。数组只要调用了这些方法,它的值就变了。现在有一个[提案](https://github.com/tc39/proposal-change-array-by-copy),允许对数组进行操作时,不改变原数组,而返回一个原数组的拷贝。
这样的方法一共有四个。
- `Array.prototype.toReversed() -> Array`
- `Array.prototype.toSorted(compareFn) -> Array`
- `Array.prototype.toSpliced(start, deleteCount, ...items) -> Array`
- `Array.prototype.with(index, value) -> Array`
它们分别对应数组的原有方法。
- `toReversed()`对应`reverse()`,用来颠倒数组成员的位置。
- `toSorted()`对应`sort()`,用来对数组成员排序。
- `toSpliced()`对应`splice()`,用来在指定位置,删除指定数量的成员,并插入新成员。
- `with(index, value)`对应`splice(index, 1, value)`,用来将指定位置的成员替换为新的值。
上面是这四个新方法对应的原有方法,含义和用法完全一样,唯一不同的是不会改变原数组,而是返回原数组操作后的拷贝。
下面是示例。
```javascript
const sequence = [1, 2, 3];
sequence.toReversed() // [3, 2, 1]
sequence // [1, 2, 3]
const outOfOrder = [3, 1, 2];
outOfOrder.toSorted() // [1, 2, 3]
outOfOrder // [3, 1, 2]
const array = [1, 2, 3, 4];
array.toSpliced(1, 2, 5, 6, 7) // [1, 5, 6, 7, 4]
array // [1, 2, 3, 4]
const correctionNeeded = [1, 1, 3];
correctionNeeded.with(1, 2) // [1, 2, 3]
correctionNeeded // [1, 1, 3]
```
## 实例方法group()groupToMap()
数组成员分组是一个常见需求,比如 SQL 有`GROUP BY`子句和函数式编程有 MapReduce 方法。现在有一个[提案](https://github.com/tc39/proposal-array-grouping),为 JavaScript 新增了数组实例方法`group()``groupToMap()`,它们可以根据分组函数的运行结果,将数组成员分组。
`group()`的参数是一个分组函数,原数组的每个成员都会依次执行这个函数,确定自己是哪一个组。
```javascript
const array = [1, 2, 3, 4, 5];
array.group((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});
// { odd: [1, 3, 5], even: [2, 4] }
```
`group()`的分组函数可以接受三个参数,依次是数组的当前成员、该成员的位置序号、原数组(上例是`num``index``array`)。分组函数的返回值应该是字符串(或者可以自动转为字符串),以作为分组后的组名。
`group()`的返回值是一个对象,该对象的键名就是每一组的组名,即分组函数返回的每一个字符串(上例是`even``odd`);该对象的键值是一个数组,包括所有产生当前键名的原数组成员。
下面是另一个例子。
```javascript
[6.1, 4.2, 6.3].groupBy(Math.floor)
// { '4': [4.2], '6': [6.1, 6.3] }
```
上面示例中,`Math.floor`作为分组函数,对原数组进行分组。它的返回值原本是数值,这时会自动转为字符串,作为分组的组名。原数组的成员根据分组函数的运行结果,进入对应的组。
`group()`还可以接受一个对象,作为第二个参数。该对象会绑定分组函数(第一个参数)里面的`this`,不过如果分组函数是一个箭头函数,该对象无效,因为箭头函数内部的`this`是固化的。
`groupToMap()`的作用和用法与`group()`完全一致,唯一的区别是返回值是一个 Map 结构而不是对象。Map 结构的键名可以是各种值所以不管分组函数返回什么值都会直接作为组名Map 结构的键名),不会强制转为字符串。这对于分组函数返回值是对象的情况,尤其有用。
```javascript
const array = [1, 2, 3, 4, 5];
const odd = { odd: true };
const even = { even: true };
array.groupToMap((num, index, array) => {
return num % 2 === 0 ? even: odd;
});
// Map { {odd: true}: [1, 3, 5], {even: true}: [2, 4] }
```
上面示例返回的是一个 Map 结构,它的键名就是分组函数返回的两个对象`odd``even`
总之,按照字符串分组就使用`group()`,按照对象分组就使用`groupToMap()`
## 数组的空位 ## 数组的空位
数组的空位指的是,数组的某一个位置没有任何值,比如`Array()`构造函数返回的数组都是空位。 数组的空位指的是,数组的某一个位置没有任何值,比如`Array()`构造函数返回的数组都是空位。

View File

@ -478,6 +478,41 @@ const regexArrows = /^\p{Block=Arrows}+$/u;
regexArrows.test('←↑→↓↔↕↖↗↘↙⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇧⇩') // true regexArrows.test('←↑→↓↔↕↖↗↘↙⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇧⇩') // true
``` ```
## v 修饰符Unicode 属性类的运算
有时,需要向某个 Unicode 属性类添加或减少字符,即需要对属性类进行运算。现在有一个[提案](https://github.com/tc39/proposal-regexp-v-flag),增加了 Unicode 属性类的运算功能。
它提供两种形式的运算一种是差集运算A 集合减去 B 集合),另一种是交集运算。
```javascript
// 差集运算A 减去 B
[A--B]
// 交集运算A 与 B 的交集)
[A&&B]
```
上面两种写法中A 和 B 要么是字符类(例如`[a-z]`),要么是 Unicode 属性类(例如`\p{ASCII}`)。
而且,这种运算支持方括号之中嵌入方括号,即方括号的嵌套。
```javascript
// 方括号嵌套的例子
[A--[0-9]]
```
这种运算的前提是,正则表达式必须使用新引入的`v`修饰符。前面说过Unicode 属性类必须搭配`u`修饰符使用,这个`v`修饰符等于代替`u`,使用了它就不必再写`u`了。
下面是一些例子。
```javascript
// 十进制字符去除 ASCII 码的0到9
[\p{Decimal_Number}--[0-9]]
// Emoji 字符去除 ASCII 码字符
[\p{Emoji}--\p{ASCII}]
```
## 具名组匹配 ## 具名组匹配
### 简介 ### 简介

View File

@ -942,6 +942,8 @@ map.set(null, 2)
上面代码中,如果将数值`1``Symbol`值作为 WeakMap 的键名,都会报错。 上面代码中,如果将数值`1``Symbol`值作为 WeakMap 的键名,都会报错。
不过,现在有一个[提案](https://github.com/tc39/proposal-symbols-as-weakmap-keys),允许 Symbol 值也可以作为 WeakMap 的键名。一旦纳入标准,就意味着键名存在两种可能:对象和 Symbole 值。
其次,`WeakMap`的键名所指向的对象,不计入垃圾回收机制。 其次,`WeakMap`的键名所指向的对象,不计入垃圾回收机制。
`WeakMap`的设计目的在于,有时我们想在某个对象上面存放一些数据,但是这会形成对于这个对象的引用。请看下面的例子。 `WeakMap`的设计目的在于,有时我们想在某个对象上面存放一些数据,但是这会形成对于这个对象的引用。请看下面的例子。