ES2016–ES2019 新特性:按版本理解数组、对象与异步
本文目录
“ES7、ES8、ES9、ES10”通常分别指 ES2016 到 ES2019。学习时不要把相邻年份或提案阶段的 API 混在一起:先确认标准版本,再查目标环境支持,最后由构建工具处理语法或 API 的缺口。
ES2016:更明确的数组判断与求幂
Array.prototype.includes 直接表达成员判断,并能匹配 NaN;indexOf 使用严格相等,因此两者在 NaN 场景不同。** 表示求幂,指数运算优先级需要用括号表达预期,负数底数和小数指数还可能产生非实数结果。
ES2017:async 函数与对象遍历
async 函数总返回 Promise,函数体内抛出的异常会变成拒绝;await 暂停当前 async 函数的后续执行,不阻塞主线程。Object.values / Object.entries 返回对象自身可枚举字符串键对应的值或键值对。padStart / padEnd 补齐文本宽度,不适合做数字精度或安全编码。
async function loadDashboard(urls) {
const responses = await Promise.all(
urls.map(async (url) => {
const response = await fetch(url);
if (!response.ok) throw new Error('HTTP ' + response.status);
return response.json();
}),
);
return Object.fromEntries(responses.map((value, index) => [String(index), value]));
}
这个组合在一个请求失败时整体失败;若每个区块应独立展示,应分别捕获错误或使用对应年份之后新增的结果聚合 API。async/await 让控制流可读,不会让顺序 await 自动并行。
ES2018:异步迭代、对象 rest/spread 与 Promise 清理
对象展开可复制自身可枚举属性,后面的属性覆盖前面的同名属性;这是浅拷贝。对象 rest 可把未单独提取的自有可枚举属性收集到新对象。Promise.prototype.finally 常用于关闭 loading 或释放资源;finally 回调的异常仍可能改变 Promise 链的最终状态。
for await...of 消费异步可迭代对象,按序等待每个结果,适合有背压语义的流式读取;它不是提升吞吐的并发工具。正则还增加 dotAll、命名捕获组、后行断言和 Unicode 属性转义,使用特定表达式前应确认目标引擎支持。
ES2019:数组扁平化与对象往返
flat(depth) 按指定层数扁平化数组,默认一层;flatMap 是 map 后扁平一层,不会递归展开任意深度。Object.fromEntries 把键值对可迭代对象还原为普通对象,适合与 Object.entries 组成转换管道。可选 catch binding 允许在确实不用异常对象时省略变量;trimStart / trimEnd 是去除单侧空白的别名。
当年规范还要求数组排序稳定;仍应写明确比较器和次级排序键,避免把实现细节当成产品规则。稀疏数组、NaN 和 locale 排序仍需按数据语义单独处理。
辨别相邻版本并做兼容验证
以下常被误归到 ES2019、实际属于 ES2020:可选链、空值合并、BigInt、Promise.allSettled、String.prototype.matchAll 和动态 import()。项目配置可能已支持它们,但文章、运行环境和 polyfill 必须使用正确版本标签。
- 构建目标决定语法降级策略;运行时 API 是否存在需另行检查。
- Babel 能改写语法,不会自动为所有浏览器补齐内置对象方法。
- 按目标浏览器执行 CI 和真实浏览器测试,不以开发机新版本代表所有访问者。
- polyfill 要按实际需求加载,避免为一个 API 引入整套全局补丁。
参考:MDN JavaScript reference、MDN Array.prototype.flat、MDN Promise.allSettled、MDN JavaScript modules、ECMAScript specification。
Live Notes
留言提交后会先进入审核,审核通过后对其他读者公开。