ES2025新特性详解
2025年6月25日,第129届Ecma大会正式批准了ECMAScript 2025的语言规范,这标志着JavaScript又迎来了一次重要的升级!
1. Import 属性与 JSON 模块支持
什么是这个特性?
以前我们要加载JSON文件,需要用fetch
然后JSON.parse
,现在可以直接像导入JS模块一样导入JSON文件了!
怎么用?
javascript
// 静态导入JSON文件
import configData from './config.json' with { type: 'json' };
// 动态导入JSON文件
const config = await import('./config.json', {
with: { type: 'json' }
});
实际应用场景
1. 配置文件加载
javascript
// config.json
{
"apiBaseUrl": "https://api.example.com",
"theme": "dark",
"maxRetries": 3
}
// app.js
import config from './config.json' with { type: 'json' };
// 直接使用配置
fetch(`${config.apiBaseUrl}/users`)
.then(res => res.json())
.then(console.log);
2. 多语言国际化
javascript
// zh.json
{
"welcome": "欢迎",
"logout": "退出登录"
}
// en.json
{
"welcome": "Welcome",
"logout": "Log Out"
}
// i18n.js
const lang = navigator.language.startsWith('zh') ? 'zh' : 'en';
const messages = await import(`./${lang}.json`, {
with: { type: 'json' }
});
document.getElementById('welcome').textContent = messages.default.welcome;
2. 迭代器辅助方法 (Iterator Helpers)
什么是这个特性?
以前我们处理数组要用很多map()
, filter()
链式调用,现在有了更优雅的迭代器方法,性能更好,语法更清晰!
基本用法
javascript
const arr = ['a', '', 'b', '', 'c', '', 'd', '', 'e'];
// 新的迭代器方法
const result = arr.values()
.filter(x => x.length > 0) // 过滤空字符串
.drop(1) // 跳过第一个元素
.take(3) // 只取前3个
.map(x => `=${x}=`) // 转换格式
.toArray(); // 转成数组
console.log(result); // ['=b=', '=c=', '=d=']
所有可用方法
- 返回迭代器的方法 :
.filter()
,.map()
,.flatMap()
- 返回布尔值 :
.some()
,.every()
- 返回值 :
.find()
,.reduce()
- 不返回值 :
.forEach()
- 特有方法 :
.drop(n)
,.take(n)
,.toArray()
实际应用 - 处理分页数据
javascript
function getPageLogs(logs, skip = 0, limit = 10) {
return logs.values()
.filter(item => item?.trim()) // 过滤空内容
.drop(skip) // 跳过指定数量
.take(limit) // 取指定数量
.map(line => `[LOG] ${line}`) // 格式化
.toArray(); // 转成数组
}
const logs = [
'', '系统启动', '', '用户登录', '处理请求', '',
'发送响应', '记录日志', '完成', '', '关闭连接'
];
console.log(getPageLogs(logs, 2, 5));
// 输出:['[LOG] 用户登录', '[LOG] 处理请求', '[LOG] 发送响应', '[LOG] 记录日志', '[LOG] 完成']
为什么它更好?
- 惰性执行:按需处理,不会创建中间数组
- 更省内存:适合处理大数据
- 更广泛兼容:支持Set、Map等数据结构
3. Set 新增集合操作方法
什么是这个特性?
Set数据结构新增了数学集合运算方法,让集合操作变得超级简单!
基本用法
javascript
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
// 集合运算
a.union(b); // 并集 Set {1, 2, 3, 4}
a.intersection(b); // 交集 Set {2, 3}
a.difference(b); // 差集 Set {1}
a.symmetricDifference(b); // 对称差集 Set {1, 4}
// 关系判断
a.isSubsetOf(new Set([1, 2, 3, 4])); // 是否为子集 true
a.isSupersetOf(new Set([1, 2])); // 是否为超集 true
a.isDisjointFrom(new Set([5, 6])); // 是否无交集 true
实际应用 - 用户权限管理
javascript
// 用户拥有的权限
const userPermissions = new Set(['read', 'write', 'comment']);
// 页面需要的权限
const pagePermissions = new Set(['read', 'write']);
// 检查用户是否有足够权限
const hasPermission = userPermissions.isSupersetOf(pagePermissions);
console.log(hasPermission); // true
// 找出用户缺少的权限
const requiredPermissions = new Set(['read', 'write', 'admin']);
const missingPermissions = requiredPermissions.difference(userPermissions);
console.log([...missingPermissions]); // ['admin']
4. 正则表达式增强
RegExp.escape() - 字符串转义
解决什么问题? 用户输入的内容可能包含正则特殊字符,直接用会出错。
javascript
// 以前这样会报错
const keyword = '.?*';
const re = new RegExp(keyword, 'g'); // ❌ 错误的正则表达式
// 现在可以安全转义
const safeKeyword = RegExp.escape('.?*'); // '\\.\\?\\*'
const safeRe = new RegExp(safeKeyword, 'g'); // ✅ 正确
// 实际应用:安全搜索
function safeSearch(text, keyword) {
const escapedKeyword = RegExp.escape(keyword);
const re = new RegExp(escapedKeyword, 'g');
return text.replaceAll(re, '🔍');
}
safeSearch('这是一个.net程序', '.net'); // '这是一个🔍程序'
内联修饰符
什么是内联修饰符? 可以在正则表达式的某个部分临时启用某些选项。
javascript
// 只在部分内容中忽略大小写
/^x(?i:HELLO)x$/.test('xHELLOx'); // true
/^x(?i:HELLO)x$/.test('xhellox'); // true
/^x(?i:HELLO)x$/.test('XhelloX'); // false(开头结尾仍然区分大小写)
命名重复捕获组
解决什么问题? 以前同一个捕获组名称只能用一次,现在可以在不同分支中重复使用。
javascript
// 匹配不同格式的值,但用同一个名称
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})|(?<day>\d{2})\/(?<month>\d{2})\/(?<year>\d{4})/;
const result1 = dateRegex.exec('2025-01-15');
console.log(result1.groups); // {year: '2025', month: '01', day: '15'}
const result2 = dateRegex.exec('15/01/2025');
console.log(result2.groups); // {year: '2025', month: '01', day: '15'}
5. Promise.try() - 统一异常处理
什么是这个特性?
以前处理同步和异步混合的代码很麻烦,现在有了Promise.try()
,可以统一处理!
以前的痛点
javascript
// 混合同步异步代码,异常处理很麻烦
try {
const val = syncFunction(); // 同步函数
await asyncFunction(val); // 异步函数
} catch (err) {
handleError(err);
}
现在的解决方案
javascript
// 用Promise.try()统一处理
Promise.try(() => {
const val = syncFunction(); // 同步函数
return asyncFunction(val); // 异步函数
}).catch(handleError); // 统一错误处理
实际应用
javascript
// 数据处理函数,可能同步也可能异步
function processData(data) {
if (data.cached) {
return data.value; // 同步返回
} else {
return fetchFromAPI(data.id); // 异步获取
}
}
// 统一处理
Promise.try(() => processData(userData))
.then(result => {
console.log('处理结果:', result);
})
.catch(error => {
console.error('处理失败:', error);
});
6. 16位浮点数支持
什么是这个特性?
新增了对16位浮点数的支持,主要用于AI模型、图像处理、WebGPU等需要大量浮点计算但对精度要求不高的场景。
新增API
javascript
// Float16Array - 16位浮点数组
const f16Array = new Float16Array([1.0, 0.5, 0.25]);
console.log(f16Array); // Float16Array(3) [1, 0.5, 0.25]
// Math.f16round - 转换为16位浮点精度
const precise = Math.f16round(3.141592653589793);
console.log(precise); // 3.140625
// DataView支持
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
// 写入16位浮点数
view.setFloat16(0, 3.1415);
view.setFloat16(2, 2.7182);
// 读取16位浮点数
console.log(view.getFloat16(0)); // 3.140625
console.log(view.getFloat16(2)); // 2.71875
实际应用场景
1. AI模型权重存储
javascript
// 存储神经网络权重,节省一半内存
const modelWeights = new Float16Array([
0.1, -0.2, 0.35, -0.8, 0.12, 0.95
]);
// 节省内存:Float32Array需要24字节,Float16Array只需要12字节
2. 图像处理
javascript
// 处理图像像素值
function processImageData(imageData) {
const pixels = new Float16Array(imageData.length);
for (let i = 0; i < imageData.length; i++) {
// 归一化到0-1范围
pixels[i] = Math.f16round(imageData[i] / 255);
}
return pixels;
}
总结
ES2025的这些新特性让JavaScript更加强大和易用:
- Import JSON - 让配置文件和数据文件导入变得简单
- 迭代器辅助 - 提供更优雅的数据处理方式
- Set集合运算 - 让集合操作像数学一样直观
- 正则增强 - 提供更安全和灵活的文本处理
- Promise.try() - 统一同步异步代码的错误处理
- 16位浮点数 - 为AI和图形处理提供更好的性能
这些特性不仅提高了代码的可读性和可维护性,还在性能和内存使用方面带来了实质性的改进。现在就开始在你的项目中使用这些新特性吧!
浏览器支持
目前这些特性还在逐步实现中,建议在使用前检查目标浏览器的兼容性。可以使用Babel等工具进行转译,确保在老版本浏览器中也能正常运行。