跳到主要内容

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 漏洞),实际使用中需要配合 CrossOriginOpenerPolicyCrossOriginEmbedderPolicy 头部
  • 主要用于高性能计算场景

六、 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