轩辕李的博客 轩辕李的博客
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • HTML&CSS
  • JavaScript
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

轩辕李

勇猛精进,星辰大海
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • HTML&CSS
  • JavaScript
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaScript

    • 关于this关键字的魔幻现实
    • JavaScript历代版本新特性
      • 前言
      • JavaScript版本发布流程
        • 关键特点
        • 全流程步骤
        • 1. 提案提交(Stage 0: Strawperson)
        • 2. 提案阶段(Stage 1: Proposal)
        • 3. 草案阶段(Stage 2: Draft)
        • 4. 候选阶段(Stage 3: Candidate)
        • 5. 完成阶段(Stage 4: Finished)
        • 6. 正式发布
        • 7. 后续更新
        • 治理模型
      • ES1(1997)
        • 核心特性
      • ES2(1998)
        • 主要改进
      • ES3(1999)
        • 核心特性
      • ES4(废弃)
      • ES5(2009)
        • 革命性特性
        • 对象增强
        • 数组增强
        • 其他改进
      • ES5.1(2011)
        • 主要改进
      • ES6 / ES2015(2015)
        • 革命性特性
        • 1. let 和 const
        • 2. 箭头函数
        • 3. 类(Class)
        • 4. 模块系统
        • 5. 模板字符串
        • 6. 解构赋值
        • 7. 默认参数、剩余参数、展开运算符
        • 8. Promise
        • 9. Symbol
        • 10. 迭代器和生成器
        • 数据结构
        • 其他重要特性
      • ES2016(ES7)
        • 核心特性
      • ES2017(ES8)
        • 革命性特性
        • 对象增强
        • 字符串增强
        • 其他特性
      • ES2018(ES9)
        • 核心特性
        • 对象增强
        • 正则表达式增强
      • ES2019(ES10)
        • 核心特性
        • 其他特性
      • ES2020(ES11)
        • 核心特性
        • 模块增强
        • 其他特性
      • ES2021(ES12)
        • 核心特性
        • 其他特性
      • ES2022(ES13)
        • 核心特性
        • 其他特性
      • ES2023(ES14)
        • 核心特性
        • 其他特性
      • ES2024(ES15)
        • 核心特性
        • 其他特性
      • ES2025(ES16)
        • 核心特性
        • 1. 迭代器辅助方法(Iterator Helpers)
        • 2. Set 新方法
        • 3. Promise.try()
        • 4. RegExp.escape()
        • 5. 导入属性(Import Attributes)
        • 6. 正则表达式模式修饰符
        • 7. 重复命名捕获组
        • 8. Float16Array(16位浮点数)
        • 正则表达式 v 标志增强
      • 总结
      • 参考资料
    • JavaScript极简入门
    • JavaScript高级特性详解
  • TypeScript

  • Node.js

  • Vue.js

  • 工程化

  • 浏览器与Web API

  • 前端
  • JavaScript
轩辕李
2025-02-06
目录

JavaScript历代版本新特性

# 前言

JavaScript 诞生于1995年,由 Brendan Eich 在 Netscape 公司仅用10天时间创建。从最初简单的网页脚本语言,发展到今天成为全栈开发的主力语言之一。

JavaScript 的标准化工作由 ECMA International 的 TC39 技术委员会负责,标准名称为 ECMAScript(ES)。从2015年 ES6 发布开始,JavaScript 进入了快速迭代期,每年发布一个新版本,语言特性不断丰富和完善。

本文系统梳理了 JavaScript/ECMAScript 各个版本的核心特性和发展历程。对于每个版本,我们会重点介绍那些影响深远的特性和重要的语法改进。

阅读建议:

  • 标记为 粗体 的特性通常是该版本最重要的改进
  • ES6(ES2015)是一个里程碑版本,建议重点关注
  • 代码示例可以帮助你快速理解新特性的用法

# JavaScript版本发布流程

JavaScript 由 TC39(ECMA International 的第39号技术委员会)管理,通过社区驱动的方式制定标准,采用提案驱动的发布模型(Proposal-Based Release Model)。

# 关键特点

  • 自 ES2015 起,每年发布一个新版本(通常在6月)
  • 版本命名采用年份(如 ES2015、ES2016、ES2017……)
  • 开发基于提案(Proposal)系统

# 全流程步骤

# 1. 提案提交(Stage 0: Strawperson)

  • 任何 TC39 成员或贡献者可以提交想法
  • 只需在 TC39 会议上展示即可进入 Stage 0
  • 此阶段的提案可能会被完全改变或废弃

# 2. 提案阶段(Stage 1: Proposal)

  • 明确问题和解决方案
  • 提供示例和高层API描述
  • 识别潜在的实现挑战

# 3. 草案阶段(Stage 2: Draft)

  • 提供精确的语法和语义描述
  • 预期该特性最终会被纳入标准
  • 可能会有实验性的实现

# 4. 候选阶段(Stage 3: Candidate)

  • 规范文本完成,等待实现和用户反馈
  • 至少需要两个符合规范的实现
  • 只有在实现过程中发现关键问题才会修改

