一. ES7 知识点

1.1. Array Includes

在 ES7 之前,如果我们想判断一个数组中是否包含某个元素,需要通过 indexOf 获取结果,并且判断是否为 -1

在 ES7 中,我们可以通过 includes 来判断一个数组中是否包含一个指定的元素,根据情况,如果包含则返回 true,否则返回 false。

语法如下:

arr.includes(valueToFind[, fromIndex])

1
2
3
4
5
6
7
8
9
10
11
12
13
const names = ["abc", "cba", "nba", "why"];

if (names.indexOf("why") !== -1) {
console.log("包含why");
}

if (names.includes("why")) {
console.log("包含why");
}

if (names.includes("why", 4)) {
console.log("包含why");
}

并且对于 NaN、undefined 的查找,includes 要好于 indexOf:

1
2
3
const names = ["abc", "cba", "nba", "why", NaN];
console.log(names.indexOf(NaN)); // -1
console.log(names.includes(NaN)); // true

1.2. 平方运算符

在 ES7 之前,计算数字的平方需要通过 Math.pow 方法来完成。

在 ES7 中,增加了 ** 运算符,可以对数字来计算平方。

1
2
3
const result1 = Math.pow(3, 3);
const result2 = 3 ** 3;
console.log(result1, result2);

二. ES8 知识点

2.1. Object values

之前我们可以通过 Object.keys 获取一个对象所有的 key,在 ES8 中提供了 Object.values 来获取所有的 value 值:

1
2
3
4
5
6
7
8
9
10
const obj = {
name: "why",
age: 18,
height: 1.88
};

console.log(Object.values(obj)); // [ 'why', 18, 1.88 ]

// 如果传入一个字符串
console.log(Object.values("abc")); // [ 'a', 'b', 'c' ]

2.2. Object entries

通过Object.entries 可以获取到一个数组,数组中会存放可枚举属性的键值对数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const obj = {
name: "why",
age: 18,
height: 1.88
};

console.log(Object.entries(obj)); // [ [ 'name', 'why' ], [ 'age', 18 ], [ 'height', 1.88 ] ]

for (const entry of Object.entries(obj)) {
const [key, value] = entry;
console.log(key, value);
}

// 如果是一个数组
console.log(Object.entries(["abc", "cba", "nba"])); // [ [ '0', 'abc' ], [ '1', 'cba' ], [ '2', 'nba' ] ]

// 如果是一个字符串
console.log(Object.entries("abc")); // [ [ '0', 'a' ], [ '1', 'b' ], [ '2', 'c' ] ]

2.3. Object Descriptors

ES8 中增加了另一个对对象的操作是 Object.getOwnPropertyDescriptors ,这个在之前已经讲过了,这里不再重复。

2.4. String Padding

某些字符串我们需要对其进行前后的填充,来实现某种格式化效果,ES8 中增加了 padStartpadEnd 方法,分别是对字符串的首尾进行填充的。

1
2
3
const message = "Hello World";
console.log(message.padStart(15, "a")); // aaaaHello World
console.log(message.padEnd(15, "b")); // Hello Worldbbbb

我们简单具一个应用场景:比如需要对身份证、银行卡的前面位数进行隐藏:

1
2
3
4
const cardNumber = "3242523524256245223879";
const lastFourNumber = cardNumber.slice(-4);
const finalCardNumber = lastFourNumber.padStart(cardNumber.length, "*");
console.log(finalCardNumber); // ******************3879

2.5. Trailing Commas

在 ES8 中,我们允许在函数定义和调用时多加一个逗号:

1
2
3
4
5
function foo(a, b) {
console.log(a, b);
}

foo(10, 20);

三. ES9 知识点

ES9 中新增的知识点主要有三个:

3.1. Async iterators

后续迭代器讲解

3.2. Object spread operators;

前面讲过了

3.3. Promise finally;

后续讲 Promise 讲解

四. ES10 知识点

4.1. flat flatMap

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const nums = [
10,
20,
[5, 8],
[
[2, 3],
[9, 22]
],
100
];

const newNums1 = nums.flat(1);
const newNums2 = nums.flat(2);
console.log(newNums1); // [ 10, 20, 5, 8, 2, 3, 9, 22, 100 ]
console.log(newNums2); // [ 10, 20, 5, 8, [ 2, 3 ], [ 9, 22 ], 100 ]

flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。

  • 注意一:flatMap 是先进行 map 操作,再做 flat 的操作;

  • 注意二:flatMap 中的 flat 相当于深度为 1;

1
2
3
4
5
6
7
const messages = ["Hello World", "你好啊 李银河", "my name is why"];

const newMessages = messages.flatMap(item => {
return item.split(" ");
});

console.log(newMessages);

4.2. Object formEntries

在前面,我们可以通过 Object.entries 将一个对象转换成 entries,那么如果我们有一个 entries 了,如何将其转换成对象呢?

  • ES10 提供了 Object.formEntries 来完成转换:
1
2
3
4
5
6
7
8
9
10
11
const obj = {
name: "why",
age: 18,
height: 1.88
};

const entries = Object.entries(obj);
console.log(entries);

const info = Object.fromEntries(entries);
console.log(info);

那么这个方法有什么应用场景呢?

1
2
3
4
5
6
7
8
9
const paramsString = "name=why&age=18&height=1.88";
const searchParams = new URLSearchParams(paramsString);

