27.ES11 新特性

 

1.私有属性

私有属性只能在类的内部访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Person {
// public
name;
// private
#age;
#weight;

constructor(name, age, weight) {
this.name = name;
this.#age = age;
this.#weight = weight;
}

introduce() {
console.log("name = " + this.name);
console.log("age = " + this.#age);
console.log("weight = " + this.#weight);
}

}

const student = new Person("Tom", 15, "50kg");

console.log(student); // Person {name: 'Tom', #age: 15, #weight: '50kg'}
console.log(student.name); // Tom
console.log(student.#age); // Uncaught SyntaxError: Private field '#age' must be declared in an enclosing class
console.log(student.#weight); // Uncaught SyntaxError: Private field '#weight' must be declared in an enclosing class

student.introduce();
// name = Tom
// age = 15
// weight = 50kg

2.Promise.allSettled()

Promise.allSettled() 返回一个 Promise 对象,并且该对象的状态总是成功的

(1) Promise.allSettled(): 多个 Promise 都是成功的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 声明多个 Promise 对象
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("commodity data 1");
}, 1000);
});

const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("commodity data 2");
}, 1000);
});

const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("commodity data 3");
}, 1000);
});

// 调用 Promise.allSettled() 方法
const result = Promise.allSettled([p1, p2, p3]);

console.log(result);
// Promise {<pending>}
// [[Prototype]]: Promise
// [[PromiseState]]: "fulfilled"
// [[PromiseResult]]: Array(3)
// 0: {status: 'fulfilled', value: 'commodity data 1'}
// 1: {status: 'fulfilled', value: 'commodity data 2'}
// 2: {status: 'fulfilled', value: 'commodity data 3'}
// length: 3
// [[Prototype]]: Array(0)

(2) Promise.allSettled(): 有 Promise 对象的状态是失败的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 声明多个 Promise 对象
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("commodity data 1");
}, 1000);
});

const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("get commodity data 2 failed");
}, 1000);
});

const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("commodity data 3");
}, 1000);
});

// 调用 Promise.allSettled() 方法
const result = Promise.allSettled([p1, p2, p3]);

console.log(result);
// Promise {<pending>}
// [[Prototype]]: Promise
// [[PromiseState]]: "fulfilled"
// [[PromiseResult]]: Array(3)
// 0: {status: 'fulfilled', value: 'commodity data 1'}
// 1: {status: 'rejected', reason: 'get commodity data 2 failed'}
// 2: {status: 'fulfilled', value: 'commodity data 3'}
// length: 3
// [[Prototype]]: Array(0)

Promise.allSettled()Promise.all() 有类似的地方,但是如果有任意一个 Promise 对象的状态是失败的,Promise.all() 返回失败的 Promise 对象,同时报错

(3) Promise.all(): 多个 Promise 都是成功的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 声明多个 Promise 对象
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("commodity data 1");
}, 1000);
});

const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("commodity data 2");
}, 1000);
});

const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("commodity data 3");
}, 1000);
});

// 调用 Promise.all() 方法
const result = Promise.all([p1, p2, p3]);

console.log(result);
// Promise {<pending>}
// [[Prototype]]: Promise
// [[PromiseState]]: "fulfilled"
// [[PromiseResult]]: Array(3)
// 0: "commodity data 1"
// 1: "commodity data 2"
// 2: "commodity data 3"
// length: 3
// [[Prototype]]: Array(0)

(4) Promise.all(): 有 Promise 对象的状态是失败的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 声明多个 Promise 对象
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("commodity data 1");
}, 1000);
});

const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("get commodity data 2 failed");
}, 1000);
});

const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("commodity data 3");
}, 1000);
});

// 调用 Promise.all() 方法
const result = Promise.all([p1, p2, p3]);

console.log(result);
// Promise {<pending>}
// [[Prototype]]: Promise
// [[PromiseState]]: "rejected"
// [[PromiseResult]]: "get commodity data 2 failed"
// Uncaught (in promise) get commodity data 2 failed

Promise.allSettled()Promise.all() 的使用范围:

  • Promise.allSettled(): 适用于有多个异步任务都要执行,需要获取每个异步任务的执行结果
  • Promise.all(): 适用于执行多个异步任务,但是有一个异步任务失败了,就不继续往后执行了

3.String.prototype.matchAll()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
let str = `
<ul>
<li>
<a>MySQL</a>
<p>2020-05-01</p>
</li>
<li>
<a>Redis</a>
<p>2020-06-10</p>
</li>
</ul>`;

// 声明正则表达式
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg;

// 调用 matchAll() 方法
const result = str.matchAll(reg);

console.log(result);
// RegExpStringIterator {}
// [[Prototype]]: RegExp String Iterator
// next: ƒ next()
// Symbol(Symbol.toStringTag): "RegExp String Iterator"
// [[Prototype]]: Object

for (const item of result) {
console.log(item);
}
// 0: "<li>\n <a>MySQL</a>\n <p>2020-05-01</p>"
// 1: "MySQL"
// 2: "2020-05-01"
// groups: undefined
// index: 34
// input: "\n <ul>\n <li>\n <a>MySQL</a>\n <p>2020-05-01</p>\n </li>\n <li>\n <a>Redis</a>\n <p>2020-06-10</p>\n </li>\n </ul>"
// length: 3
// [[Prototype]]: Array(0)