# 5. 完成阶段(Stage 4: Finished)

  • 通过 Test262 验收测试
  • 至少两个通过测试的实现
  • 编辑签字确认
  • 将在下一个年度版本中发布

# 6. 正式发布

  • 每年6月发布新版本
  • 只包含已达到 Stage 4 的提案
  • 版本以年份命名(如 ES2024)

# 7. 后续更新

  • 规范错误修正随时进行
  • 不影响已发布版本的稳定性

# 治理模型

  • 代表组织:各大浏览器厂商(Google、Mozilla、Apple、Microsoft)、科技公司(Meta、Netflix)、学术机构等
  • 治理模型:共识驱动(需要委员会达成共识)

# ES1(1997)

1997年6月发布,是 JavaScript 的第一个正式标准版本。

# 核心特性

  • 基础语法:变量声明、数据类型、运算符
  • 控制结构:if/else、for、while、switch
  • 函数:函数声明、函数表达式
  • 对象:基于原型的对象系统
  • 数组:基本数组操作
  • 字符串:字符串处理方法

# ES2(1998)

1998年6月发布,主要是编辑性修改以符合 ISO/IEC 16262 国际标准。

# 主要改进

  • 规范文本的格式化和编辑修正
  • 与 ISO/IEC 16262 标准保持一致

# ES3(1999)

1999年12月发布,是 JavaScript 成熟的重要版本。

# 核心特性

  • 正则表达式:内置正则表达式支持
  • 异常处理:try/catch/finally 语句
  • 更好的字符串处理:substring、concat、match、replace、split 等方法
  • 更多数组方法:push、pop、shift、unshift、splice 等
  • 格式化输出:toFixed、toExponential、toPrecision

示例:

// 正则表达式
var pattern = /hello/i;
var text = "Hello World";
console.log(pattern.test(text)); // true

// 异常处理
try {
    throw new Error("自定义错误");
} catch (e) {
    console.log(e.message);
} finally {
    console.log("总是执行");
}

// 数组方法
var arr = [1, 2, 3];
arr.push(4);
console.log(arr); // [1, 2, 3, 4]

# ES4(废弃)

ES4 计划引入大量新特性,包括类、模块、类型注解等,但由于提案过于激进,最终被废弃。部分特性后来在 ES6 中实现。

# ES5(2009)

2009年12月发布,是 ES3 之后的首个重大更新,间隔了10年。

# 革命性特性

  • 严格模式(Strict Mode):"use strict" 启用更严格的语法检查

    "use strict";
    x = 3.14; // 报错:未声明变量
    
  • JSON 支持:原生 JSON.parse() 和 JSON.stringify()

    var obj = {name: "张三", age: 25};
    var json = JSON.stringify(obj);
    var parsed = JSON.parse(json);
    

# 对象增强

  • 访问器属性:Object.defineProperty()、Object.defineProperties()

    var person = {};
    Object.defineProperty(person, "name", {
        get: function() { return this._name; },
        set: function(value) { this._name = value.toUpperCase(); }
    });
    
  • 对象方法:

    • Object.create():基于原型创建对象
    • Object.keys():获取对象的键
    • Object.seal():密封对象
    • Object.freeze():冻结对象
    • Object.preventExtensions():防止扩展

# 数组增强

  • 数组迭代方法:

    var arr = [1, 2, 3, 4, 5];
    
    // forEach
    arr.forEach(function(item) { console.log(item); });
    
    // map
    var doubled = arr.map(function(item) { return item * 2; });
    
    // filter
    var evens = arr.filter(function(item) { return item % 2 === 0; });
    
    // reduce
    var sum = arr.reduce(function(acc, item) { return acc + item; }, 0);
    
    // some 和 every
    var hasEven = arr.some(function(item) { return item % 2 === 0; });
    var allPositive = arr.every(function(item) { return item > 0; });
    
  • 数组方法:Array.isArray()、indexOf()、lastIndexOf()

# 其他改进

  • Function.prototype.bind():绑定函数的 this 值

    var module = {
        x: 42,
        getX: function() { return this.x; }
    };
    var boundGetX = module.getX.bind(module);
    console.log(boundGetX()); // 42
    
  • String.prototype.trim():去除字符串首尾空白

# ES5.1(2011)

2011年6月发布,是 ES5 的维护版本。

# 主要改进

  • 修正规范中的歧义和错误
  • 与 ISO/IEC 16262:2011 保持一致

# ES6 / ES2015(2015)

2015年6月发布,是 JavaScript 历史上最重要的版本,引入了大量现代化特性。

# 革命性特性

# 1. let 和 const

  • 块级作用域:解决 var 的变量提升问题
    // var 的问题
    for (var i = 0; i < 3; i++) {
        setTimeout(function() { console.log(i); }, 100);
    }
    // 输出:3 3 3
    
    // let 解决
    for (let i = 0; i < 3; i++) {
        setTimeout(function() { console.log(i); }, 100);
    }
    // 输出:0 1 2
    
    // const 常量
    const PI = 3.14159;
    // PI = 3; // 报错
    

