← JavaScript特性 没有下一篇了 →

JavaScript版本

原创 2026-03-10 JavaScript 已有人查阅

JavaScript,这个名字对于任何一个网页开发者来说都不陌生。它最初只是为了在浏览器里添加一些简单的交互而诞生,如今却已成长为可以驾驭前端、后端、移动端乃至桌面应用的“全栈”语言。它的成长轨迹,几乎就是一部现代Web技术的发展史。今天,我们就来从头梳理一下JavaScript的各个版本,看看那些我们每天都在用的特性,究竟是从哪里来的。

很多初学者在学习JavaScript时,会被ES5、ES6、ES2015这些名词搞得晕头转向。实,ES是ECMAScript的缩写,它就是一个由ECMA国际组织制定的“语言标准”。JavaScript则是这个标准最著名的“实现”。打个比方,ECMAScript是剧本,而JavaScript是演员,演员要根据剧本来表演。浏览器厂商(比如Chrome的V8引擎)也都得按照这个标准来实现JavaScript,这样才能保证我们写的代码在不同浏览器里表现一致。

为什么我们需要了解版本历史?

有人会问:“我现在直接用的语法写代码不就行了,了解这些老古董有什么用?” 我个人觉得,了解历史不仅能帮助我们更好地理解语言本身的设计哲学,当你在维护一个老项目,或者在某个老旧浏览器上调试问题时,能迅速判断出哪些特性可用,哪些需要做兼容处理。而且,看到一门语言是如何一步步吸收新思想、新特性,也是一件挺有意思的事。

早期奠基:ES1、ES2、ES3(1997-1999)

ES1 (1997): 一切的开端。这一年,ECMAScript第一版标准正式发布,为JavaScript这门语言奠定了最核心的基础。变量、函数、基本的流程控制(如if...else, for循环),这些我们现在觉得理所应当的东西,在当时都是开天辟地的创新。

ES2 (1998): 一次很小的更新,主要是为了让标准更严谨,保持与ISO/IEC国际标准的统一,没有引入什么面向开发者的新特性。

ES3 (1999): 这是一个非常重要的版本。在它之后,JavaScript沉寂了将近十年。ES3引入的特性,很多我们今天仍在频繁使用:

  • 正则表达式: 让字符串的模式匹配和处理能力上了一个大台阶。

  • try/catch异常处理: 以前代码出错了就直接崩溃或者静默失败,有了异常处理,我们就能更优雅地捕获和处理错误,增强程序的健壮性。

  • do-while循环: 新增了一种循环结构。

沉寂与重生:ES4(停用)与ES5(2009)

ES4(未发布): 这是一个“未发布”的版本。由于参与制定的各方(主要是微软和雅虎)在语言复杂度上产生了严重分歧,ES4最终被废弃。但它在语言设计上的很多激进探索,为后来的版本提供了宝贵的经验和教训。

