2017 年 6 月正式发布的 ECMAScript 2017(ES8)是 JavaScript 的一次重要更新。
一、 Async/Await:异步编程
旨在简化 Promise 的使用,使异步代码看起来更像同步代码。
async:用于声明异步函数,该函数返回一个Promise对象await:只能在async中使用,用于等待Promise的完成并获取结果
// 传统Promise链式调用
fetchData()
.then(data => processData(data))
.then(result => console.log(result))
.catch(error => console.error(error));
// Async/Await写法
async function handleData() {
try {
const data = await fetchData();
const result = await processData(data);
console.log(result);
} catch (error) {
console.error(error);
}
}
用途
- 代码解构更清晰,避免“回调地狱”
- 错误处理更直观(可使用
try/catch) - 调试更友好,执行流程更符合直觉
二、 对象方法扩展
新增了 Object.value() 和 Object.entries() 两个静态方法,简化对象的遍历操作
1. Object.values()
- 返回一个包含对象所有可枚举属性值的数组
const obj = { a: 1, b: 2, c: 3 };
// [1, 2, 3]
console.log(Object.values(obj));
提示
Object.keys() 早在 ES5(2009 年) 的时候就已经引入了
2. Object.entries()
- 返回一个包含对象所有可枚举的属性 [key, value] 的二维数组
const obj = { a: 1, b: 2, c: 3 };
// [['a', 1], ['b', 2], ['c', 3]]
console.log(Object.entries(obj));
// 便于对象转换为Map
const map = new Map(Object.entries(obj));
备注
个人感觉就像是 for...in 的函数式编程版
- 与数组
values()和entries()方法保持一致 - 减缓对象到数组的转换,便于使用数组方法处理对象数据
3. Object.getOwnPropertyDescriptors() 获取属性描述符
返回指定对象所有只有属性的描述符(包括getter/setter)。
const obj = {
name: 'es8',
get version() {
return 2017;
},
};
// {
// name: {
// value: 'es8',
// writable: true,
// enumerable: true,
// configurable: true,
// },
// version: {
// get: '[function]',
// set: undefined,
// enumerable: true,
// configurable: true,
// },
// };
console.log(Object.getOwnPropertyDescriptors(obj));
用途
- 精确复制对象(包括
getter/setter) - 实现对象的继承(配合
Object.create())
// 完整复制对象
const copy = Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj),
);
三、 字符串填充:padStart() 和 padEnd()
为字符串提供补全功能,常用于格式化输出。
padStart(targetLength[, padString]):在字符串开头填充指定的字符,直到达到目标长度padEnd(targetLength[, padString]):在字符串结尾填充指定字符,直到达到目标长度
console.log('123'.padStart(5, '0')); // "00123"
console.log('abc'.padEnd(6, 'xyz')); // "abcxyz"
console.log('hi'.padStart(5)); // " hi" (默认时使用空格填充)
用途
- 数字格式化(如日期、时间的补零)
- 文本对齐显示
- 密码掩码处理
四、 函数参数列表和调用中的尾逗号
允许在函数参数列表和调用时诸侯一个参数后添加逗号,不影响代码的执行
// 函数定义
function foo(
a,
b, // 尾逗号允许
) {}
// 函数调用
foo(
1,
2, // 尾逗号允许
);
用途
- 简化代码格式化和版本控制(减少行修改冲入)
- 便于添加/删除参数,无需调整逗号的位置
五、 SharedArrayBuffer 共享内存
用户多个工作线程(Worker)之间共享二进制数据,提高数据传输效率
// 主线程
const buffer = new SharedArrayBuffer(1024); // 1KB共享内存
const worker = new Worker('worker.js');
worker.postMessage(buffer);
// worker.js
self.onmessage = e => {
const buffer = e.data;
// 操作共享内存
};
注意
- 由于安全问题(Spectre 漏洞),实际使用中需要配合
CrossOriginOpenerPolicy和CrossOriginEmbedderPolicy头部 - 主要用于高性能计算场景
六、 Atomics:原子操作
提供了一组静态方法,确保在多线程环境下对共享内存的操作是原子性的,避免竟态条件。
常用方法
Atomics.add():原子性地添加值Atomics.load():原子性地读取值Atomics.store():原子性地写入值Atomics.wait()/Atomics.wake():线程同步
const buffer = new SharedArrayBuffer(4);
const arr = new Int32Array(buffer);
// 原子操作
Atomics.store(arr, 0, 10);
console.log(Atomics.load(arr, 0)); // 10
Atomics.add(arr, 0, 5);
console.log(Atomics.load(arr, 0)); // 15