# 2. 箭头函数

  • 简洁语法:更简洁的函数表达式
  • 词法 this:不绑定自己的 this
    // 传统函数
    var add = function(a, b) {
        return a + b;
    };
    
    // 箭头函数
    const add = (a, b) => a + b;
    
    // this 绑定
    function Timer() {
        this.seconds = 0;
        setInterval(() => {
            this.seconds++; // this 指向 Timer 实例
        }, 1000);
    }
    

# 3. 类(Class)

  • 语法糖:更清晰的面向对象编程
    class Person {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        
        sayHello() {
            console.log(`你好,我是${this.name}`);
        }
        
        static species() {
            return "智人";
        }
    }
    
    class Student extends Person {
        constructor(name, age, grade) {
            super(name, age);
            this.grade = grade;
        }
        
        study() {
            console.log(`${this.name}正在学习`);
        }
    }
    

# 4. 模块系统

  • ES6 模块:原生模块支持
    // math.js
    export const PI = 3.14159;
    export function add(a, b) {
        return a + b;
    }
    export default class Calculator {
        // ...
    }
    
    // main.js
    import Calculator, { PI, add } from './math.js';
    import * as math from './math.js';
    

# 5. 模板字符串

  • 字符串插值:更方便的字符串拼接
    const name = "张三";
    const age = 25;
    
    // 传统方式
    var msg = "我是" + name + ",今年" + age + "岁";
    
    // 模板字符串
    const msg = `我是${name},今年${age}岁`;
    
    // 多行字符串
    const html = `
        <div>
            <h1>${name}</h1>
            <p>年龄:${age}</p>
        </div>
    `;
    

# 6. 解构赋值

  • 便捷提取:从数组或对象中提取值
    // 数组解构
    const [a, b, c] = [1, 2, 3];
    const [first, ...rest] = [1, 2, 3, 4, 5];
    
    // 对象解构
    const {name, age} = {name: "张三", age: 25};
    const {name: userName, age: userAge} = {name: "张三", age: 25};
    
    // 函数参数解构
    function greet({name, age}) {
        console.log(`${name}今年${age}岁`);
    }
    greet({name: "张三", age: 25});
    

# 7. 默认参数、剩余参数、展开运算符

// 默认参数
function greet(name = "访客") {
    console.log(`你好,${name}`);
}

// 剩余参数
function sum(...numbers) {
    return numbers.reduce((acc, num) => acc + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10

// 展开运算符
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5, 6];

const obj1 = {a: 1, b: 2};
const obj2 = {...obj1, c: 3};

# 8. Promise

  • 异步编程:更优雅的异步处理
    // 创建 Promise
    const promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("成功");
            // reject(new Error("失败"));
        }, 1000);
    });
    
    // 使用 Promise
    promise
        .then(result => console.log(result))
        .catch(error => console.error(error))
        .finally(() => console.log("完成"));
    
    // Promise 链式调用
    fetch('/api/user')
        .then(response => response.json())
        .then(data => console.log(data))
        .catch(error => console.error(error));
    

# 9. Symbol

  • 唯一标识符:创建唯一的属性键
    const sym1 = Symbol('描述');
    const sym2 = Symbol('描述');
    console.log(sym1 === sym2); // false
    
    // 作为对象属性
    const obj = {
        [Symbol('id')]: 123
    };
    

# 10. 迭代器和生成器

// 迭代器
const obj = {
    data: [1, 2, 3],
    [Symbol.iterator]() {
        let index = 0;
        return {
            next: () => {
                if (index < this.data.length) {
                    return {value: this.data[index++], done: false};
                }
                return {done: true};
            }
        };
    }
};

// 生成器
function* fibonacci() {
    let [prev, curr] = [0, 1];
    while (true) {
        yield curr;
        [prev, curr] = [curr, prev + curr];
    }
}

const fib = fibonacci();
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2

# 数据结构

  • Set:值的集合,值唯一

    const set = new Set([1, 2, 3, 3, 4]);
    console.log(set.size); // 4
    set.add(5);
    set.has(3); // true
    set.delete(2);
    
  • Map:键值对集合,键可以是任意类型

    const map = new Map();
    map.set('name', '张三');
    map.set(123, '数字键');
    map.get('name'); // "张三"
    map.size; // 2
    
  • WeakSet 和 WeakMap:弱引用版本,用于防止内存泄漏

# 其他重要特性

  • Proxy 和 Reflect:元编程支持

    const handler = {
        get(target, prop) {
            console.log(`访问属性: ${prop}`);
            return target[prop];
        }
    };
    
    const proxy = new Proxy({name: "张三"}, handler);
    console.log(proxy.name); // 访问属性: name \n 张三
    
  • 二进制和八进制字面量:0b1010、0o755

  • Number 扩展:Number.isNaN()、Number.isFinite()、Number.isInteger()

  • Math 扩展:Math.trunc()、Math.sign()、Math.cbrt() 等

  • Array 扩展:Array.from()、Array.of()、find()、findIndex()、fill()、copyWithin()

  • Object 扩展:Object.assign()、Object.is()

  • String 扩展:startsWith()、endsWith()、includes()、repeat()