ES5 (2009): 在经历了长达十年的空窗期后,ES5的发布标志着JavaScript的“文艺复兴”。它不像ES4那么激进,而是在ES3的基础上进行了“现代化改造”,提供了很多我们至今仍在依赖的基础设施。我个人认为,ES5是“现代JavaScript”的基石。

  • 严格模式('use strict'): 这是我个人非常推荐开启的一个模式。它能捕获一些常见的编码错误(比如意外创建全局变量),禁用一些不严谨或容易出错的语法(比如with语句),让JavaScript运行得更安全、更规范。在代码文件或函数顶部写上'use strict',就相当于告诉JavaScript引擎:“请用更严格的规则来检查我的代码。”

    'use strict';
    // 在严格模式下,以下操作会报错
    // undeclaredVariable = 10; // ReferenceError: undeclaredVariable is not defined
  • 数组新方法: forEachmapfiltereveryindexOf等方法的加入,让数组操作变得前所未有的优雅。告别了繁琐的for循环,我们可以用更声明式的方式来处理数据。比如在代码号(https://www.ebingou.cn/)的后台管理系统里,我们经常用filter来筛选用户列表。

    const numbers = [1, 2, 3, 4, 5];
    // 用map创建一个新数组,每个元素翻倍
    const doubled = numbers.map(num => num * 2); // [2, 4, 6, 8, 10]
    // 用filter筛选出大于3的数字
    const filtered = numbers.filter(num => num > 3); // [4, 5]
  • JSON支持: 引入了JSON.parse()JSON.stringify()。这对于前后端数据交互至关重要。以前我们需要自己写函数来解析JSON字符串,现在一切都变得标准且高效。

  • 对象操作增强: 引入了Object.defineProperty()等方法,允许我们精确地控制对象的属性(比如设置属性是否可读、可枚举)。这也是后来Vue.js等框架实现响应式系统的核心技术。

大爆发时代:ES2015(ES6)及之后

ES2015(或称ES6)是JavaScript历史上重要的一次更新,它彻底改变了我们编写JavaScript的方式。

ES2015 (ES6)

这次更新带来的新特性之多,让开发者应接不暇,也促成了像Babel这样的转译工具(可以把ES6代码转为ES5代码以保证兼容性)的流行。

  • letconst 告别了var的函数作用域,迎来了块级作用域。let用于声明变量,const用于声明常量。我个人的建议是,在代码中优先使用const,当确定变量的值需要被重新赋值时,才使用let。这能让代码意图更清晰,也避免了不少意外修改带来的bug。

    // 使用const声明一个常量,它的值不能被重新赋值
    const PI = 3.14159;
    // PI = 3.14; // 这会报错
    
    // 使用let声明一个块级作用域的变量
    for (let i = 0; i < 5; i++) {
        // i只在循环内部有效
    }
    // console.log(i); // 报错:i is not defined
  • 箭头函数: 不仅写法更简洁,它不绑定自己的this,而是继承父执行上下文中的this。这解决了以前回调函数中this指向混乱的问题。

    // 传统函数
    const add1 = function(a, b) {
        return a + b;
    };
    
    // 箭头函数
    const add2 = (a, b) => a + b; 
    
    模板字符串: 用反引号(`)包裹,可以通过${}直接嵌入变量,再也不用繁琐地用加号拼接字符串了。
    const name = '代码号';
    const url = 'https://www.ebingou.cn/';
    // 用模板字符串拼接
    const message = `欢迎访问${name},网址是:${url}`; 
  • 解构赋值: 可以从数组或对象中快速提取值并赋给变量。

    // 对象解构
    const user = { name: '张三', age: 30 };
    const { name, age } = user; 
    console.log(name); // 输出: 张三
    
    // 数组解构
    const colors = ['红', '绿', '蓝'];
    const [red, green, blue] = colors;
  • Promise: 用于处理异步操作,是解决“回调地狱”的良药。

ES2016 (ES7)

这是一个小版本,主要带来了两个实用特性。

  • 数组的includes()方法: 判断数组是否包含某个元素,返回布尔值。比用indexOf() !== -1语义更清晰。

    const arr = [1, 2, 3];
    console.log(arr.includes(2)); // true
    console.log(arr.includes(4)); // false
  • 指数运算符**:** 相当于Math.pow()

    console.log(2 ** 10); // 1024

ES2017 (ES8)

  • async/await 这是对Promise的进一步封装,让异步代码写起来像同步代码一样直观。它是我现在处理所有异步操作的优选方式,极大地提升了代码的可读性和可维护性。你可以在代码号的教程频道(https://www.ebingou.cn/jiaocheng/)找到更多关于异步编程的讲解。

    async function fetchData() {
        try {
            const response = await fetch('https://api.example.com/data');
            const data = await response.json();
            console.log(data);
        } catch (error) {
            console.error('请求失败', error);
        }
    }
  • Object.values() / Object.entries() 这两个方法让遍历对象变得极方便。Object.entries()返回对象自身可枚举属性的键值对数组,非常适合与for...of循环配合使用。

    const person = { name: '李四', city: '北京' };
    for (const [key, value] of Object.entries(person)) {
        console.log(`${key}: ${value}`);
    }
    // name: 李四
    // city: 北京
  • 字符串填充: padStart()padEnd(),常用于格式化输出,比如让数字显示固定的位数。

ES2018 - ES2024 (ES9 - ES15)

此后的版本保持每年更新的节奏,每次都会带来一些实用的小特性,不断完善这门语言。

  • ES2018 (ES9): 引入了对象的展开运算符(...),让我们能轻松地克隆或合并对象;还带来了for await...of,用于遍历异步数据源。

  • ES2019 (ES10): 增加了Array.prototype.flat()flatMap(),用于扁平化嵌套数组;Object.fromEntries()则可以将键值对列表转成对象,是Object.entries()的逆操作。

  • ES2020 (ES11): 空值合并运算符() 和可选链操作符(. 是两个我非常喜欢的特性。

    • :当左侧的值为nullundefined时,才返回右侧的值。这与||不同,||会在左侧值为假(如''0false)时返回右侧,这在处理数字0时容易出错。

    • :允许我们在访问深层嵌套的对象属性时,不必显式校验每一层是否存在。如果中间某层是nullundefined,表达式会直接返回undefined,而不会报错。

    const user = {
        profile: {
            // name: '王五'
        }
    };
    // 以前我们得这样写
    // const userName = user.profile && user.profile.name;
    
    // 现在用可选链
    const userName = user.profile.name; 
    console.log(userName); // undefined, 而不是报错
    
    // 结合空值合并
    const displayName = user.profile.name  '匿名用户';
    console.log(displayName); // 输出: 匿名用户
  • ES2021 (ES12): String.prototype.replaceAll()可以一次性替换所有匹配的字符串,而不用写正则;Promise.any()接受一组Promise,只要中一个成功,就返回那个成功的值。

  • ES2022 (ES13): 允许在类的顶层使用await,即顶层await;并且正式引入了类的私有属性和方法,用#前缀表示,强化了封装性。

  • ES2023 (ES14): 新增了非破坏性的数组方法,如toSorted()toReversed()toSpliced()。它们会返回一个新数组,而不是修改原数组,这符合函数式编程的不可变性理念,能有效避免副作用。在代码号的编程学习社区(https://www.ebingou.cn/biancheng/)里,处理用户提交的不可变数据时,这些方法非常有用。

    const original = [3, 1, 2];
    const sorted = original.toSorted(); // sorted是 [1, 2, 3]
    console.log(original); // 原数组仍然是 [3, 1, 2],没有被改变!
  • ES2024 (ES15): 引入了Object.groupBy()Map.groupBy(),可以根据回调函数的返回值对数组元素进行分组,非常实用。

总结

从1997年到2025年,JavaScript从一个简单的浏览器脚本语言,成长为如今功能强大、生态繁荣的编程语言。每次版本的更新,都不是简单的功能堆砌,而是为了解决开发者痛点、适应Web发展需求而精心设计的。

对于我们开发者而言,持续跟进这些新特性是非常有价值的。它们能帮助我们写出更简洁、更高效、更健壮的代码。也不必为了用新特性而用,理解背后的设计思想和适用场景,才是学习的核心。

← JavaScript特性 没有下一篇了 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号