ECMAScript 2016-2024 新特性讲解

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. 获取上传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);
      }
    }
    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 text
      with 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 {
      @measure
      async 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. 学习资源

相关推荐
冴羽6 分钟前
SvelteKit 最新中文文档教程(1)—— 入门指南
前端·javascript·svelte
冬冬小圆帽26 分钟前
防抖和节流
开发语言·前端·javascript
周努力.30 分钟前
关于Vue/React中Diffing算法以及key的作用
javascript·vue.js·react.js
lydxwj31 分钟前
vue3自定义hooks遇到的问题
前端·javascript·vue.js
野生的程序媛1 小时前
重生之我在学Vue--第8天 Vue 3 UI 框架(Element Plus)
前端·vue.js·ui
轻松Ai享生活1 小时前
从代码粘贴侠到优雅的Coder? - 3个大神教我的脱坑不传之秘
人工智能·面试·程序员
前端付杰2 小时前
从Vue源码解锁位运算符:提升代码效率的秘诀
前端·javascript·vue.js
然后就去远行吧2 小时前
小程序 wxml 语法 —— 37 setData() - 修改对象类型数据
android·前端·小程序
用户3203578360022 小时前
程序员鸡翅-Java微服务从0到1带你做社区项目实战
javascript
用户3203578360022 小时前
高薪运维必备Prometheus监控系统企业级实战(已完结)
前端