# ES2016(ES7)

2016年6月发布,包含2个新特性。

# 核心特性

  • 数组 includes 方法:检查数组是否包含某个值

    const arr = [1, 2, 3, NaN];
    arr.includes(2); // true
    arr.includes(NaN); // true(indexOf 无法识别 NaN)
    
  • 指数运算符:** 运算符

    console.log(2 ** 3); // 8
    console.log(Math.pow(2, 3)); // 8(旧方法)
    

# ES2017(ES8)

2017年6月发布,引入了异步编程的重大改进。

# 革命性特性

  • async/await:基于 Promise 的异步语法糖
    // Promise 方式
    function fetchData() {
        return fetch('/api/data')
            .then(response => response.json())
            .then(data => console.log(data))
            .catch(error => console.error(error));
    }
    
    // async/await 方式
    async function fetchData() {
        try {
            const response = await fetch('/api/data');
            const data = await response.json();
            console.log(data);
        } catch (error) {
            console.error(error);
        }
    }
    
    // 并行执行
    async function parallel() {
        const [result1, result2] = await Promise.all([
            fetch('/api/1'),
            fetch('/api/2')
        ]);
    }
    

# 对象增强

  • Object.values():返回对象的值数组

  • Object.entries():返回对象的键值对数组

    const obj = {name: "张三", age: 25};
    
    Object.values(obj); // ["张三", 25]
    Object.entries(obj); // [["name", "张三"], ["age", 25]]
    
    // 遍历对象
    for (let [key, value] of Object.entries(obj)) {
        console.log(`${key}: ${value}`);
    }
    
  • Object.getOwnPropertyDescriptors():获取对象所有属性描述符

# 字符串增强

  • 字符串填充:padStart() 和 padEnd()
    '5'.padStart(3, '0'); // "005"
    'abc'.padEnd(5, '*'); // "abc**"
    

# 其他特性

  • 函数参数尾逗号:允许函数参数列表和调用时的尾逗号

    function foo(
        a,
        b,
        c,
    ) {
        // ...
    }
    
  • 共享内存和原子操作:SharedArrayBuffer 和 Atomics

# ES2018(ES9)

2018年6月发布,进一步完善异步和对象操作。

# 核心特性

  • 异步迭代:for await...of

    async function* asyncGenerator() {
        yield await Promise.resolve(1);
        yield await Promise.resolve(2);
        yield await Promise.resolve(3);
    }
    
    (async () => {
        for await (const num of asyncGenerator()) {
            console.log(num);
        }
    })();
    
  • Promise.finally():无论成功或失败都执行

    fetch('/api/data')
        .then(response => response.json())
        .catch(error => console.error(error))
        .finally(() => console.log('请求完成'));
    

# 对象增强

  • 对象展开运算符:对象的剩余/展开属性
    const {a, b, ...rest} = {a: 1, b: 2, c: 3, d: 4};
    console.log(rest); // {c: 3, d: 4}
    
    const obj = {a: 1, b: 2};
    const newObj = {...obj, c: 3}; // {a: 1, b: 2, c: 3}
    

# 正则表达式增强

  • 命名捕获组:

    const pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
    const match = pattern.exec('2024-01-15');
    console.log(match.groups.year); // "2024"
    
  • 反向断言:(?<=...) 和 (?<!...)

  • dotAll 模式:s 标志让 . 匹配换行符

  • Unicode 属性转义:\p{...} 和 \P{...}

# ES2019(ES10)

2019年6月发布,带来了多个实用特性。

# 核心特性

  • Array.flat() 和 Array.flatMap():数组扁平化

    const arr = [1, 2, [3, 4, [5, 6]]];
    arr.flat(); // [1, 2, 3, 4, [5, 6]]
    arr.flat(2); // [1, 2, 3, 4, 5, 6]
    arr.flat(Infinity); // 完全扁平化
    
    const arr2 = [1, 2, 3];
    arr2.flatMap(x => [x, x * 2]); // [1, 2, 2, 4, 3, 6]
    
  • Object.fromEntries():将键值对列表转换为对象

    const entries = [['name', '张三'], ['age', 25]];
    const obj = Object.fromEntries(entries);
    // {name: "张三", age: 25}
    
    // 对象转换
    const obj2 = {a: 1, b: 2, c: 3};
    const filtered = Object.fromEntries(
        Object.entries(obj2).filter(([key, value]) => value > 1)
    );
    
  • String.trimStart() 和 String.trimEnd():去除首尾空白

    '  hello  '.trimStart(); // "hello  "
    '  hello  '.trimEnd(); // "  hello"
    

# 其他特性

  • 可选的 catch 绑定:catch 可以省略参数

    try {
        // ...
    } catch {
        console.log('发生错误');
    }
    
  • Symbol.description:获取 Symbol 的描述

    const sym = Symbol('描述');
    console.log(sym.description); // "描述"
    
  • Function.toString() 改进:返回精确的源代码文本

  • JSON 超集:允许 U+2028 和 U+2029 字符

# ES2020(ES11)

