作为全球应用最广泛的编程语言之一,JavaScript 每年都在通过 ECMAScript 标准持续进化。2025 年,ECMAScript 再次带来多项重磅更新,本文将带你深入解读已正式定稿的核心特性,
问题背景:同步函数与异步 Promise 的异常处代码理割裂的问题
// 传统方式需要手动包裹同步函数
function fetchData() {
if (Math.random() console.log(data))
.catch(err => console.error('统一捕获:', err));
//传统方案
try{
fetchData
.then(data => console.log(data))
.catch(err => console.error('统一捕获:', err));
} catch{
}
优势:
新增 API:
const devs = new Set(['Alice', 'Bob']);
const seniors = new Set(['Alice', 'Charlie']);
// 交集:同时具备开发与资深身份
devs.intersection(seniors); // Set {'Alice'}
// 差集:普通开发者
devs.difference(seniors); // Set {'Bob'}
// 并集:所有相关人员
devs.union(seniors); // Set {'Alice','Bob','Charlie'}
这个新增的api倒是让我想起 Python 的交集并集运算了
随着 Javascript 的快速发展,现在如今变成了语法最为灵活且速度最快的语言,越来越多 Python 的语法特性被 Javascript 借鉴过来了,
人生苦短,我用 python
这句话的主角也许可以换成 Javascript 了
那么留下一个思考题 Python 是否最终会被更灵活的JS取代呢?
传统正则表达式中,若多个分支需要捕获同类数据但格式不同,开发者必须为每个分支定义不同的组名:
// 旧方案:不同格式需不同组名
const OLD_DATE_REGEX = /^
(?d{4})-(?d{2})-(?d{2}) // 格式1:YYYY-MM-DD
|
(?d{2})/(?d{2})/(?d{4}) // 格式2:MM/DD/YYYY
$/;
// 需手动判断匹配分支
const { y, m, d } = match.groups || {};
const year = y || match.groups.y2; // 冗余的条件判断
新语法的优势
使用重复命名捕获组后,不同分支可复用相同组名,直接通过统一字段访问数据:
// ES2025 新方案:统一组名
const DATE_REGEX = /^
(?d{4})-(?d{2})-(?d{2})
|
(?d{2})/(?d{2})/(?d{4})
$/;
// 直接解构,无需条件判断
const { year, month, day } = match.groups; // 自动匹配对应分支的组
精准控制匹配规则:
// 仅对部分模式启用忽略大小写
const re = /HELLO(?i: World)/;
re.test('HELLO world'); // true(World 部分不区分大小写)
延迟模块加载 (Deferred Module Evaluation)
优化大型应用启动性能:
// 按需加载重型模块
defer import heavyModule from './heavy.js';
button.onclick = async () => {
await heavyModule.run(); // 点击时才加载
};
那在这里有个疑问? 都是按需加载? 这跟动态加载的方案有啥本质区别呢?
示例:
// 声明时预加载模块(不执行代码)
defer import { heavyModule } from './heavy-module.js';
button.onclick = async () => {
// 点击时触发模块执行(此时模块已加载完毕)
await heavyModule.run();
};
优势:
import()
时触发模块的异步加载和立即执行。await
或 .then()
处理。示例:
// 点击时触发加载和执行
button.onclick = async () => {
const { heavyModule } = await import('./heavy-module.js');
heavyModule.run();
};
首屏优化
的问题虽然我们现在也是会用懒加载
或者按需加载
的办法去进行首屏优化,
但是这两个方案都有一个共同的痛点就是用户体验极差 (用户无法实时看到内容,有时候我们需要使用hack技巧去预加载这些本来需要按需加载的模块)
懒加载方案问题:
懒加载方案会导致用户拖动到隐藏区域的视口后才会触发加载,如果是图片为主的区域,用户会看到一段白屏时间,一般我们会结合预加载去解决
动态导入的问题:
动态引入方案,特别是弹窗这种资源, 在你第一次打开的时候会出现白屏和闪屏的现象
延迟模块加载天生自带预加载和按需加载的功能, 所以大大简化了我们的代码
// 延迟模块加载:依赖已预加载但未执行
defer import { A } from './a.js';
defer import { B } from './b.js';
async function run() {
// 执行时触发 A 和 B 的代码
await A.init();
await B.init();
}
// 动态 import:运行时按需加载依赖
async function loadDependencies() {
const { A } = await import('./a.js');
const { B } = await import('./b.js');
await A.init();
await B.init();
}
阶段 | 延迟模块加载 | 动态 import |
---|---|---|
加载 | 声明时触发加载(与 HTML 解析并行) | 调用时触发加载 |
解析/编译 | 加载后立即完成 | 加载后立即完成 |
执行 | 延迟到首次访问导出时 | 加载完成后立即执行 |
缓存 | 全局模块缓存(与静态导入共享) | 全局模块缓存(与静态导入共享) |
特性 | 延迟模块加载 (Deferred Import) | 动态 import (Dynamic Import) |
---|---|---|
语法 | defer import { ... } from '...' |
await import('...') |
加载时机 | 声明时预加载,访问时触发执行 | 调用时异步加载并执行 |
执行顺序 | 模块代码延迟到首次访问时执行 | 立即执行模块代码 |
是否阻塞主线程 | 非阻塞(预加载资源,延迟执行) | 非阻塞(异步加载) |
适用场景 | 需要预加载但延迟执行的模块 | 按需加载的代码分割场景 |
两者可组合使用:用 defer import
预加载关键模块,用 import()
处理动态路由,达到最佳性能平衡。
参与评论
手机查看
返回顶部