for (const param of searchParams) {
console.log(param);
}

const searchObj = Object.fromEntries(searchParams);
console.log(searchObj);

4.3. trimStart trimEnd

去除一个字符串首尾的空格,我们可以通过 trim 方法,如果单独去除前面或者后面呢?

  • ES10 中给我们提供了 trimStart 和 trimEnd;
1
2
3
4
const message = "   Hello World   ";
console.log(message.trim());
console.log(message.trimStart());
console.log(message.trimEnd());

4.4. Symbol description

已经讲过了(讲解 Symbol 的时候)

4.5. Optional catch binding

后面讲解 try cach 讲解

五. ES11 知识点

5.1. BigInt

在早期的 JavaScript 中,我们不能正确的表示过大的数字:

  • 大于 MAX_SAFE_INTEGER 的数值,表示的可能是不正确的。
1
2
3
4
const maxInt = Number.MAX_SAFE_INTEGER;
console.log(maxInt); // 大于MAX_SAFE_INTEGER值的一些数值,无法正确的表示
console.log(maxInt + 1); // 9007199254740992
console.log(maxInt + 2); // 9007199254740992

那么 ES11 中,引入了新的数据类型 BigInt,用于表示大的整数:

  • BitInt 的表示方法是在数值的后面加上 n
1
2
3
const bigInt = 9007199254740991n;
console.log(bigInt + 1n);
console.log(bigInt + 2n);

BigInt 可以将其他数据类型转成 BigInt:

1
2
3
4
const bigInt1 = BigInt(10);
console.log(bigInt1); // 10n
const int1 = Number(bigInt1);
console.log(int1);

5.2. Dynamic Import

后续 ES Module 模块化中讲解。

5.3. Nullish Coalescing Operator

ES11,Nullish Coalescing Operator 增加了空值合并操作符:

1
2
3
4
5
const foo = "";
const result1 = foo || "默认值";
const result2 = foo ?? "默认值";
console.log(result1); // 默认值
console.log(result2); // ""

5.4. Optional Chaining

可选链也是 ES11 中新增一个特性,主要作用是让我们的代码在进行 null 和 undefined 判断时更加清晰和简洁:

1
2
3
4
5
6
7
8
9
10
11
const obj = {
friend: {
girlFriend: {
name: "lucy"
}
}
};

if (obj.friend && obj.friend.girlFriend) {
console.log(obj.friend.girlFriend.name);
}

可选链可以帮助我们在有值的情况下返回对应的值,没有值的情况下返回 undefined:

1
2
// 可选链的方式
console.log(obj.friend?.girlFriend?.name);

5.5. Promise.allSettled

后续讲 Promise 的时候讲解。

5.6. Global This

在之前我们希望获取 JavaScript 环境的全局对象,不同的环境获取的方式是不一样的

  • 比如在浏览器中可以通过 this、window 来获取;

  • 比如在 Node 中我们需要通过 global 来获取;

那么在 ES11 中对获取全局对象进行了统一的规范:globalThis

1
2
3
console.log(globalThis);
console.log(this); // 浏览器上
console.log(global); // Node中

5.7. import meta

后续 ES Module 模块化中讲解。

5.8. for..in 标准化

在 ES11 之前,虽然很多浏览器支持 for…in 来遍历对象类型,但是并没有被 ECMA 标准化。

在 ES11 中,对其进行了标准化,for…in 是用于遍历对象的 key 的:

1
2
3
4
5
6
7
8
9
const obj = {
name: "why",
age: 18,
height: 1.88
};

for (const key in obj) {
console.log(key);
}

六. ES12 知识点

6.1. FinalizationRegistry

FinalizationRegistry 对象可以让你在对象被垃圾回收时请求一个回调。

  • FinalizationRegistry 提供了这样的一种方法:当一个在注册表中注册的对象被回收时,请求在某个时间点上调用一个清理回调。(清理回调有时被称为 finalizer );

  • 你可以通过调用register方法,注册任何你想要清理回调的对象,传入该对象和所含的值;

1
2
3
4
5
6
7
8
9
10
let obj = {
name: "why"
};

const registry = new FinalizationRegistry(value => {
console.log("对象被销毁了", value);
});

registry.register(obj, "obj");
obj = null;

6.2. WeakRefs

如果我们默认将一个对象赋值给另外一个引用,那么这个引用是一个强引用:

  • 如果我们希望是一个弱引用的话,可以使用 WeakRef;
1
2
3
4
5
6
7
8
9
10
11
12
let obj = {
name: "why"
};

let info = new WeakRef(obj);

const registry = new FinalizationRegistry(value => {
console.log("对象被销毁了", value);
});

registry.register(obj, "obj");
obj = null;

6.3. logical assignment operators

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 1.逻辑或运算符
let message = "";

// message = message || "hello world"
message ||= "Hello World";
console.log(message);
let obj = { name: "why" };

// 2.逻辑与操作符
// obj = obj && obj.foo()
obj &&= obj.name;
console.log(obj);

// 3.逻辑空运算符
let foo = null;
foo ??= "默认值";
console.log(foo);

6.4. Numeric Separator

1
2
// ES2021新增特性
const num5 = 100_000_000;

七. ES13 知识点

更新 ing ~~~


文章转载于coderwhy | JavaScript 高级系列(十五) - ES6ES13-ES7ES12 知识点