2020年6月发布,引入了多个重要特性。

# 核心特性

  • 可选链操作符(Optional Chaining):?.

    const user = {
        name: '张三',
        address: {
            city: '北京'
        }
    };
    
    // 传统方式
    const city = user && user.address && user.address.city;
    
    // 可选链
    const city = user?.address?.city;
    const zipCode = user?.address?.zipCode; // undefined
    
    // 函数调用
    obj.method?.();
    
    // 数组访问
    arr?.[0];
    
  • 空值合并运算符(Nullish Coalescing):??

    // || 的问题
    const count = 0;
    const result = count || 10; // 10(不符合预期)
    
    // ?? 只判断 null 和 undefined
    const result = count ?? 10; // 0
    const result = null ?? 10; // 10
    const result = undefined ?? 10; // 10
    
  • BigInt:任意精度整数

    const bigInt = 9007199254740991n;
    const alsoHuge = BigInt(9007199254740991);
    
    const result = bigInt + 1n; // 9007199254740992n
    
    // 不能与 Number 混用
    // bigInt + 1; // 报错
    
  • Promise.allSettled():等待所有 Promise 完成(无论成功或失败)

    const promises = [
        Promise.resolve(1),
        Promise.reject('错误'),
        Promise.resolve(3)
    ];
    
    Promise.allSettled(promises).then(results => {
        results.forEach(result => {
            if (result.status === 'fulfilled') {
                console.log('成功:', result.value);
            } else {
                console.log('失败:', result.reason);
            }
        });
    });
    

# 模块增强

  • 动态 import():运行时动态加载模块

    // 条件加载
    if (condition) {
        import('./module.js').then(module => {
            module.doSomething();
        });
    }
    
    // async/await
    async function loadModule() {
        const module = await import('./module.js');
        module.doSomething();
    }
    
  • import.meta:模块元数据

    console.log(import.meta.url); // 模块的 URL
    

# 其他特性

  • globalThis:统一的全局对象

    // 浏览器: window
    // Node.js: global
    // Web Workers: self
    
    // 统一访问
    globalThis.setTimeout(...);
    
  • String.matchAll():返回所有匹配的迭代器

    const str = 'test1test2test3';
    const regex = /test(\d)/g;
    
    for (const match of str.matchAll(regex)) {
        console.log(match[0], match[1]);
    }
    
  • for-in 顺序标准化:规范化 for-in 的遍历顺序

# ES2021(ES12)

2021年6月发布,带来了多个实用的新特性。

# 核心特性

  • 逻辑赋值运算符:&&=、||=、??=

    // 逻辑或赋值
    let x = 0;
    x ||= 10; // x = x || 10
    console.log(x); // 10
    
    // 逻辑与赋值
    let y = 5;
    y &&= 10; // y = y && 10
    console.log(y); // 10
    
    // 空值赋值
    let z = null;
    z ??= 10; // z = z ?? 10
    console.log(z); // 10
    
  • 数字分隔符:提高数字可读性

    const billion = 1_000_000_000;
    const bytes = 0xFF_FF_FF_FF;
    const pi = 3.14_15_92_65;
    
  • String.replaceAll():替换所有匹配项

    const str = 'hello world hello';
    
    // 传统方式
    str.replace(/hello/g, 'hi'); // "hi world hi"
    
    // replaceAll
    str.replaceAll('hello', 'hi'); // "hi world hi"
    
  • Promise.any():任意一个 Promise 成功即返回

    const promises = [
        Promise.reject('错误1'),
        Promise.resolve('成功'),
        Promise.reject('错误2')
    ];
    
    Promise.any(promises)
        .then(result => console.log(result)) // "成功"
        .catch(error => console.error(error));
    
    // 如果全部失败,返回 AggregateError
    

# 其他特性

  • WeakRef:弱引用对象

    const obj = {name: '张三'};
    const weakRef = new WeakRef(obj);
    
    // 获取引用
    const deref = weakRef.deref();
    if (deref) {
        console.log(deref.name);
    }
    
  • FinalizationRegistry:对象被垃圾回收时的回调

  • 逻辑赋值运算符的短路特性

# ES2022(ES13)

2022年6月发布,进一步完善了类和模块系统。

# 核心特性

  • 类字段声明:直接在类中声明字段

    class Person {
        name = '张三'; // 公共字段
        #age = 25; // 私有字段
        
        getAge() {
            return this.#age;
        }
    }
    
    const p = new Person();
    console.log(p.name); // "张三"
    // console.log(p.#age); // 报错:私有字段
    console.log(p.getAge()); // 25
    
  • 私有方法和访问器:

    class Counter {
        #count = 0;
        
        #increment() {
            this.#count++;
        }
        
        get #privateCount() {
            return this.#count;
        }
        
        increase() {
            this.#increment();
            return this.#privateCount;
        }
    }
    
  • 静态类字段和方法:

    class MathUtils {
        static PI = 3.14159;
        static #secret = 'private';
        
        static area(radius) {
            return this.PI * radius * radius;
        }
        
        static #privateMethod() {
            return this.#secret;
        }
    }
    
    console.log(MathUtils.PI); // 3.14159
    console.log(MathUtils.area(5)); // 78.53975
    
  • 类静态初始化块:

    class Database {
        static connection;
        
        static {
            // 静态初始化块
            this.connection = createConnection();
        }
    }
    

