ECMAScript 各个版本的语法列表

1 阅读9分钟

 

ES6「经典JS时代之前的语法

         ES6 之前(即 ES5.1 及更早,1997–2011) 的 JS 语法与特性。这段统称为「经典 JS / ES5 时代」,是 ES6 出现前所有浏览器原生支持的基础。

        时间线一句话:ES1(1997) → ES2(1998) → ES3(1999,大版本) → ES4(废弃) → ES5(2009) → ES5.1(2011) → ES6(2015)

一、变量与函数声明

  • var(函数作用域、变量提升 hoisting、可重复声明)

    var x = 1;
    

  • 函数声明 function f() { }(整体提升)

  • 函数表达式 var f = function() { }

  • 隐式全局变量(不声明直接赋值 → 泄漏到全局)

  • 没有 let / const(那是 ES6)

二、原始类型与字面量

  • 五种原始类型:undefined / null / boolean / number / string(无 Symbol、无 BigInt
  • number 即 IEEE-754 双精度;NaNInfinity-Infinity
  • 字面量:十进制、0x 十六进制;遗留八进制 010(仅非严格模式,已废弃)
  • 字符串字面量 '...' / "..."(无模板字符串)
  • 没有 0b / 0o 字面量(ES6)

三、对象与原型

  • 对象字面量 { key: value },属性访问 . 与 []

  • 访问器(getter/setter) { get x(){}, set x(v){} } — (ES5)

  • 方法定义只能写 m: function(){}(无方法简写、无计算属性名)

  • 基于原型的继承:prototypeconstructornew

  • this 动态绑定(四种规则:默认 / new / 隐式 / 显式 call·apply

  • Object 内置:

    • Object.create (ES5)Object.defineProperty / defineProperties (ES5)
    • Object.getOwnPropertyDescriptor / getPrototypeOf (ES5)
    • Object.keys (ES5)Object.freeze / seal / preventExtensions / isFrozen… (ES5)
    • Object.prototypehasOwnPropertytoStringvalueOfisPrototypeOfpropertyIsEnumerable

四、函数特性

  • arguments 类数组对象(无剩余参数)

  • call / apply(ES3)、bind(ES5,固定 this

  • 闭包(lexical scope)

  • IIFE 立即执行函数表达式(模块隔离的惯用法)

    ( function(){ 
        var private = 1; 
        /*  xxx   */
    })();
    

  • 回调函数、this 丢失需 var self = this 或 bind 保存(无箭头函数)

  • 递归、命名函数表达式

  • 没有默认参数、剩余参数、展开运算符(均 ES6)

五、控制流

  • if / elseswitch / case / break / default
  • for(C 风格)、while / do...while
  • for...in(遍历对象可枚举属性,含继承链,(ES1);无 for...of
  • try / catch(e) / finallycatch 必须带参数,省略参数是 ES2019 才允许)
  • throw、三元 ? :、逗号运算符、break / continue(含 label: 标签语句)

六、运算符与比较

  • 算术 + - * / %(无 **,那是 ES2016)、++ --、一元 +/-
  • 位运算 & | ^ ~ << >> >>>
  • 赋值 = 及复合 += -= 等
  • 关系 > < >= <=ininstanceof
  • 逻辑 && || !
  • 相等:==/!=(宽松、会发生类型转换)、===/!==(严格)
  • typeofvoiddeletenew() 分组
  • 没有 ?. / ??(ES2020)

七、数组

  • 数组字面量 [1,2,3]new Array()、稀疏数组
  • ES3 方法push/pop/shift/unshift/slice/splice/concat/join/sort/reverse
  • (ES5)forEach / map / filter / reduce / reduceRight / some / everyindexOf / lastIndexOfArray.isArray
  • 没有 from/of/find/findIndex/fill/flat/includes/at(ES6 及以后)

八、字符串

  • ES3charAtcharCodeAtconcatindexOflastIndexOfmatchreplacesearchslicesplitsubstringsubstrtoLowerCasetoUpperCaselocaleCompare,以及一批 HTML 辅助方法(bold/link…)
  • (ES5)trim(仅前后空白)
  • 没有 includes/startsWith/endsWith/repeat(ES6)、padStart/padEnd(ES2017)、replaceAll(ES2021)

九、正则

  • 正则字面量 /pat/flags 与 new RegExp
  • 标志仅 g / i / m(无 u/y(ES6)、s(ES2018)、d(ES2022)、v(ES2024))
  • 方法:testexec;字符串侧 match/replace/search/split
  • 无具名捕获组 (?<n>)、后行断言 (?<=)\p{} 属性转义

十、内置对象

  • Math(ES1):abs/ceil/floor/round/max/min/random/pow/sqrt/sin/cos/tan/log/exp/atan/atan2…(无 trunc/sign/hypot/cbrt/log2/log10/imul,均 ES6)
  • Date(ES1)及 (ES5) Date.now()
  • Number 常量:MAX_VALUE/MIN_VALUE/NaN/POSITIVE_INFINITY/NEGATIVE_INFINITY(无 EPSILON/MAX_SAFE_INTEGER,ES6)
  • 全局:parseInt/parseFloatisNaN/isFiniteevalencodeURI/decodeURI/encodeURIComponent/decodeURIComponent(ES3)、escape/unescape(已废弃)
  • JSON.parse / JSON.stringify — (ES5)
  • 错误类型:Error/EvalError/RangeError/ReferenceError/SyntaxError/TypeError/URIError(无 AggregateError(ES2021)、无 Error.cause(ES2022))

十一、严格模式与遗留语法

  • "use strict"; 指令 — (ES5)(启用更严格的校验,且禁止 with 与遗留八进制)
  • with (obj) {} 语句 — 遗留语法,严格模式下报错(不推荐使用)
  • debugger; 语句
  • 模块系统:原生没有 import/export,靠 IIFE / 全局命名空间,或社区方案 CommonJS、AMD

小结:回到 ES5 会失去的关键能力

你习惯的现代写法ES5 替代表达
let / constvar + 函数作用域 / IIFE
箭头函数function(){} + var self=this 或 .bind(this)
模板字符串字符串拼接 '+a+'
解构 / 默认 / 剩余 / 展开手动赋值、arguments、循环合并
class构造函数 + 原型赋值
Promise / async回调 / 手动 Promise 垫片
Map / Set普通对象 / 数组 + indexOf
for...offor + 索引 或 for...in + hasOwnProperty 过滤
模块 import/exportIIFE / CommonJS / AMD
?. / ??&& 链 / `

简单说:ES5 时代没有块级作用域、没有 class、没有 Promise/模块/解构/箭头函数,异步全靠回调,this 需要手动绑定  这些正是 ES6 一次性补齐、并让 JS 从「能用的脚本语言」变成「可工程化的语言」的核心。

ES2015(ES6)— 奠基大版本

〇、大纲

  • let / const 块级声明
  • 箭头函数 =>
  • 模板字符串 `...${}`
  • 解构赋值(数组 / 对象)
  • 默认参数、剩余参数 ...args、展开运算符 ...
  • 对象字面量增强(属性简写 / 计算属性名)
  • class 类与继承
  • 模块 import / export
  • Symbol 原始类型
  • Promise
  • 迭代器 + for...of
  • 生成器 function* / yield
  • Map / Set / WeakMap / WeakSet
  • Proxy / Reflect
  • 新 API:Array.from/of/find/fillObject.assign/isNumber.*Math.*0b/0o 字面量;正则 u/y

这是 JS 历史上最大的一次单版本更新,之后的 ES2016/2017… 都是在它基础上的增量。

说明:严格意义上的「ES6 = ES2015」。有些人把一切现代 JS 都叫「ES6」,async/awaitObject.values?.?? 等其实属于 ES2017 / ES2020。


一、变量声明:let / const

  • let:块级作用域变量,存在暂时性死区(声明前访问报错),不允许重复声明。
  • const:声明常量(绑定不可重新赋值,但对象/数组内部可改)。
let x = 1;
const PI = 3.14;
if (true) { let y = 2; } // y 在块外不可见

二、函数增强

特性说明
箭头函数 =>不绑定自己的 this/arguments,继承外层;适合回调
默认参数function f(a = 1, b = 2){}
剩余参数 Restfunction f(...args){} 收集为真正数组
展开运算符[...a, ...b]Math.max(...nums)
块级函数声明块内声明的函数仅在块内可见
const add = (a, b) => a + b;
const nums = [1, 2, 3];
const merged = [...nums, 4];   // [1,2,3,4]

三、模板字符串(Template Literals)

  • 反引号 ` 包裹,支持 ${} 插值和多行。
  • 衍生:标签模板 tag`...`(用于 i18n、安全转义等)。
const name = 'Tom';
const msg = `Hello ${name}, sum=${1 + 1}`;

四、解构赋值(Destructuring)

  • 数组解构、对象解构、嵌套解构、重命名、默认值、参数解构。
const [a, b] = [1, 2];
const { name, age: a2 = 18 } = user;   // 重命名+默认值
const [, , third] = arr;                // 跳过
function f({ id, type = 'x' }) {}       // 参数解构

五、对象字面量增强

  • 属性简写、方法简写、计算属性名、__proto__ 设置。
const x = 1;
const o = {
  x,                       // 等同于 x: x
  say() {},                // 方法简写
  ['key' + 1]: 100,        // 计算属性名 → key1
};

六、类 class

  • 语法糖,本质仍是原型继承;支持  constructor extends、 super、  静态方法 static、getter/setter。
class Animal {
  constructor(name) { this.name = name; }
  speak() { return `${this.name} makes sound`; }
}
class Dog extends Animal {
  speak() { return `${this.name} barks`; }
}

七、模块 import / export

  • 真正的静态模块系统(区别于 CommonJS 的运行时加载)。
export const x = 1;
export default function() {}
import { x } from './mod.js';
import def, { x } from './mod.js';

八、Promise

  • 异步编程的一等公民,解决回调地狱。
new Promise((resolve, reject) => { 
        /* ... */
     }).then(r => { 
        /* ... */
     }
    ).catch(e => { 
        /* ... */
     });

九、迭代器与 for...of

  • 任何实现了 [Symbol.iterator] 的对象都可被 for...of 遍历(Array、Set、Map、String、arguments、NodeList…)。
for (const v of arr) { 
    /* ... */ 
}

十、生成器 Generator

  • function* + yield,可暂停/恢复执行;也是异步流程(co 库)和迭代器工厂的基础。
function* gen() {
  yield 1; yield 2;
}
const g = gen(); g.next(); // {value:1, done:false}

十一、Symbol

  • 新增的第七种原始类型,用作唯一键值,避免属性名冲突;内置了许多 well-known symbols(Symbol.iteratorSymbol.toStringTag 等)。
const key = Symbol('desc');
const obj = { [key]: 'hidden' };

十二、新数据结构

  • Map(键值对任意类型)、Set(去重)、WeakMap / WeakSet(弱引用,键只能是对象,不可遍历)。
const m = new Map();
 m.set(obj, 1); 
m.get(obj);
const s = new Set([1, 1, 2]); 
// {1, 2}

十三、Proxy 与 Reflect

  • Proxy:拦截/自定义对象的基础操作(get/set/apply/construct…)。
  • Reflect:与 Proxy 钩子一一对应的静态方法集合,规范了对对象的内省操作。
const p = new Proxy(target, {
  get(t, k) { 
    return k in t ? t[k] : 'default';
 }
});

十四、内置对象新增方法(ES6 引入)

  • Array:  Array.from、  Array.offind、  findIndex、  fillcopyWithin、 keys、 valuesentries
  • String: includes、 startsWithendsWithrepeatcodePointAtnormalizeString.fromCodePoint
  • NumberNumber.isFiniteNumber.isNaNNumber.isIntegerNumber.parseIntNumber.parseFloatNumber.EPSILONNumber.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER
  • MathMath.signMath.truncMath.cbrtMath.hypotMath.log2Math.log10Math.imulMath.clz32Math.expm1Math.log1pMath.cosh… 双曲函数族
  • ObjectObject.assignObject.isObject.setPrototypeOfObject.getPrototypeOfObject.getOwnPropertySymbolsObject.preventExtensions 等规范化
[1, 2, 3].find(n => n > 1);   // 2
'hello'.includes('ell');      // true
Object.assign({}, a, b);       // 浅合并

十五、字面量语法扩展

  • 二进制 0b101 与八进制 0o17 字面量(旧八进制 010 已废弃)。

十六、正则表达式增强

  • u 标志(Unicode 模式,正确处理码点)、y 标志(粘连 sticky)、实例 .flags 属性、RegExp.prototype.unicode/sticky

十七、其它机制

  • 尾调用优化(TCO) :严格模式下尾递归不新增栈帧(仅少数引擎实现)。
  • new.target:检测函数是否通过 new 调用。
  • 函数名推导:匿名函数表达式会推断 name

ES2016(ES7)

  • 求幂运算符 ** 与 **=(语法)

    2 ** 3;        // 8
    x **= 2;
    

  • Array.prototype.includes(含 NaN 判断)

ES2017(ES8)

  • async / await(语法)

    async function f() { 
        const r = await fetch(url); 
    }
    

  • 函数参数与调用允许多余的尾随逗号(语法)

    function g(a, b,) {
    
    }
    

  • Object.values / Object.entries / Object.getOwnPropertyDescriptors

  • 字符串填充 padStart / padEnd

  • SharedArrayBuffer 与 Atomics

ES2018(ES9)

  • 异步迭代for await...of 与异步生成器 async function*(语法)

    for await (const x of asyncIterable) {}
    

  • 对象 rest / spread(语法)

    const { a, ...rest } = obj;
    const c = { ...a, ...b };
    

  • Promise.prototype.finally

  • 正则增强(语法):具名捕获组 (?<name>)后行断言 (?<=)、点匹配所有 s(dotAll)标志、Unicode 属性转义 \p{...}

    const { groups: { year } } = /(?<year>\d{4})/.exec(s);
    

ES2019(ES10)

  • 数组 flat / flatMap

  • Object.fromEntries(与 entries 互逆)

  • 字符串 trimStart / trimEnd

  • 可选 catch 绑定catch {} 可省略参数(语法)

    try {
         /* ... */
     } catch {
         /* 不需要 e */
     }
    

  • Symbol.prototype.description

  • JSON 超集(允许行分隔符 U+2028/2029)与 JSON.stringify 保形输出

ES2020(ES11)

  • 可选链 ?. (语法)

    user?.address?.city;
    

  • 空值合并 ?? (语法,只在 null/undefined 时生效)

    const v = input ?? 'default';
    

  • BigInt 与字面量 123n(语法)

  • 动态 import() (语法,返回 Promise)

  • globalThisimport.meta

  • export * as ns from '...'(聚合导出,语法)

  • Promise.allSettledString.prototype.matchAll

ES2021(ES12)

  • 逻辑赋值运算符 &&= / ||= / ??=(语法)

    obj.x ??= defaultValue;
    

  • 数字分隔符 1_000_000(语法,仅可读性)

  • String.prototype.replaceAll

  • Promise.any(任意一个成功即 resolve)

  • WeakRef 与 FinalizationRegistry

  • Array.prototype.sort 改为稳定排序

ES2022(ES13)

  • 顶层 await(模块顶层可直接 await,语法)

  • 类字段全面落地(语法):

    • 公共实例字段、私有字段 #x、私有方法 #m()
    • 静态字段 / 静态私有成员
    • 静态初始化块 static {}
    class C {
      #secret = 1;
      static #cnt = 0;
      static { this.init(); }
      #helper() {}
    }
    

  • 索引方法 .at()(Array / String / TypedArray,支持负索引 -1

  • Object.hasOwn(替代 hasOwnProperty.call

  • Error.prototype.cause(错误链路)

  • 正则匹配索引 d 标志

ES2023(ES14)

  • Array.prototype.findLast / findLastIndex

  • 不改原数组的数组副本方法(语法/API):toSortedtoReversedtoSplicedwith

    const sorted = arr.toSorted((a, b) => a - b); // 原数组不变
    const replaced = arr.with(0, 99);
    

  • 脚本文件头 Hashbang #!/usr/bin/env node 语法合法化

  • TypedArray 对应的 findLast / with / toSorted 等副本方法

ES2024(ES15,最新)

  • Array.fromAsync(异步可迭代 → 数组)

  • Set 集合运算方法(语法/API):unionintersectiondifferencesymmetricDifferenceisSubsetOfisSupersetOfisDisjointFrom

  • 分组方法Object.groupBy(返回对象)、Map.groupBy(返回 Map)

    const byAge = Object.groupBy(users, u => u.age > 18 ? 'adult' : 'minor');
    

  • Promise.withResolvers(直接拿到 resolve/reject

  • 正则 v 标志(unicodeSets,增强字符类集合运算)

  • ArrayBuffer.prototype.resize / transferSharedArrayBuffer 的 transfer(缓冲区可转移/扩容)


 

速查:哪些是“语法”、哪些是“API”

类别典型例子
纯语法(写法变化)let/const=>**、?.??、模板字符串、解构、class 字段/#、rest/spread、async/awaitfor await、动态 import()`、数字分隔符、逻辑赋值、尾随逗号、可选 catch
内置 APIPromise.*Array.includes/findLast/flat/toSortedObject.entries/groupBySet 集合方法、BigIntWeakRefReflectglobalThis

建议记忆锚点:ES6 打地基,ES2017 给 async,ES2020 给 ?./??,ES2022 给类字段与顶层 await,ES2024 给 Set 集合运算与 groupBy。