Javascript 2016-2024 新特性讲解

devtools/2025/3/13 13:19:52/

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 表示从末尾开始
      • undefinednull 也能正确处理
  • 代码示例:

    javascript">const 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个元素开始查找
    
  • 应用场景:

    1. 权限验证
    javascript">const userPermissions = ['read', 'write', 'delete'];function canUserDelete() {return userPermissions.includes('delete');
    }
    
    1. 表单验证
    javascript">const validTypes = ['jpg', 'png', 'gif'];function isValidFileType(filename) {const extension = filename.split('.').pop().toLowerCase();return validTypes.includes(extension);
    }
    
    1. 条件判断优化
    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))
    
  • 应用场景:

    1. 数学计算
    javascript">// 计算圆面积
    const getCircleArea = radius => Math.PI * (radius ** 2);// 计算复利
    const compound = (principal, rate, years) => {return principal * ((1 + rate) ** years);
    };
    
    1. 3D变换
    javascript">// 3D缩放变换
    const scale3d = (x, y, z, factor) => ({x: x * (factor ** 1),y: y * (factor ** 1),z: z * (factor ** 1)
    });
    
    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)
    • 特点:
      • 只返回对象自身的可枚举属性
      • 属性顺序遵循:
        1. 数字键(按升序)
        2. 字符串键(按添加顺序)
        3. 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']
    // ]
    
  • 应用场景:

    1. 对象转换
    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);
    });
    
    1. 数据处理
    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;}, {});
    
    1. 数据可视化
    javascript">// 转换为图表数据格式
    const data = {'Q1': 1000,'Q2': 1500,'Q3': 1200,'Q4': 2000
    };const chartData = {labels: Object.keys(data),values: Object.values(data)
    };
    

async/await

  • 详细讲解:

    • 作用:以同步的方式编写异步代码
    • 核心概念:
      • async:声明异步函数,总是返回 Promise
      • await:暂停执行,等待 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));
    }
    
  • 应用场景:

    1. API 请求处理
    javascript">async function uploadFile(file) {try {// 1. 获取上传URLconst { 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);}
    }
    
    1. 数据库操作
    javascript">async 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();}
    }
    
    1. 资源加载
    javascript">async 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']
    
  • 应用场景:

  1. 数字格式化
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"
  1. 表格对齐
javascript">const data = ['a', 'ab', 'abc'];
const aligned = data.map(s => s.padEnd(5, ' '));
// ["a    ", "ab   ", "abc  "]
  1. 掩码处理
javascript">// 信用卡号掩码
const maskCreditCard = num => num.slice(-4).padStart(num.length, '*');maskCreditCard('1234567890123456'); // "************3456"

Object.getOwnPropertyDescriptors()

  • 详细讲解:

    • 作用:获取对象所有自有属性的描述符
    • 语法:Object.getOwnPropertyDescriptors(obj)
    • 特点:
      • 返回包含所有属性描述符的对象
      • 包括不可枚举属性
      • 包括符号属性
      • 描述符包含:value, writable, enumerable, configurable, get, set
  • 代码示例:

    javascript">const 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
    //   }
    // }
    
  • 应用场景:

    1. 克隆对象(包括 getter/setter)
    javascript">const source = {set name(value) {this._name = value;},get name() {return this._name;}
    };const clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(source)
    );
    
    1. 合并对象
    javascript">const 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 默认为 1
      • arr.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]
    
  • 应用场景:

    1. 数据处理
    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);
    
    1. 文本处理
    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' }
    
  • 应用场景:

    1. 数据转换
    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 }
    
    1. 表单处理
    javascript">// FormData 转对象
    const form = document.querySelector('form');
    const formData = new FormData(form);
    const data = Object.fromEntries(formData);
    
    1. 配置处理
    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() 的别名
    • 特点:
      • 不修改原字符串
      • 移除所有空白字符(空格、制表符、换行符等)
  • 代码示例:

    javascript">const text = '   Hello World   ';text.trimStart();  // 'Hello World   '
    text.trimEnd();    // '   Hello World'// 实际应用
    function normalizeInput(input) {return input.trimStart().toLowerCase();
    }// 处理多行文本
    const multiline = `Some textwith spaces`;
    multiline.trimStart().trimEnd();  // 'Some text\n    with spaces'

Symbol.prototype.description

  • 详细讲解:

    • 作用:获取 Symbol 的描述字符串
    • 语法: symbol.description
    • 特点:
      • 只读属性
      • 返回创建 Symbol 时传入的描述
      • 如果没有描述则返回 undefined
  • 代码示例:

    javascript">const 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()

  • 详细讲解:

    • 作用:返回函数的源代码字符串
    • 改进:现在保留了空格和注释
    • 特点:
      • 包含完整的函数声明
      • 保持原始格式
      • 适用于调试和文档生成
  • 代码示例:

    javascript">function /* 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 失败而中断
      • 适合处理多个独立的异步操作
  • 代码示例:

    javascript">const 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
    
  • 应用场景:

    1. API 响应处理
    javascript">async 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};
    }
    
    1. 配置对象处理
    javascript">function 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)