# 其他特性

  • 顶层 await:模块顶层可以直接使用 await

    // module.js
    const data = await fetch('/api/data');
    export default data;
    
  • Array.at():支持负索引的数组访问

    const arr = [1, 2, 3, 4, 5];
    arr.at(-1); // 5
    arr.at(-2); // 4
    arr.at(0); // 1
    
  • Object.hasOwn():更安全的属性检查

    const obj = {name: '张三'};
    
    // 传统方式(可能有问题)
    obj.hasOwnProperty('name'); // true
    
    // 新方式
    Object.hasOwn(obj, 'name'); // true
    
  • Error.cause:错误链

    try {
        // ...
    } catch (error) {
        throw new Error('上层错误', {cause: error});
    }
    
  • 正则表达式 d 标志:匹配索引

# ES2023(ES14)

2023年6月发布,带来了数组操作的重要改进。

# 核心特性

  • Array.findLast() 和 Array.findLastIndex():从后向前查找

    const arr = [1, 2, 3, 4, 5];
    
    arr.findLast(x => x > 2); // 5
    arr.findLastIndex(x => x > 2); // 4
    
  • Array.toReversed()、toSorted()、toSpliced():不可变数组方法

    const arr = [3, 1, 2];
    
    // 传统方式(会修改原数组)
    arr.sort(); // [1, 2, 3]
    
    // 新方式(返回新数组)
    const sorted = arr.toSorted(); // [1, 2, 3]
    console.log(arr); // [3, 1, 2](原数组不变)
    
    const reversed = arr.toReversed(); // [2, 1, 3]
    const spliced = arr.toSpliced(1, 1, 10); // [3, 10, 2]
    
  • Array.with():不可变的索引替换

    const arr = [1, 2, 3];
    const newArr = arr.with(1, 10); // [1, 10, 3]
    console.log(arr); // [1, 2, 3](原数组不变)
    

# 其他特性

  • WeakMap 支持 Symbol 作为键:

    const weakMap = new WeakMap();
    const sym = Symbol('key');
    const obj = {};
    weakMap.set(sym, obj);
    
  • #! Shebang 语法:支持 Unix Shebang

    #!/usr/bin/env node
    console.log('Hello');
    

# ES2024(ES15)

2024年6月发布,包含多个实用的新特性。

# 核心特性

  • Promise.withResolvers():更方便地创建 Promise

    // 传统方式
    let resolve, reject;
    const promise = new Promise((res, rej) => {
        resolve = res;
        reject = rej;
    });
    
    // 新方式
    const {promise, resolve, reject} = Promise.withResolvers();
    
    // 使用场景
    class Queue {
        #items = [];
        #resolvers = [];
        
        async dequeue() {
            if (this.#items.length > 0) {
                return this.#items.shift();
            }
            const {promise, resolve} = Promise.withResolvers();
            this.#resolvers.push(resolve);
            return promise;
        }
        
        enqueue(item) {
            if (this.#resolvers.length > 0) {
                const resolve = this.#resolvers.shift();
                resolve(item);
            } else {
                this.#items.push(item);
            }
        }
    }
    
  • Object.groupBy() 和 Map.groupBy():数组分组

    const people = [
        {name: '张三', age: 25},
        {name: '李四', age: 30},
        {name: '王五', age: 25}
    ];
    
    // 按年龄分组(返回对象)
    const grouped = Object.groupBy(people, person => person.age);
    // {
    //   25: [{name: '张三', age: 25}, {name: '王五', age: 25}],
    //   30: [{name: '李四', age: 30}]
    // }
    
    // 按年龄分组(返回 Map)
    const groupedMap = Map.groupBy(people, person => person.age);
    
  • 正则表达式 v 标志:Unicode 集合符号和属性

    // v 标志支持更强大的 Unicode 匹配
    const regex = /[\p{Script=Han}&&\p{Radical=亻}]/v;
    

# 其他特性

  • ArrayBuffer 转移:

    const buffer = new ArrayBuffer(8);
    const newBuffer = buffer.transfer(16); // 转移并调整大小
    
  • Atomics.waitAsync():异步等待共享内存

# ES2025(ES16)

2025年6月发布,包含8个重要的新特性。

# 核心特性

# 1. 迭代器辅助方法(Iterator Helpers)

为迭代器提供链式操作方法,使其使用更加便捷。

// 创建生成器
function* numberGenerator() {
    yield 1;
    yield 2;
    yield 3;
    yield 4;
    yield 5;
}

// map() - 转换每个值
const doubled = numberGenerator().map(x => x * 2);
console.log([...doubled]); // [2, 4, 6, 8, 10]

// filter() - 过滤元素
const evens = numberGenerator().filter(x => x % 2 === 0);
console.log([...evens]); // [2, 4]