// 0: "<li>\n <a>Redis</a>\n <p>2020-06-10</p>"
// 1: "Redis"
// 2: "2020-06-10"
// groups: undefined
// index: 148
// input: "\n <ul>\n <li>\n <a>MySQL</a>\n <p>2020-05-01</p>\n </li>\n <li>\n <a>Redis</a>\n <p>2020-06-10</p>\n </li>\n </ul>"
// length: 3
// [[Prototype]]: Array(0)

const arr = [...result];
console.log(arr);
// (2) [Array(3), Array(3)]
// 0: Array(3)
// 0: "<li>\n <a>MySQL</a>\n <p>2020-05-01</p>"
// 1: "MySQL"
// 2: "2020-05-01"
// groups: undefined
// index: 34
// input: "\n <ul>\n <li>\n <a>MySQL</a>\n <p>2020-05-01</p>\n </li>\n <li>\n <a>Redis</a>\n <p>2020-06-10</p>\n </li>\n </ul>"
// length: 3
// [[Prototype]]: Array(0)
// 1: Array(3)
// 0: "<li>\n <a>Redis</a>\n <p>2020-06-10</p>"
// 1: "Redis"
// 2: "2020-06-10"
// groups: undefined
// index: 148\
// input: "\n <ul>\n <li>\n <a>MySQL</a>\n <p>2020-05-01</p>\n </li>\n <li>\n <a>Redis</a>\n <p>2020-06-10</p>\n </li>\n </ul>"
// length: 3
// [[Prototype]]: Array(0)
// length: 2
// [[Prototype]]: Array(0)

4.可选链操作符 ?.

(1) 需要对对象进行判空

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function main(config) {
// 需要对 config 参数进行判空,否则如果参数为空,会报错
const dbHost = config.db.host;

console.log(dbHost);
// Uncaught TypeError: Cannot read properties of undefined (reading 'host')
}

main({
// db: {
// host:'192.168.1.100',
// username: 'root'
// },
cache: {
host: '192.168.1.200',
username:'admin'
}
});

(2) 对象属性存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function main(config) {
const dbHost = config && config.db && config.db.host;

console.log(dbHost);
// 192.168.1.100
}

main({
db: {
host:'192.168.1.100',
username: 'root'
},
cache: {
host: '192.168.1.200',
username:'admin'
}
});

(3) 对象属性不存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function main(config){
const dbHost = config && config.db && config.db.host;

console.log(dbHost);
// undefined
}

main({
// db: {
// host:'192.168.1.100',
// username: 'root'
// },
cache: {
host: '192.168.1.200',
username:'admin'
}
});

(4) 对象属性存在: 使用可选链操作符 ?.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 可选链操作符: ?.
function main(config){
const dbHost = config?.db?.host;

console.log(dbHost);
// 192.168.1.100
}

main({
db: {
host:'192.168.1.100',
username: 'root'
},
cache: {
host: '192.168.1.200',
username:'admin'
}
});

(5) 对象属性不存在: 使用可选链操作符 ?.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 可选链操作符 ?.
function main(config){
const dbHost = config?.db?.host;

console.log(dbHost);
// undefined
}

main({
// db: {
// host:'192.168.1.100',
// username: 'root'
// },
cache: {
host: '192.168.1.200',
username:'admin'
}
});

5.动态 import 加载

动态 import 加载,使用模块时再加载该模块

  • test.html
1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动态 import </title>
</head>
<body>
<button id="btn">点击</button>
<script src="./05_js/app.js" type="module"></script>
</body>
</html>
  • app.js

(1) 静态加载

1
2
3
4
5
6
7
8
import * as m1 from "./hello.js"

// 获取元素
const btn = document.getElementById("btn");

btn.onclick = function() {
m1.hello();
}

(2) 动态加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 获取元素
const btn = document.getElementById("btn");

btn.onclick = function() {
import("./hello.js").then(module => {
console.log(module);
// Module {Symbol(Symbol.toStringTag): 'Module'}
// hello: (...)
// Symbol(Symbol.toStringTag): "Module"
// get hello: ƒ ()
// set hello: ƒ ()

module.hello();
})
}
  • hello.js
1
2
3
export function hello() {
alert("Hello");
}

6.BigInt 类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 定义一个 BigInt 类型的数字
let number1 = 32n;
console.log(number1); // 32n
console.log(typeof(number1)); // bigint

// BigInt() 函数
let number2 = 123;
console.log(BigInt(number2)); // 123n
console.log(BigInt(1.2)); // 06_bigint.html:16 Uncaught RangeError: The number 1.2 cannot be converted to a BigInt because it is not an integer

// JavaScript 最大的安全整数
let maxInt = Number.MAX_SAFE_INTEGER;
console.log(maxInt); // 9007199254740991
console.log(maxInt + 1); // 9007199254740992
console.log(maxInt + 2); // 9007199254740992
console.log(maxInt + 10); // 9007199254741000

console.log(BigInt(maxInt)); // 9007199254740991n
console.log(BigInt(maxInt) + BigInt(1)); // 9007199254740992n
console.log(BigInt(maxInt) + BigInt(2)); // 9007199254740993n
console.log(BigInt(maxInt) + BigInt(10)); // 9007199254741001n

// BigInt 不能直接和整形类型直接运算
console.log(BigInt(maxInt) + 1); // Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions

7.globalThis 对象

无论在哪种运行环境,globalThis 始终指向全局对象

(1) 浏览器环境

globalThis: Window 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>globalThis</title>
</head>
<body>
<script>
console.log(globalThis); // Window 对象
</script>
</body>
</html>

(2) node.js 环境

globalThis: Object [global] 对象

1
console.log(globalThis);    // Object [global]