JavaScript 作为世界上最流行的编程语言之一,一直在不断发展和进化。从 2016 年的 ES7 到 2024 年的 ES15,每年都会有新的语言特性和功能被添加进来。这些更新不仅提升了语言的表达能力,也为开发者提供了更多便利的工具和更优雅的解决方案。
本文将按时间顺序,详细介绍从 ES2016 到 ES2024 各个版本中引入的重要特性
ES2016(ES7)
Array.prototype.includes
-
详细讲解:
- 作用:用于判断数组中是否包含指定元素,返回布尔值(true/false)
- 语法:
array.includes(searchElement[, fromIndex])
- 参数:
searchElement
:要查找的元素fromIndex
(可选):开始搜索的位置索引。默认为0
- 特点:
- 可以检测
NaN
,而indexOf
不能 - 对比
indexOf
,返回值更直观(布尔值 vs 索引值) - 支持负数索引,如
-1
表示从末尾开始 - 对
undefined
和null
也能正确处理
- 可以检测
-
代码示例:
javascriptconst numbers = [1, 2, 3, NaN, undefined, null]; // 基础用法 numbers.includes(2); // true numbers.includes(4); // false // 处理特殊值 numbers.includes(NaN); // true numbers.includes(undefined); // true numbers.includes(null); // true // 指定起始位置 numbers.includes(1, 1); // false,从索引1开始查找 numbers.includes(3, -2); // false,从倒数第2个元素开始查找
-
应用场景:
- 权限验证
javascriptconst userPermissions = ['read', 'write', 'delete']; function canUserDelete() { return userPermissions.includes('delete'); }
- 表单验证
javascriptconst validTypes = ['jpg', 'png', 'gif']; function isValidFileType(filename) { const extension = filename.split('.').pop().toLowerCase(); return validTypes.includes(extension); }
- 条件判断优化
javascript// 旧写法 if (status === 'pending' || status === 'processing' || status === 'waiting') { // ... } // 新写法 const loadingStates = ['pending', 'processing', 'waiting']; if (loadingStates.includes(status)) { // ... }
指数运算符 **
-
详细讲解:
- 作用:提供了一种更简洁的幂运算方式,替代
Math.pow()
- 语法:
base ** exponent
- 特点:
- 支持与赋值运算符组合(
**=
) - 运算优先级高于乘除
- 支持负数底数,但需要括号
- 支持小数指数
- 右结合性(从右向左计算)
- 支持与赋值运算符组合(
- 作用:提供了一种更简洁的幂运算方式,替代
-
代码示例:
javascript// 基础用法 2 ** 3; // 8 3 ** 2; // 9 // 与赋值运算符组合 let x = 2; x **= 3; // x = 8 // 优先级示例 2 ** 3 * 2; // 16 (先计算 2^3,再乘以 2) 2 * 3 ** 2; // 18 (先计算 3^2,再乘以 2) // 负数底数 (-2) ** 2; // 4 // -2 ** 2; // 语法错误,需要括号 // 小数指数 8 ** (1/3); // 2 (立方根) 16 ** 0.5; // 4 (平方根) // 右结合性 2 ** 3 ** 2; // 512 (等同于 2 ** (3 ** 2))
-
应用场景:
- 数学计算
javascript// 计算圆面积 const getCircleArea = radius => Math.PI * (radius ** 2); // 计算复利 const compound = (principal, rate, years) => { return principal * ((1 + rate) ** years); };
- 3D变换
javascript// 3D缩放变换 const scale3d = (x, y, z, factor) => ({ x: x * (factor ** 1), y: y * (factor ** 1), z: z * (factor ** 1) });
- 动画缓动函数
javascript// 二次方缓动 const easeQuadratic = progress => progress ** 2; // 三次方缓动 const easeCubic = progress => progress ** 3;
ES2017(ES8)
Object.values()
/ Object.entries()
-
详细讲解:
- 作用:
Object.values()
:返回对象自身所有可枚举属性的值的数组Object.entries()
:返回对象自身所有可枚举属性的键值对数组
- 语法:
Object.values(obj)
Object.entries(obj)
- 特点:
- 只返回对象自身的可枚举属性
- 属性顺序遵循:
- 数字键(按升序)
- 字符串键(按添加顺序)
- Symbol键(按添加顺序)
- 不会返回原型链上的属性
- 对非对象参数会强制转换为对象
- 作用:
-
代码示例:
javascript// Object.values() 示例 const person = { name: 'Alice', age: 30, role: 'developer' }; Object.values(person); // ['Alice', 30, 'developer'] // 数字键排序 const obj = { 2: 'b', 1: 'a', 3: 'c' }; Object.values(obj); // ['a', 'b', 'c'] // 处理特殊类型 Object.values('hello'); // ['h', 'e', 'l', 'l', 'o'] Object.values(100); // [] // Object.entries() 示例 Object.entries(person); // [ // ['name', 'Alice'], // ['age', 30], // ['role', 'developer'] // ]
-
应用场景:
- 对象转换
javascript// 对象转Map const obj = { key1: 'value1', key2: 'value2' }; const map = new Map(Object.entries(obj)); // 对象转FormData const formData = new FormData(); Object.entries(obj).forEach(([key, value]) => { formData.append(key, value); });
- 数据处理
javascript// 计算对象值的总和 const scores = { math: 95, english: 88, science: 92 }; const total = Object.values(scores).reduce((sum, score) => sum + score, 0); // 对象值过滤 const filtered = Object.entries(scores) .filter(([_, score]) => score >= 90) .reduce((obj, [subject, score]) => { obj[subject] = score; return obj; }, {});
- 数据可视化
javascript// 转换为图表数据格式 const data = { 'Q1': 1000, 'Q2': 1500, 'Q3': 1200, 'Q4': 2000 }; const chartData = { labels: Object.keys(data), values: Object.values(data) };
async/await
-
详细讲解:
- 作用:以同步的方式编写异步代码
- 核心概念:
async
:声明异步函数,总是返回 Promiseawait
:暂停执行,等待 Promise 解决
- 特点:
- 简化 Promise 链式调用
- 更好的错误处理机制
- 调试更容易
- 支持并行执行
-
代码示例:
javascript// 基本使用 async function fetchUserData(userId) { try { const user = await fetch(`/api/users/${userId}`); const posts = await fetch(`/api/posts?userId=${userId}`); return { user: await user.json(), posts: await posts.json() }; } catch (error) { console.error('Error fetching user data:', error); throw error; } } // 并行执行 async function fetchMultipleUsers(userIds) { const promises = userIds.map(id => fetch(`/api/users/${id}`)); const users = await Promise.all(promises); return await Promise.all(users.map(user => user.json())); } // 循环中的异步操作 async function processItems(items) { // 串行执行 for (const item of items) { await processItem(item); } // 并行执行 await Promise.all(items.map(processItem)); }
-
应用场景:
- API 请求处理
javascriptasync function uploadFile(file) { try { // 1. 获取上传URL const { uploadUrl } = await getUploadUrl(); // 2. 上传文件 const response = await fetch(uploadUrl, { method: 'PUT', body: file }); // 3. 确认上传 if (response.ok) { await confirmUpload(file.name); } return response; } catch (error) { handleUploadError(error); } }
- 数据库操作
javascriptasync function createUser(userData) { const connection = await db.connect(); try { await connection.beginTransaction(); const user = await connection.query( 'INSERT INTO users SET ?', userData ); await connection.query( 'INSERT INTO user_settings SET ?', { userId: user.insertId } ); await connection.commit(); return user; } catch (error) { await connection.rollback(); throw error; } finally { connection.release(); } }
- 资源加载
javascriptasync function loadApplication() { // 并行加载资源 const [ config, translations, userPreferences ] = await Promise.all([ loadConfig(), loadTranslations(), loadUserPreferences() ]); // 初始化应用 await initApp({ config, translations, userPreferences }); }
String.prototype.padStart()
/ String.prototype.padEnd()
-
详细讲解:
- 作用:
padStart()
:在字符串开头填充字符padEnd()
:在字符串末尾填充字符
- 语法:
str.padStart(targetLength [, padString])
str.padEnd(targetLength [, padString])
- 特点:
- 如果不指定填充字符,默认使用空格
- 如果目标长度小于等于原字符串长度,返回原字符串
- 如果填充后超过目标长度,会截断填充字符串
- 作用:
-
代码示例:
javascript// 基础用法 'abc'.padStart(6); // ' abc' 'abc'.padStart(6, '0'); // '000abc' 'abc'.padEnd(6, '0'); // 'abc000' // 截断填充字符 'abc'.padStart(6, '123456'); // '123abc' // 实际应用 const numbers = [1, 2, 3, 4]; numbers.map(n => n.toString().padStart(2, '0')); // ['01', '02', '03', '04']
-
应用场景:
- 数字格式化
javascript
// 格式化日期
const month = '5';
const day = '7';
const formattedDate = `${month.padStart(2, '0')}/${day.padStart(2, '0')}`; // "05/07"
// 格式化数字
const formatNumber = n => n.toString().padStart(6, '0');
formatNumber(123); // "000123"
- 表格对齐
javascript
const data = ['a', 'ab', 'abc'];
const aligned = data.map(s => s.padEnd(5, ' '));
// ["a ", "ab ", "abc "]
- 掩码处理
javascript
// 信用卡号掩码
const maskCreditCard = num =>
num.slice(-4).padStart(num.length, '*');
maskCreditCard('1234567890123456'); // "************3456"
Object.getOwnPropertyDescriptors()
-
详细讲解:
- 作用:获取对象所有自有属性的描述符
- 语法:
Object.getOwnPropertyDescriptors(obj)
- 特点:
- 返回包含所有属性描述符的对象
- 包括不可枚举属性
- 包括符号属性
- 描述符包含:value, writable, enumerable, configurable, get, set
-
代码示例:
javascriptconst obj = { name: 'test', get age() { return 18; } }; const descriptors = Object.getOwnPropertyDescriptors(obj); // { // name: { // value: 'test', // writable: true, // enumerable: true, // configurable: true // }, // age: { // get: [Function: get age], // set: undefined, // enumerable: true, // configurable: true // } // }
-
应用场景:
- 克隆对象(包括 getter/setter)
javascriptconst source = { set name(value) { this._name = value; }, get name() { return this._name; } }; const clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(source) );
- 合并对象
javascriptconst target = { name: 'target' }; const source = { get value() { return 42; } }; Object.defineProperties(target, Object.getOwnPropertyDescriptors(source) );
SharedArrayBuffer
- 用于在多线程环境中共享内存
ES2019(ES10)
Array.prototype.flat()
和 Array.prototype.flatMap()
-
详细讲解:
- 作用:
flat()
:将嵌套数组扁平化处理flatMap()
:先映射再扁平化,相当于map()
和flat()
的组合
- 语法:
arr.flat([depth])
:depth 默认为 1arr.flatMap((currentValue, index, array) => { ... })
- 特点:
- 自动移除空项
- 支持指定展开深度
flatMap
只能展开一层- 处理非数组元素时会跳过
- 作用:
-
代码示例:
javascript// flat() 基础用法 const numbers = [1, [2, 3], [4, [5, 6]]]; numbers.flat(); // [1, 2, 3, 4, [5, 6]] numbers.flat(2); // [1, 2, 3, 4, 5, 6] // 处理空项 const array = [1, 2, , 4, 5]; array.flat(); // [1, 2, 4, 5] // flatMap() 示例 const sentences = ["Hello world", "JavaScript is awesome"]; sentences.flatMap(s => s.split(' ')); // ['Hello', 'world', 'JavaScript', 'is', 'awesome'] // 数值计算 const numbers = [1, 2, 3]; numbers.flatMap(x => [x, x * 2]); // [1, 2, 2, 4, 3, 6]
-
应用场景:
- 数据处理
javascript// 处理多层JSON数据 const comments = [ { replies: [ { text: 'Great!', replies: [] }, { text: 'Nice!', replies: [] } ]}, { replies: [ { text: 'Awesome!', replies: [] } ]} ]; const allReplies = comments .flatMap(comment => comment.replies) .map(reply => reply.text);
- 文本处理
javascript// 分词并过滤 const text = [" hello ", " world "]; const words = text .flatMap(str => str.trim().split(/\s+/)) .filter(Boolean);
Object.fromEntries()
-
详细讲解:
- 作用:将键值对列表转换为对象
- 语法:
Object.fromEntries(iterable)
- 特点:
- 接受任何实现了迭代器接口的对象
- 是
Object.entries()
的逆操作 - 可用于 Map 转对象
- 自动转换键为字符串
-
代码示例:
javascript// 基础用法 const entries = [ ['name', 'Alice'], ['age', 25], ['city', 'Beijing'] ]; const obj = Object.fromEntries(entries); // { name: 'Alice', age: 25, city: 'Beijing' } // Map 转对象 const map = new Map([ ['foo', 'bar'], ['baz', 42] ]); const obj2 = Object.fromEntries(map); // { foo: 'bar', baz: 42 } // URL 参数处理 const paramsString = 'user=alice&page=1&limit=10'; const searchParams = new URLSearchParams(paramsString); const paramsObject = Object.fromEntries(searchParams); // { user: 'alice', page: '1', limit: '10' }
-
应用场景:
- 数据转换
javascript// 过滤对象属性 const object = { a: 1, b: 2, c: 3 }; const filtered = Object.fromEntries( Object.entries(object) .filter(([key, value]) => value > 1) ); // { b: 2, c: 3 }
- 表单处理
javascript// FormData 转对象 const form = document.querySelector('form'); const formData = new FormData(form); const data = Object.fromEntries(formData);
- 配置处理
javascript// 合并默认配置 const defaults = { theme: 'light', lang: 'en' }; const userPrefs = new Map([ ['theme', 'dark'], ['fontSize', '16px'] ]); const config = { ...defaults, ...Object.fromEntries(userPrefs) };
String.prototype.trimStart()
/ String.prototype.trimEnd()
-
详细讲解:
- 作用:
trimStart()
:删除字符串开头的空白字符trimEnd()
:删除字符串末尾的空白字符
- 别名:
trimLeft()
是trimStart()
的别名trimRight()
是trimEnd()
的别名
- 特点:
- 不修改原字符串
- 移除所有空白字符(空格、制表符、换行符等)
- 作用:
-
代码示例:
javascriptconst text = ' Hello World '; text.trimStart(); // 'Hello World ' text.trimEnd(); // ' Hello World' // 实际应用 function normalizeInput(input) { return input.trimStart().toLowerCase(); } // 处理多行文本 const multiline = ` Some text with spaces `; multiline.trimStart().trimEnd(); // 'Some text\n with spaces'
Symbol.prototype.description
-
详细讲解:
- 作用:获取 Symbol 的描述字符串
- 语法: symbol.description
- 特点:
- 只读属性
- 返回创建 Symbol 时传入的描述
- 如果没有描述则返回 undefined
-
代码示例:
javascriptconst sym1 = Symbol('foo'); console.log(sym1.description); // 'foo' const sym2 = Symbol(); console.log(sym2.description); // undefined // 实际应用 const symbols = { RED: Symbol('red'), GREEN: Symbol('green'), BLUE: Symbol('blue') }; function getColorName(colorSymbol) { return colorSymbol.description || 'unknown'; }
Function.prototype.toString()
-
详细讲解:
- 作用:返回函数的源代码字符串
- 改进:现在保留了空格和注释
- 特点:
- 包含完整的函数声明
- 保持原始格式
- 适用于调试和文档生成
-
代码示例:
javascriptfunction /* comment */ test(x) { return x + 1; // increment } console.log(test.toString()); // 'function /* comment */ test(x) { // return x + 1; // increment // }' // 实际应用:函数文档生成 function extractFunctionDocs(fn) { const source = fn.toString(); const comments = source.match(/\/\*[\s\S]*?\*\/|\/\/.*/g) || []; return comments.map(c => c.trim()); }
try...catch 绑定参数可选
-
详细讲解:
- 作用:catch 子句的参数变为可选
- 特点:
- 当不需要错误对象时可以省略
- 提高代码简洁性
- 避免未使用变量警告
-
代码示例:
javascript// 旧写法 try { // 可能抛出错误的代码 } catch (error) { // 不使用 error 对象 console.log('发生错误'); } // 新写法 try { // 可能抛出错误的代码 } catch { console.log('发生错误'); } // 实际应用 async function validateJSON(str) { try { JSON.parse(str); return true; } catch { return false; } }
ES2020(ES11)
Promise.allSettled()
-
详细讲解:
- 作用:等待所有 Promise 完成(无论成功或失败)
- 语法:
Promise.allSettled(iterable)
- 返回值:包含所有 Promise 结果的数组,每个结果对象包含:
status
:'fulfilled' 或 'rejected'value
:成功值(如果成功)reason
:失败原因(如果失败)
- 特点:
- 总是返回成功的 Promise
- 不会因为单个 Promise 失败而中断
- 适合处理多个独立的异步操作
-
代码示例:
javascriptconst promises = [ fetch('/api/user'), fetch('/api/invalid-url'), fetch('/api/posts') ]; const results = await Promise.allSettled(promises); results.forEach(result => { if (result.status === 'fulfilled') { console.log('成功:', result.value); } else { console.log('失败:', result.reason); } }); // 实际应用 async function uploadFiles(files) { const uploadPromises = files.map(file => uploadFile(file)); const results = await Promise.allSettled(uploadPromises); const succeeded = results.filter(r => r.status === 'fulfilled'); const failed = results.filter(r => r.status === 'rejected'); return { successful: succeeded.length, failed: failed.length, failedFiles: failed.map(r => r.reason) }; }
可选链操作符 ?.
和空值合并运算符 ??
-
详细讲解:
- 可选链
?.
:- 安全访问可能为 null/undefined 的属性
- 可用于属性访问、方法调用、数组索引
- 短路特性:一旦遇到 null/undefined 立即返回
- 空值合并
??
:- 仅当左侧为 null/undefined 时使用右侧值
- 区别于
||
:不会将 falsy 值(如 0、'')视为假
- 可选链
-
代码示例:
javascript// 可选链示例 const user = { address: { street: 'Main St', city: 'Beijing' }, orders: [ { id: 1, items: ['book', 'pen'] } ] }; // 属性访问 console.log(user?.address?.street); // 'Main St' console.log(user?.contact?.phone); // undefined(不报错) // 方法调用 console.log(user.getAge?.()); // undefined(不报错) // 数组访问 console.log(user.orders?.[0]?.items); // ['book', 'pen'] // 空值合并示例 const config = { timeout: 0, retries: null, maxSize: undefined }; console.log(config.timeout ?? 1000); // 0(保留0值) console.log(config.retries ?? 3); // 3 console.log(config.maxSize ?? 5000); // 5000
-
应用场景:
- API 响应处理
javascriptasync function getUserData(userId) { const response = await fetch(`/api/users/${userId}`); const user = await response.json(); return { name: user?.name ?? 'Unknown', email: user?.contact?.email ?? 'No email', city: user?.address?.city ?? 'No city', orders: user?.orders?.length ?? 0 }; }
- 配置对象处理
javascriptfunction initializeApp(config) { return { debug: config?.debug ?? false, api: { url: config?.api?.url ?? 'http://localhost', timeout: config?.api?.timeout ?? 5000, retries: config?.api?.retries ?? 3 }, theme: config?.theme ?? 'light' }; }
BigInt
-
详细讲解:
- 作用:表示任意精度的整数
- 语法:数字后加
n
或使用BigInt()
- 特点:
- 可以安全地表示超过 2^53 的整数
- 支持基本算术运算
- 不能与普通数字混合运算
- 不支持小数
-
代码示例:
javascript// 创建 BigInt const bigInt = 9007199254740991n; const anotherBigInt = BigInt("9007199254740991"); // 基本运算 const sum = bigInt + 1n; const product = bigInt * 2n; // 比较操作 console.log(1n < 2n); // true console.log(2n > 1n); // true console.log(2n === 2); // false console.log(2n == 2); // true // 实际应用 function factorial(n) { let result = 1n; for (let i = 2n; i <= n; i++) { result *= i; } return result; } console.log(factorial(50n)); // 超大整数阶乘
globalThis
-
详细讲解:
- 作用:提供统一的全局对象访问方式
- 特点:
- 在任何环境下都指向全局对象
- 浏览器中是 window
- Node.js 中是 global
- Web Workers 中是 self
-
代码示例:
javascript// 以前的兼容性写法 const getGlobal = function() { if (typeof self !== 'undefined') return self; if (typeof window !== 'undefined') return window; if (typeof global !== 'undefined') return global; throw new Error('无法找到全局对象'); }; // 现在可以直接使用 console.log(globalThis); // 指向当前环境的全局对象 // 实际应用 function isRunningInBrowser() { return globalThis.window === globalThis; } function isRunningInNode() { return globalThis.process?.versions?.node != null; }
动态导入
-
详细讲解:
- 作用:按需动态加载模块
- 语法:
import()
- 特点:
- 返回 Promise
- 支持条件导入
- 可用于代码分割
-
代码示例:
javascript// 基础用法 const modulePath = './modules/math.js'; import(modulePath) .then(module => { console.log(module.sum(2, 3)); }); // 异步函数中使用 async function loadModule(name) { const module = await import(`./modules/${name}.js`); return module; } // 条件导入 async function loadLocaleMessages(locale) { const messages = await import( `/i18n/${locale}.js` ); return messages.default; } // 实际应用:按需加载组件 async function loadComponent(name) { const component = await import( `/components/${name}.js` ); return component.default; }
ES2021(ES12)
String.prototype.replaceAll()
-
详细讲解:
- 作用:替换字符串中所有匹配项
- 语法:
str.replaceAll(searchValue, replacement)
- 参数:
searchValue
:要替换的字符串或正则表达式replacement
:替换值(字符串或函数)
- 特点:
- 不修改原字符串
- 支持正则表达式(需要带 g 标志)
- 支持函数作为替换值
-
代码示例:
javascript// 基础用法 const str = 'hello hello world'; str.replaceAll('hello', 'hi'); // 'hi hi world' // 使用正则表达式 const text = 'cat, bat, sat, fat'; text.replaceAll(/[a-z]at/g, 'word'); // 'word, word, word, word' // 使用替换函数 const prices = '价格: $10, $20, $30'; prices.replaceAll(/\$(\d+)/g, (match, p1) => `¥${p1 * 7}`); // '价格: ¥70, ¥140, ¥210'
Promise.any()
-
详细讲解:
- 作用:返回第一个成功的 Promise
- 语法:
Promise.any(iterable)
- 特点:
- 只要有一个 Promise 成功就返回
- 所有 Promise 失败时抛出 AggregateError
- 与 Promise.race() 的区别:忽略失败的 Promise
-
代码示例:
javascript// 基础用法 const promises = [ fetch('https://api1.example.com'), fetch('https://api2.example.com'), fetch('https://api3.example.com') ]; try { const firstSuccess = await Promise.any(promises); console.log('第一个成功的响应:', firstSuccess); } catch (error) { console.log('所有请求都失败了:', error.errors); } // 实际应用:图片加载 async function loadImage(urls) { try { const firstImage = await Promise.any( urls.map(url => { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => resolve(img); img.onerror = reject; img.src = url; }); }) ); return firstImage; } catch { throw new Error('所有图片加载失败'); } }
ES2022(ES13)
类字段声明
-
详细讲解:
- 作用:直接在类中声明字段
- 特点:
- 支持公共和私有字段
- 支持静态字段
- 支持类字段初始化器
-
代码示例:
javascriptclass Counter { // 公共字段 count = 0; // 私有字段 #privateValue = 42; // 静态字段 static instances = 0; // 私有静态字段 static #lastCreated; constructor() { Counter.instances++; Counter.#lastCreated = new Date(); } increment() { this.count++; this.#privateValue++; } static getLastCreated() { return Counter.#lastCreated; } }
顶层 Await
-
详细讲解:
- 作用:在模块顶层使用 await
- 特点:
- 不需要包装在 async 函数中
- 模块加载会等待 await 完成
- 适用于动态依赖加载
-
代码示例:
javascript// config.js export const config = await fetch('/api/config').then(r => r.json()); // 动态导入 const strings = await import(`/i18n/${navigator.language}`); // 条件加载模块 const moduleA = await import( condition ? './moduleA.js' : './moduleB.js' );
ES2023(ES14)
Array 查找方法 findLast
和 findLastIndex
-
详细讲解:
- 作用:从后向前查找数组元素
- 语法:
arr.findLast(callback)
arr.findLastIndex(callback)
- 特点:
- 与 find/findIndex 相反的搜索顺序
- 返回最后一个匹配项
-
代码示例:
javascriptconst numbers = [1, 3, 5, 7, 3, 9]; // 查找最后一个小于 5 的数 numbers.findLast(n => n < 5); // 3 // 查找最后一个小于 5 的数的索引 numbers.findLastIndex(n => n < 5); // 4 // 实际应用 const transactions = [ { id: 1, status: 'pending' }, { id: 2, status: 'completed' }, { id: 3, status: 'pending' }, { id: 4, status: 'completed' } ]; // 查找最后一个待处理的交易 const lastPending = transactions.findLast( t => t.status === 'pending' );
ES2024(ES15)
Promise.withResolvers()
-
详细讲解:
- 作用:创建 Promise 及其控制器
- 语法:
Promise.withResolvers()
- 返回值:包含
promise
、resolve
和reject
的对象 - 特点:
- 简化 Promise 创建和控制
- 避免额外的闭包
- 更清晰的代码结构
-
代码示例:
javascript// 传统方式 let resolvePromise, rejectPromise; const promise = new Promise((resolve, reject) => { resolvePromise = resolve; rejectPromise = reject; }); // 使用 withResolvers const { promise, resolve, reject } = Promise.withResolvers(); // 实际应用 class Deferred { constructor() { const { promise, resolve, reject } = Promise.withResolvers(); this.promise = promise; this.resolve = resolve; this.reject = reject; } }
RegExp V 标志(Unicode Sets)
-
详细讲解:
- 作用:支持 Unicode 属性转义和集合操作
- 语法:使用
v
标志 - 特点:
- 支持 Unicode 属性类
- 支持集合运算(交集、并集、差集)
- 更好的 Unicode 支持
-
代码示例:
javascript// Unicode 属性类 const regex1 = /[\p{Letter}\p{Number}]/v; // 集合操作 const regex2 = /[\p{Letter}--\p{Script=Greek}]/v; // 字母但不是希腊字母 const regex3 = /[\p{Letter}&&\p{Script=Latin}]/v; // 拉丁字母 // 实际应用 function isValidIdentifier(str) { return /^[\p{Letter}_$][\p{Letter}\p{Number}_$]*$/v.test(str); }
ArrayBuffer.prototype.transfer()
-
详细讲解:
- 作用:转移 ArrayBuffer 的所有权
- 语法:
arrayBuffer.transfer()
- 特点:
- 零拷贝操作
- 原 ArrayBuffer 变为已分离状态
- 提高性能和内存效率
-
代码示例:
javascript// 基础用法 const buffer1 = new ArrayBuffer(1024); const buffer2 = buffer1.transfer(); // buffer1 现在已分离,不能再使用 // buffer2 包含原始数据 // 实际应用:数据传输 async function processLargeData(data) { const buffer = new ArrayBuffer(data.length); new Uint8Array(buffer).set(data); await worker.postMessage(buffer.transfer(), [buffer]); }
Atomics.waitAsync()
-
详细讲解:
- 作用:异步等待共享内存的变化
- 语法:
Atomics.waitAsync(typedArray, index, value[, timeout])
- 特点:
- 支持主线程使用
- 返回 Promise
- 可设置超时
-
代码示例:
s
javascript// 基础用法 const shared = new SharedArrayBuffer(4); const int32 = new Int32Array(shared); async function waitForChange() { const result = await Atosmics.waitAsync(int32, 0, 0).value; console.log('值已更改:', result); } // 实际应用:线程同步 class AsyncLock { #shared = new SharedArrayBuffer(4); #int32 = new Int32Array(this.#shared); async acquire(timeout = Infinity) { while (true) { if (Atomics.compareExchange(this.#int32, 0, 0, 1) === 0) { return true; } await Atomics.waitAsync(this.#int32, 0, 1, timeout).value; } } release() { Atomics.store(this.#int32, 0, 0); Atomics.notify(this.#int32, 0, 1); } }
Promise.withResolvers()
-
详细讲解:
- 作用:创建 Promise 及其控制器
- 语法:
Promise.withResolvers()
- 返回值:包含
promise
、resolve
和reject
的对象 - 特点:
- 简化 Promise 创建和控制
- 避免额外的闭包
- 更清晰的代码结构
-
代码示例:
javascript// 传统方式 let resolvePromise, rejectPromise; const promise = new Promise((resolve, reject) => { resolvePromise = resolve; rejectPromise = reject; }); // 使用 withResolvers const { promise, resolve, reject } = Promise.withResolvers(); // 实际应用:延迟执行 class Deferred { constructor() { const { promise, resolve, reject } = Promise.withResolvers(); this.promise = promise; this.resolve = resolve; this.reject = reject; } }
数组分组方法
-
详细讲解:
Object.groupBy()
:按条件对数组元素进行分组Map.groupBy()
:类似 Object.groupBy,但返回 Map- 特点:
- 保持原始数据类型
- 支持自定义分组逻辑
- 处理复杂数据结构
-
代码示例:
javascriptconst inventory = [ { name: "苹果", type: "水果", quantity: 5 }, { name: "香蕉", type: "水果", quantity: 3 }, { name: "胡萝卜", type: "蔬菜", quantity: 8 } ]; // 使用 Object.groupBy const groupedByType = Object.groupBy(inventory, item => item.type); // { // 水果: [ // { name: "苹果", type: "水果", quantity: 5 }, // { name: "香蕉", type: "水果", quantity: 3 } // ], // 蔬菜: [ // { name: "胡萝卜", type: "蔬菜", quantity: 8 } // ] // } // 使用 Map.groupBy const groupedByQuantity = Map.groupBy(inventory, item => item.quantity > 5 ? '库存充足' : '库存不足' );
WeakMap 改进
-
详细讲解:
- 新增
WeakMap.prototype.delete()
- 支持弱引用键值对
- 更好的内存管理
- 新增
-
代码示例:
javascript// 缓存管理 const cache = new WeakMap(); class ResourceManager { constructor() { this.resources = new WeakMap(); } getResource(key) { if (!this.resources.has(key)) { const resource = loadResource(key); this.resources.set(key, resource); } return this.resources.get(key); } releaseResource(key) { if (this.resources.delete(key)) { console.log('资源已释放'); } } }
错误原因(Error Cause)
- 详细讲解:
- 作用:提供更详细的错误信息
- 语法:在 Error 构造函数中添加 cause 属性
- 特点:
- 更好的错误追踪
- 支持错误链
- 便于调试
javascript
async function fetchUserData(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error('获取用户数据失败', {
cause: {
code: response.status,
url: response.url
}
});
}
return await response.json();
} catch (error) {
throw new Error('用户数据处理失败', { cause: error });
}
}
try {
await fetchUserData(123);
} catch (error) {
console.error('错误:', error.message);
console.error('原因:', error.cause);
}
最新提案与未来特性
装饰器(Decorators)
-
详细讲解:
- 作用:以声明方式修改或增强类和类成员
- 语法:使用
@
符号 - 类型:
- 类装饰器
- 方法装饰器
- 访问器装饰器
- 属性装饰器
- 特点:
- 可组合多个装饰器
- 执行顺序从下到上
-
代码示例:
javascript// 类装饰器 function logged(target) { return class extends target { constructor(...args) { console.log('Creating instance...'); super(...args); } }; } // 方法装饰器 function measure(target, key, descriptor) { const original = descriptor.value; descriptor.value = async function(...args) { const start = performance.now(); const result = await original.apply(this, args); const end = performance.now(); console.log(`${key} took ${end - start}ms`); return result; }; return descriptor; } @logged class Example { @measure async fetchData() { // ... 异步操作 } }
Record 和 Tuple 类型
-
详细讲解:
- 作用:提供不可变的数据结构
- 语法:
- Record:
#{}
- Tuple:
#[]
- Record:
- 特点:
- 深度不可变
- 结构相等性比较
- 可用作对象键
-
代码示例:
javascript// Record 示例 const point = #{ x: 10, y: 20 }; // point.x = 30; // 错误:不可修改 // Tuple 示例 const coords = #[1, 2, 3]; // coords[0] = 4; // 错误:不可修改 // 结构相等性 #{ x: 1, y: 2 } === #{ x: 1, y: 2 }; // true #[1, 2, 3] === #[1, 2, 3]; // true // 作为 Map 键 const map = new Map(); map.set(#{ id: 1 }, 'value');
管道操作符(Pipeline Operator)
-
详细讲解:
- 作用:简化函数调用链
- 语法:
|>
- 特点:
- 提高代码可读性
- 减少嵌套调用
- 支持异步操作
-
代码示例:
javascript// 基础用法 const double = n => n * 2; const increment = n => n + 1; const square = n => n ** 2; // 传统写法 square(increment(double(5))); // 121 // 管道操作符 5 |> double |> increment |> square; // 121 // 异步操作 async function processData(data) { return data |> await validate |> await transform |> await save; }
模式匹配(Pattern Matching)
-
详细讲解:
- 作用:结构化数据匹配和提取
- 语法:
match
表达式 - 特点:
- 支持解构赋值
- 支持守卫条件
- 支持默认分支
-
代码示例:
javascript// 基础匹配 const result = match (response) { when { status: 200, data } -> handleSuccess(data), when { status: 404 } -> handleNotFound(), when { status } if status >= 500 -> handleServerError(), default -> handleUnknown() }; // 数组匹配 const parse = match (tokens) { when [] -> null, when [{ type: 'number', value }] -> Number(value), when [{ type: 'string', value }] -> String(value), default -> throw new SyntaxError() };
总结与最佳实践
-
特性选择建议
- 考虑项目的浏览器兼容性要求
- 评估特性的性能影响
- 权衡代码可读性和维护性
-
工具链配置
javascript// babel.config.js 示例 module.exports = { presets: [ ['@babel/preset-env', { targets: { browsers: ['> 1%', 'last 2 versions'] }, useBuiltIns: 'usage', corejs: 3 }] ] };
-
性能优化提示
- 合理使用新特性,避免过度使用导致性能下降
- 考虑使用 tree-shaking 优化打包体积
- 按需引入 polyfill
-
调试技巧
- 使用 Chrome DevTools 的 Console 验证新特性
- 利用 Babel REPL 在线测试代码转换
- 使用 Node.js 的
--harmony
标志测试新特性
-
学习资源
- TC39 提案追踪:github.com/tc39/propos...
- MDN Web Docs:详细的 API 文档和示例
- ECMAScript 兼容性表:kangax.github.io/compat-tabl...