// take() - 取前 N 个
const first3 = numberGenerator().take(3);
console.log([...first3]); // [1, 2, 3]

// drop() - 跳过前 N 个
const after2 = numberGenerator().drop(2);
console.log([...after2]); // [3, 4, 5]

// flatMap() - 扁平化映射
const flattened = numberGenerator().flatMap(x => [x, x * 10]);
console.log([...flattened]); // [1, 10, 2, 20, 3, 30, 4, 40, 5, 50]

// reduce() - 累积计算
const sum = numberGenerator().reduce((acc, x) => acc + x, 0);
console.log(sum); // 15

// 链式调用
const arr = ['a', '', 'b', '', 'c', '', 'd', '', 'e'];
const result = arr.values()
    .filter(x => x.length > 0)
    .drop(1)
    .take(3)
    .map(x => `=${x}=`)
    .toArray();
console.log(result); // ['=b=', '=c=', '=d=']

// 其他方法
numberGenerator().forEach(x => console.log(x)); // 遍历
numberGenerator().some(x => x % 2 === 0); // true - 是否存在偶数
numberGenerator().every(x => x > 0); // true - 是否全部为正数
numberGenerator().find(x => x > 3); // 4 - 查找第一个匹配

// Iterator.from() - 从可迭代对象创建
const iter = Iterator.from([1, 2, 3]);
console.log([...iter.map(x => x * 2)]); // [2, 4, 6]

# 2. Set 新方法

新增一系列集合操作方法。

const setA = new Set(['a', 'b', 'c']);
const setB = new Set(['b', 'c', 'd']);

// union() - 并集
setA.union(setB); // Set(['a', 'b', 'c', 'd'])

// intersection() - 交集
setA.intersection(setB); // Set(['b', 'c'])

// difference() - 差集
setA.difference(setB); // Set(['a'])

// symmetricDifference() - 对称差(存在于A或B,但不同时存在)
setA.symmetricDifference(setB); // Set(['a', 'd'])

// isSubsetOf() - 判断是否为子集
new Set(['a', 'b']).isSubsetOf(new Set(['a', 'b', 'c'])); // true

// isSupersetOf() - 判断是否为超集
new Set(['a', 'b', 'c']).isSupersetOf(new Set(['a', 'b'])); // true

// isDisjointFrom() - 判断是否不相交
new Set(['a', 'b']).isDisjointFrom(new Set(['c', 'd'])); // true

# 3. Promise.try()

统一处理同步和异步代码的错误。

// 传统方式的问题
function compute() {
    try {
        const value = syncFuncMightThrow(); // 可能抛出同步错误
        return asyncFunc(value); // 返回 Promise
    } catch (error) {
        return Promise.reject(error);
    }
}

// 使用 Promise.try()
function compute() {
    return Promise.try(() => {
        const value = syncFuncMightThrow();
        return asyncFunc(value);
    });
}

// 实际应用
Promise.try(() => {
    return riskyOperation();
})
.then(result => console.log('成功:', result))
.catch(error => console.error('错误:', error));

// 优势:统一了同步和异步错误处理
async function processData(data) {
    return Promise.try(() => {
        // 这里可能是同步代码,也可能是异步代码
        if (!data) throw new Error('数据为空');
        return fetch(`/api/${data}`);
    })
    .then(response => response.json())
    .catch(error => {
        console.error('处理失败:', error);
        throw error;
    });
}

# 4. RegExp.escape()

转义正则表达式中的特殊字符。

// 问题场景
const userInput = '[hello]';
// new RegExp(userInput); // 错误:[] 是特殊字符

// 使用 RegExp.escape()
const escaped = RegExp.escape(userInput); // '\[hello\]'
const regex = new RegExp(escaped);

// 实际应用:移除未引用的文本
function removeUnquotedText(str, text) {
    const regExp = new RegExp(
        `(?<!")${RegExp.escape(text)}(?!")`,
        'gu'
    );
    return str.replaceAll(regExp, '•');
}
removeUnquotedText('"yes" and yes and "yes"', 'yes');
// '"yes" and • and "yes"'

// 搜索包含特殊字符的字符串
const searchTerm = 'a+b*c?';
const pattern = new RegExp(RegExp.escape(searchTerm));
pattern.test('a+b*c?'); // true
pattern.test('aabbbbc'); // false

# 5. 导入属性(Import Attributes)

支持导入 JSON 等非 JavaScript 资源。

// 静态导入 JSON
import config from './config.json' with { type: 'json' };
console.log(config.apiUrl);

// 动态导入 JSON
const configData = await import(
    './config.json',
    { with: { type: 'json' } }
);

// 导入 CSS(将来可能支持)
import styles from './styles.css' with { type: 'css' };

// 实际应用
// config.json
{
    "apiUrl": "https://api.example.com",
    "timeout": 5000
}

// app.js
import settings from './config.json' with { type: 'json' };

async function fetchData() {
    const response = await fetch(settings.apiUrl, {
        signal: AbortSignal.timeout(settings.timeout)
    });
    return response.json();
}

# 6. 正则表达式模式修饰符

在正则表达式内部使用修饰符。

