ECMAScript特性全面解读(从ES3到ES2024)
1. ECMAScript 3 (ES3) - 1999年
ES3是第一个正式发布的版本,主要对JavaScript的核心语法和功能进行了规范化,增强了语言的稳定性和扩展性。
特性
- 正则表达式支持: 在ES3中,JavaScript引入了对正则表达式的支持。
示例
javascript
// 使用正则表达式匹配字符串
const str = "Hello, world!";
const regex = /world/;
console.log(regex.test(str)); // 输出 true
- 异常处理 : ES3引入了
try...catch
结构用于错误处理。
javascript
try {
throw new Error("Something went wrong!");
} catch (e) {
console.error(e.message); // 输出 Something went wrong!
}
2. ECMAScript 5 (ES5) - 2009年
ES5对JavaScript进行了重要的增强,引入了严格模式、数组和对象的方法、JSON支持等。
特性
- 严格模式(Strict Mode) :
strict mode
使得JavaScript运行更加严格,避免了一些潜在的错误。
javascript
"use strict";
x = 10; // 会抛出错误,x未定义
Object.defineProperty()
: 允许在对象上精细控制属性的定义,如是否可写、可枚举等。
javascript
const obj = {};
Object.defineProperty(obj, 'name', {
value: 'Alice',
writable: false
});
console.log(obj.name); // 输出 'Alice'
obj.name = 'Bob'; // 无法修改,因为属性不可写
console.log(obj.name); // 输出 'Alice'
Array.prototype.forEach()
、map()
、filter()
等方法: ES5为数组引入了很多常用的高阶方法。
javascript
const arr = [1, 2, 3];
arr.forEach((num) => console.log(num)); // 输出 1, 2, 3
const doubled = arr.map(num => num * 2);
console.log(doubled); // 输出 [2, 4, 6]
const even = arr.filter(num => num % 2 === 0);
console.log(even); // 输出 [2]
3. ECMAScript 6 (ES6 / ES2015) - 2015年
ES6是JavaScript的一个重大版本,包含了很多新特性,大大提高了语言的功能性与简洁性。
特性
let
和const
: 新的变量声明方式,提供了块级作用域。
javascript
let x = 10;
const y = 20;
x = 15; // 可以修改
// y = 25; // 会报错,因为const不能修改
- 箭头函数 : 简化了函数的书写,并且
this
绑定方式不同于传统函数。
javascript
const add = (a, b) => a + b;
console.log(add(2, 3)); // 输出 5
- 类(class): 引入了类的概念,简化了面向对象编程的方式。
javascript
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
const person = new Person('Alice', 25);
person.greet(); // 输出 Hello, my name is Alice and I am 25 years old.
- 模板字符串: 可以更方便地进行字符串拼接和多行字符串。
javascript
const name = 'Alice';
const message = `Hello, ${name}!`;
console.log(message); // 输出 Hello, Alice!
- 解构赋值: 支持从数组或对象中提取值,简化了代码。
javascript
const [a, b] = [1, 2];
console.log(a, b); // 输出 1 2
const person = { name: 'Alice', age: 25 };
const { name, age } = person;
console.log(name, age); // 输出 Alice 25
- 模块化 : 引入了
import
和export
语法,支持模块化编程。
javascript
// file1.js
export const greeting = 'Hello, world!';
// file2.js
import { greeting } from './file1';
console.log(greeting); // 输出 Hello, world!
Promise
: 用于处理异步操作,使得异步代码更易于理解。
javascript
const promise = new Promise((resolve, reject) => {
const success = true;
if (success) {
resolve('Operation successful!');
} else {
reject('Operation failed.');
}
});
promise
.then(result => console.log(result)) // 输出 Operation successful!
.catch(error => console.log(error));
4. ECMAScript 7 (ES7 / ES2016) - 2016年
ES7引入了相对较少的新特性,但仍有一些有用的增强。
特性
Array.prototype.includes()
: 检查数组是否包含某个值。
javascript
const arr = [1, 2, 3, 4];
console.log(arr.includes(3)); // 输出 true
console.log(arr.includes(5)); // 输出 false
- 指数运算符(
\**
): 用于计算幂。
javascript
console.log(2 ** 3); // 输出 8
5. ECMAScript 8 (ES8 / ES2017) - 2017年
ES8引入了几个重要的新功能,特别是在异步编程方面的增强。
特性
async/await
: 使得异步编程更简洁和直观。
javascript
async function fetchData() {
let response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
let data = await response.json();
console.log(data);
}
fetchData();
Object.entries()
和Object.values()
: 返回对象的键值对数组或值数组。
javascript
const obj = { a: 1, b: 2 };
console.log(Object.entries(obj)); // 输出 [['a', 1], ['b', 2]]
console.log(Object.values(obj)); // 输出 [1, 2]
String.prototype.padStart()
和String.prototype.padEnd()
: 在字符串的开头或结尾填充指定字符,直到达到指定长度。
javascript
const str = '5';
console.log(str.padStart(3, '0')); // 输出 '005'
console.log(str.padEnd(3, '0')); // 输出 '500'
6. ECMAScript 9 (ES9 / ES2018) - 2018年
ES9增强了正则表达式、异步编程和数组操作等方面。
特性
- 异步迭代器: 支持异步操作中的迭代。
javascript
async function* generateNumbers() {
yield 1;
yield 2;
yield 3;
}
(async () => {
for await (const num of generateNumbers()) {
console.log(num); // 输出 1, 2, 3
}
})();
Object.fromEntries()
: 用于将键值对数组转为对象。
javascript
const entries = [['name', 'Alice'], ['age', 25]];
const obj = Object.fromEntries(entries);
console.log(obj); // 输出 { name: 'Alice', age: 25 }
7. ECMAScript 10 (ES10 / ES2019) - 2019年
ES10引入了一些实用的新功能,特别是对于数组和字符串的操作。
特性
Array.prototype.flat()
和flatMap()
: 用于将嵌套数组"拉平",或映射并扁平化。
javascript
const arr = [1, [2, [3, [4]]]];
console.log(arr.flat(2)); // 输出 [1, 2, 3, [4]]
const mapped = arr.flatMap(x => [x, x * 2]);
console.log(mapped); // 输出 [1, 2, 2, 4, 3, 6]
String.prototype.matchAll()
: 返回正则表达式匹配的所有结果。
javascript
const str = 'a1b2c3';
const regex = /\d/g;
const matches = str.match
All(regex);
for (const match of matches) {
console.log(match); // 输出 ["1", index: 1, input: "a1b2c3"]
}
8. ECMAScript 11 (ES11 / ES2020) - 2020年
ES11引入了对大整数(BigInt
)和全局对象(globalThis
)的支持。
特性
BigInt
: 用于处理超出Number
范围的整数。
javascript
const bigInt = 1234567890123456789012345678901234567890n;
console.log(bigInt + 1n); // 输出 1234567890123456789012345678901234567891n
globalThis
: 标准化访问全局对象。
javascript
console.log(globalThis); // 输出全局对象
9. ECMAScript 12 (ES12 / ES2021) - 2021年
ES12引入了一些小而有用的特性,主要集中在语法增强和新方法。
特性
-
逻辑赋值运算符 (
&&=
,||=
,??=
)ES12引入了逻辑赋值运算符,简化了条件赋值的代码书写。
javascript
let x = 1;
x &&= 2; // 如果 x 为真,则 x = 2
console.log(x); // 输出 2
let y = null;
y ||= 3; // 如果 y 为假,则 y = 3
console.log(y); // 输出 3
let z;
z ??= 4; // 如果 z 为 null 或 undefined,则 z = 4
console.log(z); // 输出 4
-
数字分隔符(Numeric Separators)
数字分隔符使用
_
使长数字更易读。
javascript
const billion = 1_000_000_000;
console.log(billion); // 输出 1000000000
-
Promise.any()
返回第一个成功的
Promise
,如果所有Promise
都失败,则返回一个包含所有错误的AggregateError
。
javascript
const promises = [
Promise.reject('Error 1'),
Promise.resolve('Success 1'),
Promise.resolve('Success 2'),
];
Promise.any(promises).then(result => {
console.log(result); // 输出 "Success 1"
}).catch(error => {
console.error(error); // 如果全部失败,输出 AggregateError
});
-
WeakRefs
和FinalizationRegistry
提供了一种引用弱对象的方式,避免内存泄漏。
javascript
let obj = { name: 'Alice' };
const weakRef = new WeakRef(obj);
console.log(weakRef.deref()); // 输出 { name: 'Alice' }
obj = null; // 引用被删除
console.log(weakRef.deref()); // 输出 undefined
10. ECMAScript 13 (ES13 / ES2022) - 2022年
ES13增强了异步和类的功能,优化了数组的操作。
特性
-
顶级
await
允许在模块的顶层直接使用
await
,无需放在异步函数中。
javascript
const data = await fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json());
console.log(data);
-
类字段声明
ES13允许在类中直接声明字段,而无需放在构造函数中。
javascript
class Person {
name = 'Alice'; // 类字段
age = 25;
greet() {
console.log(`Hello, my name is ${this.name}.`);
}
}
const person = new Person();
console.log(person.name); // 输出 "Alice"
-
Error.cause
为
Error
对象添加了cause
属性,便于追踪错误来源。
javascript
try {
throw new Error('Main error', { cause: 'Invalid input' });
} catch (e) {
console.log(e.message); // 输出 "Main error"
console.log(e.cause); // 输出 "Invalid input"
}
11. ECMAScript 14 (ES14 / ES2023) - 2023年
ES14引入了一些针对数组和排序操作的优化。
特性
-
Array.prototype.at()
支持使用负索引从数组末尾访问元素。
javascript
const arr = [10, 20, 30, 40];
console.log(arr.at(-1)); // 输出 40
console.log(arr.at(-2)); // 输出 30
-
数组查找方法:
findLast()
和findLastIndex()
从数组的末尾开始查找满足条件的元素或索引。
javascript
const arr = [1, 2, 3, 4];
console.log(arr.findLast(x => x % 2 === 0)); // 输出 4
console.log(arr.findLastIndex(x => x % 2 === 0)); // 输出 3
-
优化的
Array.prototype.sort()
避免了原数组被修改的问题(如果浏览器支持此特性)。
javascript
const arr = [3, 1, 4];
const sorted = arr.sort((a, b) => a - b);
console.log(arr); // 原数组仍可能被修改(特性正在优化)
console.log(sorted); // 输出排序后的数组
12. ECMAScript 15 (ES2024) - 2024年
ES15进一步增强了语言功能,引入了更多现代化特性。
特性
-
类装饰器(Decorators)
允许为类和类的成员添加装饰器,用于修改行为。
javascript
function log(target, name, descriptor) {
const original = descriptor.value;
descriptor.value = function (...args) {
console.log(`Calling ${name} with`, args);
return original.apply(this, args);
};
return descriptor;
}
class Calculator {
@log
add(a, b) {
return a + b;
}
}
const calc = new Calculator();
console.log(calc.add(2, 3)); // 输出日志,并返回 5
-
异步可迭代增强
改进了异步迭代器,使其更易用。
javascript
async function* generate() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
yield await Promise.resolve(3);
}
for await (const value of generate()) {
console.log(value); // 输出 1, 2, 3
}
-
数组分组方法:
group()
和groupToMap()
根据指定规则将数组元素分组。
javascript
const arr = ['apple', 'banana', 'cherry', 'date'];
const grouped = arr.group(item => item.length);
console.log(grouped);
// 输出 { 5: ['apple'], 6: ['banana', 'cherry'], 4: ['date'] }
总结
从ES3到ES2024,ECMAScript经历了从基础语法优化到现代语言功能的全面进化。以下是每个版本的亮点回顾:
- ES3(1999):正则表达式、异常处理。
- ES5(2009):严格模式、JSON支持、数组方法。
- ES6(2015):模块化、类、Promise、箭头函数。
- ES7 (2016):
includes()
、指数运算符。 - ES8 (2017):
async/await
、Object.entries()
。 - ES9 (2018):异步迭代器、
flat()
。 - ES10 (2019):
Object.fromEntries()
、matchAll()
。 - ES11 (2020):
BigInt
、globalThis
。 - ES12 (2021):逻辑赋值运算符、
Promise.any()
。 - ES13 (2022):顶级
await
、类字段。 - ES14 (2023):
findLast()
、at()
。 - ES15(2024):类装饰器、分组方法。
以上内容覆盖了每个版本的重要特性和代码示例,便于全面理解ECMAScript的进化历程。如果需要更深入的某一部分特性解析,可以随时提问!如果有哪里解释的不到位, 也欢迎各位大神指正