漫长的 JavaScript 的发展史。
ES 1 创业版
JavaScript 语言的雏形,奠定了语言的基本。
- 原始值:
Number、String、boolean、null、undefined - 变量声明:使用
var关键字声明变量 - 定义了大部分的运算符、基本流程控制语句、内置对象、函数与对象机制
- 确立了函数的一等公民的身份
- 建立了基于原型的继承机制,且内置了核心的内置对象
- 提出了初步的正则表达式雏形
- 提出了初步的错误处理机制
try...catch...finally
ES 2 补丁版
在 ECMAScript 2 中并没有添加新的特性,反而是让 [ES1] 更加的规范和正规(符合国际标准化组织规范)
ES 3 重大更新
- 正则表达式的加强:确立了正则表达式的一等公民身份,明确了字面量语法、构造函数 构建表达式及提供了
String使用方法 - 异常处理:完善了结构化的错误处理机制(主动抛出错误),让开发者可以更加优雅的捕获和处理运行时的错误,避免程序崩溃,并执行清理工作,显著提高了代码的健壮性和可维护性
switch分支:提供了更优的分支体系do...while循环:提供了确保循环体至少执行一次的循环结构,优化了原有循环逻辑for...in循环:提供更便捷的对象可枚举属性的遍历new运算符的改进:使其创建对象的过程更加明确可控- **
==和!=改进**:规范了其对比时类型强制转化的行为 String对象:新增了charAt():查找给定字符在字符串的索引下标charCodeAt():查找给定字符在字符串的索引下标indexOf():查找给定子串在字符串的位置lastIndexOf()slice():substring()toLoverCase()toUpperCase()
Array对象:新增了concat()join()pop()push()reverse()shift()slice()sort():sort()还支持传入自定义的比较函数splice()unshift()
Date()对象:增强了日期的处理能力,提供了更精准的毫秒级时间操作方法Function对象:length属性被标准化,表示函数期望的参数个个数- 全局对象:
isFinite()和isNaN()函数被明确定义和标准化 - 函数和
this的增强:call()与apply()方法:允许调用函数时执行this指向,解决了函数在不同上下文执行时的 this 绑定问题arguments对象完善:明确arguments与函数的“动态绑定”(修改了arguments[i]会同步修改对应参数,反之亦然),但后续 ES5 严格模式取消了这一特性
ES 4 失败的激进版
为了让 JavaScript 能够成为一个可以与 Java、C# 竞争、适合大型应用开发的企业级语言,试图从一门动态脚本语言转变成一门更严谨、更适合大规模开发的静态类型语言。
所以,ES 4 提案提出了:
- 强类型系统
- 类
- 模块化
- 包和命名空间
- 丰富的集合类型
- 迭代器和生成器
- 泛型
- 多重继承
- 字符串模版
- 更大的元编辑能力
但由于太过于极具野心而成为被放弃的版本。
ES 5 里程碑式的版本
- 严格模式
Array内置对象新增- 迭代
forEach()map()filter()some()every()reduce()reduceRight()
- 查找
indexOf()lastIndexOf()
- 迭代
- 还为数组添加了原型方法
Array.isArray(arr)用于判定一个值是否是数组 String内置对象新增了trim()方法Object对象新增Object.create(proto, [propertiesObjet])Object.defineProperty(obj, prop, descriptor)/Object.defineProperties(obj, props)Object.keys(obj)Object.getOwnPropertyNames(obj)Object.getOwnPropertyDescriptor(obj, prop)Object.seal(obj)Object.freeze(obj)Object.preventExtensions(obj)- 新增了
getter/setter属性,使用get和set关键字定义对象的访问器属性
- 添加了原生的
JSON支持 - 新添了
bind解决this指向问题 - 新增了
Date.now()返回当前时间戳
ES 6 可能是最后一次重大升级的版本
- 添加了:
let和const来创建有块级作用域的声明关键字(或称为“变量声明语句”)- 模版字符串
Symbols这一原始类型Set和Map两种复合类型的数据Proxy和Reflect两个好基友- 箭头函数,简化了部分场景下的函数使用
- 解构赋值
- 默认参数、剩余参数、扩展运算符(扩展运算符并未支持
Object,这一特性在 [es9] 才得以引入) - class 类这个语法糖
- 迭代器和生成器的官法迭代认证
- 提供了字符串的
includes()、startsWith()、endsWith()、repeat()等方法 - 在正则表达式中添加了
u修饰符,含义为Unicode模式,用于处理大于\uFFFF的 Unicode 字符 - 引入了 Promise ,解决了地狱循环。包含
Promise.resolve()、Promise.reject()、Promise.all()、Promise.race()静态方法 - 官方确立了 模块化 的标准
- 优化了:
- 升级了
Unicode到支持 5.1.0 版本 - 增强了对象字面量,可以简写属性同名变量值、方法声明无需使用
: function () {}格式
- 升级了
ES 7 微小的改进
- 为数组新增了
includes()方法,解决了传统的indexOf()的局限性 - 新增了
**指数运算符
ES 8 异步变“同步”
- 为了简化
Promise的使用,引入了Async/Await - 为对象引入了
Object.value()Object.entries()Object.getOwnPropertyDescriptors()
- 字符串填充
padStart()、padEnd()简化了文本的格式化输出 - 函数参数列表和调用中的尾逗号不在影响代码的执行
SharedArrayBuffer共享内存- 提供了
Atomics原子操作
ES 9 异步迭代和正则表达式的增强
- 新增了:
- 异步迭代和异步可迭代对象,提供了
for-await-of用于遍历异步数据 Promise.prototype.finally()避免了部分代码的重复(好吧,我之前都是封装函数解决的)
- 异步迭代和异步可迭代对象,提供了
- 扩展了 Rest/Spread 到对象上的使用
- 正则表达式尽心了加强:
- 命名捕获组
- 反向断言
- Unicode 属性转义
- ditAll (
s标志)模式,可使.匹配包含\n、\r在内的换行符
- 模版字符串进行了加强,允许
\u、\x等转义序列而不再报错 - 可选的
catch绑定 JSON超集问题,允许 JSON 中出现未转义的终止符(如\n、\r、\u2028、\u2029)
ES 10 中规中矩的增强
- 添加了:
Array.prototype.flat()和Array.prototype.flatMap()解决嵌套数组的扁平化处理String.prototype.trimStart()和String.prototype.trimEnd()去除文本空格Object.formEntries()作为Object.entries()的逆向操作,更优雅的构建对象Symbol.prototype.description用于获取Symbol创建时的描述字符串,无描述时返回undefined- 可选的
Catch绑定
- 优化了:
function.prototype.toString()方法,现返回函数的完整源代码,包含注释、空格、参数默认值等Array.prototype.sort()的稳定性JSON.stringify()对Symbol的处理
- 规范了
JSON.stringify()输出符合标准的 JSON 字符串,避免因为“孤立代理项”导致的无效 JSON
ES 11 面向模块的优化
- 添加了:
- 可选链式操作符
?. - 空值合并操作符
?? import()函数允许动态加载模块BigInt类型以支持大数字String.prototype.matchAll()解决match()无法获取所有捕获组的问题globalThis统一了全局对象访问Promise.allSettled()方法用于补充Promise.all()有子Promise失败就退出- 模块化中的
import.meta来访问模块的元信息
- 可选链式操作符
- 优化了:
- 模块化的命名空间导出
for-in枚举时顺序问题
ES 12 进一步的优化
- 添加了:
String.prototype.replaceAll()来补充String.prototype.replace()&&=、||=、??=等方法,进一步简化某些情况下的赋值- 数字分隔符,在不影响数字的值的前提下增强了数字的可读性
Promise.any()与AggregateError来返回第一个成功兑现的 Promise 结果WeakRef与FinalizationRegistry来优化对象的“强引用”问题Intl对象,增强了国际化
- 优化了
Array.prototype.sort()方法,提升排序结果的一致性
ES 13 类与对象的强化
- 添加了
- 类中属性或方法使用
#前缀声明为私有属性或方法 - 静态成员使用
#前缀声明为私有静态成员 - 类的静态初始块,用于执行类级别的初始化逻辑
- 顶层的
await Array.prototype.at()方法,弥补之前访问元素不便- 正则表达式的
d标志,使exec()、match()等方法返回的结果包含indices属性,记录匹配内容以及捕获组的起始结果索引 Error构造函数的cause选项,允许抛出新错误时附加原始错误,形成错误链Object.hasOwn()代替Object.prototype.hasOwnProperty.call(obj, prop)检测对象自身是否有某属性
- 类中属性或方法使用
- 优化了
- 类声明字段的声明,可在类中直接声明字段,而不再在
constructor中使用this.xxx声明 in操作符中使用#fieldName来检测一个对象是否包含特定的私有字段,而不会抛出错误
- 类声明字段的声明,可在类中直接声明字段,而不再在
ES 14 数组的进一步优化
- 添加了:
- 数组的 4 个不可变操作
Array.prototype.toReversed()返回一个新的反转数组Array.prototype.toSorted(compareFn)返回一个新的排序后的数组Array.prototype.toSpliced(start, deleteCount, ...items)返回更改后一个新的数组Array.prototype.with(index, value)返回一个指定索引被更改的新数组
- 数组的新的尾部查找:
Array.prototype.findLast(callback, thisArg)从数组的最后一个元素开始遍历,找到第一个满足条件的元素Array.prototype.findLastIndex(callback, thisArg)从数组的最后一个元素开始遍历,找到第一个满足条件的元素的索引
WeakMap的键可被设置成使用Object.freeze()、Object.seal()处理过的对象- 正式将 Hashbang 语言纳入标准
Object.groupBy用于数组的统计,简化了传统的Array.prototype.reduce()方法进行分组的复杂操作- 添加了
@装饰器(这货在 Angular 和 Nest.js 中用的风生水起)
- 数组的 4 个不可变操作
ES 15 小小的优化
- 添加了:
Promise.withResolvers()直接返回一个包含promise、resolve、reject的对象,简化 Promise 的创建ArrayBuffer和SharedArrayBuffer新功能TypedArray.prototype.with()不可变修改TypedArray- 正则匹配新的
v标志,增强了处理 Unicode 的复杂的字符集运算
ES 16 可能还没被支持的大更新
- 添加了:
Promise.try()统一处理同步和异步操作的错误,避免了Promise.resolver().then()的微任务延迟问题Set新增了七个方法:Set.prototype.union()并集Set.prototype.Intersection()交集Set.prototype.difference()差集Set.prototype.symmetricDifference()对称差集Set.prototype.isSubsetOf()子集判定Set.prototype.isSupersetOf()超集判定Set.prototype.isDisjoinFrom()无交集判定
- 同步迭代辅助方法,链式结构
map()、filter()、take()、drop()、toArray() - 通过
with { type: 'json'}直接导入 JSON 文件,无需手动解析 - 使用
defer声明一个预加载模块,延迟到首次调用时才访问引入模块 - 使用
RegExp.escape()安全转义正则特殊字符(*、?、$) - 在正则表达式中动态启用或禁用标志的功能
- 在正则表达式中重复命名捕获组
- 底层支持
Float16Array类型 - 通过
using声明的变量,通过Symbol.dispose在作用域结束清理逻辑时,自动释放文件句柄、网络连接等资源,避免内存泄漏 - 支持对象、数组结构以及条件分支,代替深层嵌套的
if-else(没看懂要干啥) - 智能管道符
|>将连续调用转化为更直观的线式调用 - 原生的类型注解(与其说是为了干掉 TypeScript,但不如说是变成了 TypeScript)
Record和Tuple两种新的深度不可变的数据结构,通过#标记数据