// 内联标志 - 对部分表达式应用修饰符
const regex = /^x(?i:hello)x$/;

regex.test('xHELLOx'); // true
regex.test('xhellox'); // true
regex.test('XhelloX'); // false(开头和结尾的 x 仍然区分大小写)

// 实际应用:部分不区分大小写
const pattern = /^(?i:mr|mrs|ms)\.\s+[A-Z][a-z]+$/;
pattern.test('Mr. Smith'); // true
pattern.test('mrs. Johnson'); // true
pattern.test('MS. Williams'); // true

// 禁用修饰符
const regex2 = /(?-i:HELLO)/i; // 整体不区分大小写,但 HELLO 部分区分大小写

# 7. 重复命名捕获组

允许在不同分支中使用相同的组名。

// ES2024 之前,捕获组名必须唯一
// const RE_OLD = /(?<year>\d{4})-\d{2}|(?<year>\d{4})\/\d{2}/; // 错误

// ES2025 允许在不同分支中重复
const RE = /(?<year>\d{4})-(?<month>\d{2})|(?<year>\d{4})\/(?<month>\d{2})/v;

RE.exec('2024-01').groups; // { year: '2024', month: '01' }
RE.exec('2024/12').groups; // { year: '2024', month: '12' }

// 实际应用:匹配不同格式
const datePattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})|(?<month>\d{2})\/(?<day>\d{2})\/(?<year>\d{4})/v;

datePattern.exec('2024-01-15').groups;
// { year: '2024', month: '01', day: '15' }

datePattern.exec('01/15/2024').groups;
// { year: '2024', month: '01', day: '15' }

// 字符类匹配
const RE2 = /(?<chars>a+)|(?<chars>b+)/v;
RE2.exec('aaa').groups; // { chars: 'aaa' }
RE2.exec('bb').groups; // { chars: 'bb' }

# 8. Float16Array(16位浮点数)

支持半精度浮点数,适用于 WebGPU 和机器学习。

// 创建 Float16Array
const arr = new Float16Array([1.5, 2.5, 3.5, 4.5]);

// 属性
arr.BYTES_PER_ELEMENT; // 2(每个元素占2字节)
arr.length; // 4
arr.byteLength; // 8

// Math.f16round() - 转换为最接近的 16 位浮点数
Math.f16round(2.60); // 2.599609375
Math.f16round(2.50); // 2.5
Math.f16round(2.49); // 2.490234375

// DataView 支持
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);

view.setFloat16(0, 3.14);
view.getFloat16(0); // 3.140625

// 实际应用:节省内存
// 32位浮点数数组
const float32 = new Float32Array([1.1, 2.2, 3.3]); // 12 字节

// 16位浮点数数组(精度略低但节省空间)
const float16 = new Float16Array([1.1, 2.2, 3.3]); // 6 字节

// WebGPU 使用场景
const vertices = new Float16Array([
    // x, y, z 坐标
    0.0, 0.5, 0.0,
    -0.5, -0.5, 0.0,
    0.5, -0.5, 0.0
]);

# 正则表达式 v 标志增强

v 标志是 u(unicode)标志的升级版,支持更强大的 Unicode 匹配。

// 匹配 emoji
const emojiPattern = /\p{RGI_Emoji}/v;
emojiPattern.test('Hello 😀'); // true

// 字符类运算
// 并集、交集、差集
const pattern = /[\p{Script=Greek}&&\p{Letter}]/v;

// 字符串属性
const stringPattern = /\p{Emoji_Keycap_Sequence}/v;
stringPattern.test('1️⃣'); // true

# 总结

JavaScript 从简单的脚本语言发展到今天的全栈开发语言,经历了巨大的变化:

  • ES3(1999):奠定基础,引入正则和异常处理
  • ES5(2009):严格模式、JSON 支持、数组方法
  • ES6(2015):里程碑版本,引入 class、模块、Promise、箭头函数等
  • ES2016-ES2025:每年一个版本,持续改进和完善

重点关注的版本:

  • ES6(ES2015):必须掌握,现代 JavaScript 的基础
  • ES2017:async/await 改变异步编程
  • ES2020:可选链和空值合并极大提升开发体验
  • ES2022:私有字段和方法使类更加完善
  • ES2025:迭代器辅助方法、Set 集合操作、Promise.try() 等实用特性

# 参考资料

  • ECMAScript 规范 (opens new window)
  • TC39 提案流程 (opens new window)
  • MDN JavaScript 文档 (opens new window)
  • Can I Use (opens new window):浏览器兼容性查询

祝你变得更强!

编辑 (opens new window)
#JavaScript版本新特性#ECMAScript
上次更新: 2025/11/07
关于this关键字的魔幻现实
JavaScript极简入门

← 关于this关键字的魔幻现实 JavaScript极简入门→

最近更新
01
AI编程时代的一些心得
09-11
02
Claude Code与Codex的协同工作
09-01
03
Claude Code 最佳实践(个人版)
08-01
更多文章>
Theme by Vdoing | Copyright © 2018-2025 京ICP备2021021832号-2 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式