类字段声明

  • 详细讲解:

    • 作用:直接在类中声明字段
    • 特点:
      • 支持公共和私有字段
      • 支持静态字段
      • 支持类字段初始化器
  • 代码示例:

    javascript">class 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 查找方法 findLastfindLastIndex

  • 详细讲解:

    • 作用:从后向前查找数组元素
    • 语法:
      • arr.findLast(callback)
      • arr.findLastIndex(callback)
    • 特点:
      • 与 find/findIndex 相反的搜索顺序
      • 返回最后一个匹配项
  • 代码示例:

    javascript">const 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()
    • 返回值:包含 promiseresolvereject 的对象
    • 特点:
      • 简化 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()
    • 返回值:包含 promiseresolvereject 的对象
    • 特点:
      • 简化 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
    • 特点:
      • 保持原始数据类型
      • 支持自定义分组逻辑
      • 处理复杂数据结构
  • 代码示例:

    javascript">const 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 {@measureasync fetchData() {// ... 异步操作}
    }
    

Record 和 Tuple 类型

  • 详细讲解:

    • 作用:提供不可变的数据结构
    • 语法:
      • Record: #{}
      • Tuple: #[]
    • 特点:
      • 深度不可变
      • 结构相等性比较
      • 可用作对象键
  • 代码示例:

    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()
    };
    

总结与最佳实践

  1. 特性选择建议

    • 考虑项目的浏览器兼容性要求
    • 评估特性的性能影响
    • 权衡代码可读性和维护性
  2. 工具链配置

    javascript">// babel.config.js 示例
    module.exports = {presets: [['@babel/preset-env', {targets: {browsers: ['> 1%', 'last 2 versions']},useBuiltIns: 'usage',corejs: 3}]]
    };
    
  3. 性能优化提示

    • 合理使用新特性,避免过度使用导致性能下降
    • 考虑使用 tree-shaking 优化打包体积
    • 按需引入 polyfill
  4. 调试技巧

    • 使用 Chrome DevTools 的 Console 验证新特性
    • 利用 Babel REPL 在线测试代码转换
    • 使用 Node.js 的 --harmony 标志测试新特性
  5. 学习资源

    • TC39 提案追踪:https://github.com/tc39/proposals
    • MDN Web Docs:详细的 API 文档和示例
    • ECMAScript 兼容性表:https://kangax.github.io/compat-table/es6/

http://www.ppmy.cn/devtools/166778.html

相关文章

算法题(94):除2!

审题&#xff1a; 本题需要我们对n个数据中的偶数数据进行不大于k次除2操作&#xff0c;使得n个数据的总和最小 思路&#xff1a; 方法一&#xff1a;贪心与优先级队列&#xff08;大堆&#xff09; 贪心策略&#xff1a;我们每次都对目前最大的偶数进行除2的操作 策略证明&…

AI科技公司招聘一位后端开发工程师

招聘岗位&#xff1a;后端开发工程师&#xff08;兼运维&#xff09; 公司名称&#xff1a;深圳市格子科技有限公司 公司介绍&#xff1a;深圳市格子科技有限公司作为AI应用创新先锋&#xff0c;构建起以AI工具研发为核心、短剧平台运营为延伸的多业务发展模式。公司自主研发A…

linux在 Ubuntu 系统中设置服务器时间

在 Ubuntu 系统中设置服务器时间通常涉及以下步骤&#xff0c;涵盖自动同步和手动配置两种方式。以下是详细操作指南&#xff1a; 一、检查当前时间状态 timedatectl status输出示例&#xff1a;Local time: Wed 2023-10-18 15:30:00 UTC Universal time: Wed 2023-10-18 15:3…

51单片机Proteus仿真速成教程——P1-软件与配置+Proteus绘制51单片机最小系统+新建程序模版

前言&#xff1a;本文主要围绕 51 单片机最小系统的绘制及程序模板创建展开。首先介绍了使用 Proteus 绘制 51 单片机最小系统的详细步骤&#xff0c;包括软件安装获取途径、工程创建、器件添加&#xff08;如单片机 AT89C51、晶振、电容、电阻、按键等&#xff09;、外围电路&…

【蓝桥杯速成】| 1.暴力解题

1高频考点与暴力解题_哔哩哔哩_bilibili 感谢up主分享&#xff0c;以下内容是学习笔记&#xff0c;以c为主&#xff0c;部分python 题目一&#xff1a;维纳的年龄 题目内容 美国数学家维纳(N.Wiener)智力早熟&#xff0c; 11岁就上了大学。他曾在1935~1936年应邀来中国清华大…

反射、 Class类、JVM的类加载机制、Class的常用方法

DAY11.1 Java核心基础 反射 重点和难点&#xff0c;应用面很广 大部分库和框架都需要用到反射机制&#xff0c;它是动态语言的关键&#xff0c;但是概念抽象不好理解 反射&#xff1a;通过实例化类映射到类&#xff0c;从而获取类的信息 概括说就是&#xff1a;常规情况是…

scrcpy pc机远程 无线 控制android app 查看调试log

背景&#xff1a; 公司的安卓机&#xff0c;是那种大屏幕的连接usb外设的。不好挪动&#xff0c;占地方&#xff0c;不能直接连接pc机上的android stduio来调试。 所以从网上找了一个python adb.exe控制器&#xff0c;可以局域网内远程控制开发的app,并在android stduio上看…

2024年广州市智能网联汽车创新实践年度报告

政策法规方面&#xff0c;积极推进《广州市智能网联汽车创新发展条例》的制定和发布&#xff0c;不断完善法规标准体系&#xff0c;为产业创新发展营造良好政策环境&#xff1b;技术创新方面&#xff0c;企业加大研发投入&#xff0c;在自动驾驶算法、车联网安全等关键领域取得…