🚀 ES6 / ES2015(2015)
一句话定性
ES6 是 JavaScript 历史的楚河汉界:它一次性补齐了一门现代语言该有的一切(
class、let/const、箭头函数、Promise、模块、解构),把”古典 JS”和”现代 JS”彻底劈成两个世界。但它最深刻的智慧,藏在它做这一切时一行旧代码都没破坏——这正是 ES4 流产用六年和一场内战换来的教训。
一、它是什么 & 出现的时代
ES6,正式名 ECMAScript 2015,发布于 2015 年 6 月。它酝酿了整整六年(自 ES5 2009),是 ES4 流产后”Harmony 路线”修成的正果——那些 ES4 想做却做砸的事(class、模块),被拆散、温和化,小心翼翼地重新引入。
它的发布恰逢 SPA 时代的开端:React(2013)、Vue(2014)正在崛起,前端正从”页面制作”升级为”软件工程”。但开发者手里的语言工具(ES3/ES5)还停留在上个时代。ES6 给了现代框架一套趁手的现代化工具——它和 SPA 革命互相成就。
为什么叫 ES6,又叫 ES2015?
它本来该叫 ES6(第六版)。但因为拖了六年,委员会借此机会改革:从此改为年度发布,用年份命名(ES2016、ES2017……)。所以 ES6 是”旧命名法的最后一个大版本”,也是”新命名法的第一年”。两个名字指的是同一个东西,新代码里更推荐叫 ES2015。
二、为什么会出现(解决上一代什么痛点)
ES5 之后,JS 写大型应用的痛点已经积累到临界点:
- 作用域混乱:只有函数作用域,
var提升导致闭包陷阱(循环里的经典 bug)。 this反复无常:回调里this丢失,满屏var self = this和.bind(this)。- 没有 class:模拟”类”要写一长串原型链样板代码,新人完全看不懂。
- 回调地狱(Callback Hell):异步嵌套成”金字塔”,错误处理一团乱。
- 没有原生模块:全局变量污染,靠 AMD 等社区方案各自为政。
- 字符串拼接地狱:
'Hello ' + name + ', you have ' + n + ' msgs'。
ES6 是一次”集中还债”——把这些积压十几年的痛点一次性解决。
三、关键特性 & 为什么重要
① let / const(块级作用域)
终于有了块级作用域({}),const 提供常量。为什么重要:消灭了 var 提升和闭包循环陷阱这一整类 bug;const 鼓励”默认不可变”的心智,代码更可推理。注意:var 没有被删除(不能破坏旧代码),let 是叠加上去的——又一次渐进兼容。
② 箭头函数 =>
更短的语法,且词法 this(继承外层的 this,不再丢失)。为什么重要:它一举消灭了 var self = this 和满屏 .bind(this)。在 React/Vue 的回调和数组方法里,箭头函数成了绝对主力。
③ class(语法糖)
class Dog extends Animal {
constructor(name) { super(name) }
bark() { /* ... */ }
}class 只是语法糖,底层还是原型链
这是 ES6 最容易被误解的特性。
class没有引入任何新的对象模型——它底层依然是 JS 一直以来的原型链(prototype chain)。class Dog {}本质上还是创建一个构造函数 + 在Dog.prototype上挂方法。 为什么这么做?因为不能破坏向后兼容(ES4 的教训)。 委员会不能把 JS 改成 Java 那样的”真正的类”,只能提供一层让原型链”看起来像类”的糖衣,降低认知门槛。理解这一点,才能解释为什么class里依然有this绑定问题、为什么能Dog.prototype访问到方法。
④ Promise
把异步从”回调地狱”拉成可链式调用(.then().catch())的扁平结构。为什么重要:它给了异步一个统一的标准抽象,是后来 ES2017 async/await 的地基——async/await 只是 Promise 的语法糖。
⑤ 模板字符串 `
`Hello ${name}, you have ${n} msgs` + 多行字符串。为什么重要:终结了 + 拼接地狱,也为后来的 styled-components、GraphQL 标签模板等”模板 DSL”打开了大门。
⑥ 解构 & 展开运算符
const { a, b } = obj、const [x, y] = arr、...rest / ...spread。为什么重要:它让”从对象/数组里取值”和”合并/拷贝”变得极其简洁。在 React 里,const { name, age } = props 和 <Comp {...props} /> 成了日常。
⑦ Module(ES Modules)
import / export 终于成了语言原生标准。为什么重要:这是结束 CommonJS vs AMD 模块大战的关键一步,而且它的静态可分析性(import 关系在编译期就能确定)是 tree-shaking 和 Vite 的根本前提。详见 ES-Modules。
还有:
Map/Set、Symbol、Proxy、生成器、默认参数、迭代器协议……
四、带来的新问题 / 副作用
ES6 的强大,催生了一整条工具链
- 浏览器跟不上,催生了 Babel:2015 年没有任何浏览器完整支持 ES6,但开发者迫不及待要用。Babel 应运而生——把 ES6 转译成 ES5,让新语法能在老浏览器跑。 这是 ES6 能”立即普及”的关键,也让”转译”成为现代前端不可或缺的一环。
- 模块要打包:浏览器当时还不支持原生
import,于是 Webpack/Rollup 等打包器成了标配。语言现代化 → 工具链复杂化,这是通往 2018-2023 工程化时代的直接推手。class的误解:很多从 Java/C# 来的开发者以为 JS 有了”真正的类”,结果在this绑定、原型继承上反复踩坑。语法糖掩盖了底层模型,降低了门槛也制造了认知错位。- 特性过载:ES6 一次性塞进太多东西,初学者的学习曲线陡增。“现代 JS”和”古典 JS”的鸿沟,也让老项目的迁移成本变高。
五、对后续技术的影响(因果链)
ES4 流产 (2008) ──► 教训:渐进、不破坏兼容
│
↓ (酝酿 6 年)
ES6 / ES2015 (2015) 分水岭
│
├──► class / 箭头函数 / let / 解构 / 模板字符串
│ │
│ └──► 现代框架([[React]]/[[Vue]])的趁手工具 ──► 成就 [[2013-2018 SPA时代]]
│
├──► 浏览器不支持 ──► [[Babel]] 转译 ES6→ES5 ──► 新语法立即可用
│ ──► "转译"成为前端标配
│
├──► Promise ──► ES2017 async/await(Promise 的语法糖)──► 异步编程现代化
│
├──► Module([[ES-Modules]])──► 静态可分析 ──► tree-shaking([[Rollup]])
│ ──► 浏览器原生 ESM ──► [[Vite]]
│
└──► Proxy(比 defineProperty 强)──► [[Vue]] 3 重写响应式,解决 Vue 2 的顽疾
历史地位
如果说 SPA 时代的”牛顿第一定律”是
UI = f(state),那 ES6 就是承载这条定律的语言基石。它是现代前端的”创世纪”:今天你写的几乎每一行专业 JS/TS 代码——箭头函数、解构、async/await、import——都直接源自 ES6。它最伟大之处不在于”加了多少特性”,而在于它在做这一切剧变时,没有打碎任何一块旧玻璃。这,就是从 ES4 的废墟里学到的、最昂贵的一课。
🔗 时代背景:2013-2018 SPA时代 | 2018-2023 工程化时代 🔗 版本脉络:ECMAScript演进史 | 上一版 ES5 | 模块详解 → ES-Modules 🔗 相关:Babel | React | Vue | TypeScript | Webpack | Vite