Skip to main content

ECMAScript Version

VersionOfficial NameDateDescription
JavaScript 1.01995by Brendan Eich
ES1ECMAScript 11997ECMA-262
ES2ECMAScript 21998
ES3ECMAScript 31999
ES4ECMAScript 4未发布
ES5ECMAScript 52009
ES6ECMAScript 20152015
ECMAScript 20162016
ECMAScript 20172017
ECMAScript 20182018
ECMAScript 20192019
ECMAScript 20202020
ECMAScript 20212021
ECMAScript 20222022
ECMAScript 20232023
ES.Next下一个版本
tip
  • 今年采纳的建议,发布到下一年版本,因此会相差一年版本号
stagefornote
stage 0Strawperson
stage 1Proposal
stage 2Draft描述准确
stage 3Candidate实现,等待用户使用反馈
stage 4Finished准备添加到 标准
👀
syntaxChromeName
?.Chrome80Optional chaining
??Chrome80Nullish coalescing operator
??=Chrome85Nullish coalescing assignment

ECMAScript 2023

  • findLast, findLastIndex
    • {Array, %TypedArray%}.prototype.findLastIndex
    • {Array, %TypedArray%}.prototype.findLast
  • Hashbang Grammar - JS 直接只为可执行脚本
#!/usr/bin/env node

ECMAScript 2022

// Class Fields
class Counter extends HTMLElement {
// 私有
#val = 0;

get #x() { return #val; }
set #x(value) {
this.#val = value;
}

#inc() {
this.#val ++
}

// 静态
static #blue = "#0000ff";
static getBlue() {
return this.#blue
}
}

// regex 索引
// d -> indices
/a+(?<Z>z)?/d.exec('xaaaz').indices

// Top-level await
await Promise.resolve()

// static block
class C {
static {
// statements
}
}

// error cause
try {
throw new Error('error', { cause: err });
} catch (e) {
console.log('Caused by', e.cause);
}

// Array#at
[,-1].at(-1)

ECMAScript 2021

  • FinalizationRegistry
    • 注册 GC 回调
String.prototype.replaceAll;

Promise.any;

// WeakRef.prototype.deref
new WeakRef(() => 1);

// Logical Assignment Operators
a ||= b;
a &&= b;
a ??= b;

// Numeric separators
1_000_000_000;

ECMAScript 2020

// String.prototype.matchAll
// 要求 RegEx 必须有 g 标识
'aa'.matchAll(/a/g);

// 动态 import
import('./foo.js');

// 模块元信息
import.meta;

BigInt;

// Promise.all 会在第一个异常时终止
Promise.allSettled;

globalThis;

// Optional Chaining
undefined?.b;

// Nullish coalescing Operator
undefined ?? null ?? 0 ?? 1;

ECMAScript 2019

  • JSON superset
    • U+2028 LINE SEPARATOR, U+2029 PARAGRAPH SEPARATOR
  • Function.prototype.toString revision
  • Well-formed JSON.stringify
    • 避免返回错误 Unicode escape
// Optional catch binding
try {
} catch {}

Symbol.prototype.description;

Object.fromEntries([['k', 'v']]);

// String.prototype.{trimStart,trimEnd}
' 1 '.trimStart().trimEnd();

String.prototype.matchAll;

// Array.prototype.{flat,flatMap}
[[1], [2]].flat();
[0, 0].flatMap((_, i) => [1]);

ECMAScript 2018

// Regex Named Group
/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u.exec('2015-01-02')
// Regex s -> dot all, single line
/foo.bar/s.test('foo\nbar');
// Regex Lookbehind Assertions
/(?<=\D)\d/
/(?<!\D)\d/
// Regex Unicode Property Escapes
// \p{UnicodePropertyName=UnicodePropertyValue}
// General_Category, Script, Script_Extensions
//
// \p{LoneUnicodePropertyNameOrValue}
// Alphabetic, Uppercase, Lowercase, White_Space, Noncharacter_Code_Point, Default_Ignorable_Code_Point, Any, ASCII, Assigned, ID_Start, ID_Continue, Join_Control, Emoji_Presentation, Emoji_Modifier, Emoji_Modifier_Base
//
// http://unicode.org/Public/UNIDATA/PropertyValueAliases.txt
// http://unicode.org/Public/UNIDATA/PropertyAliases.txt
// http://unicode.org/reports/tr18/#RL1.2
/^\p{Decimal_Number}+$/u.test('𝟏𝟐𝟑𝟜𝟝𝟞𝟩𝟪𝟫𝟬𝟭𝟮𝟯𝟺𝟻𝟼')

// Object Rest/Spread
const {a,...rest} = {a:1,b:2,...{c:3}}

// Promise#finally
Promise.prototype.finally;

// Asynchronous Iteration
// [Symbol.asyncIterator]
for await (const line of readLines()) {
console.log(line);
}
async function* readLines(){
yield await Promise.resolve('Line 1')
yield 'Line 2'
}

ECMAScript 2017

Object.values;
Object.entries;

'1'.padEnd(4, ' ');
'1'.padStart(4, ' ');

Object.getOwnPropertyDescriptors;

// 方法参数容许多余逗号
console.log(true);

// async,await
async function run() {
await Promise.resolve();
}

ECMAScript 2016

Array.prototype.includes;

// Exponentiation
1 ** 2; // Math.pow(1,2)

ECMAScript 2015

// array function
() => 1;

// let, const
let a = 1;
const b = 1;

// for-of
for (const v of [1]);

// Map, Set
new Map();
new Set();

// Symbol
const mySym = new Symbol();

// class
class Car {
constructor() {}
}

// promise
Promise.resolve();

// 默认参数, rest 参数
function hello(name = 'world', ...props) {}

const { a, b } = { a: 1, b: 2 };

String.prototype.includes;
String.prototype.startsWith;
String.prototype.endsWith;

Array.from('abc');
[(1, 2)].keys();
[(1, 2)].find((v) => v == 1);
[(1, 2)].findIndex((v) => v == 1);

Math.trunc;
Math.sign;
Math.cbrt;
Math.log2;
Math.log10;

Number.isInteger;
Number.isSafeInteger;

isFinite(1 / 0);
isNaN(false);

ECMAScript 5

'use strict';

'Hello'.charAt(0);
'Hello'[0];

// 多行 string
console.log(
'Hello \
Wener!',
);

// 允许关键字作为属性名
const a = { new: 'yes' };

String.prototype.trim;

Array.isArray([]);
Array.prototype.forEach;
Array.prototype.map;
Array.prototype.filter;
Array.prototype.reduce;
Array.prototype.reduceRight;
Array.prototype.every;
Array.prototype.some;
Array.prototype.indexOf;
Array.prototype.lastIndexOf;

JSON.parse('{}');
JSON.stringify({});

Date.now();
Date.prototype.toISOString;
Date.prototype.toJSON;

// getter,setter
const a = {
get name() {
return '';
},
set name(v) {
console.log(v);
},
};

// mgmt
Object.create;
Object.defineProperty;
Object.defineProperties;
Object.getOwnPropertyDescriptor;
Object.getOwnPropertyNames;
Object.getPrototypeOf;
Object.keys;
// protect
Object.preventExtensions;
Object.isExtensible;
Object.seal;
Object.isSealed;
Object.freeze;
Object.isFrozen;

// 允许多余逗号
// {a:1,}
// [1,]