ES6到ES14的新特性一覽表
你好,我的前端朋友们,今天, 我将整理所有从ES6到最新的ES15版本中引入的ECMAScript特性。
我们开始吧...
特性 | 描述 |
---|---|
let, const | 块级作用域的变量声明 |
箭头函数 | 函数的简写语法 |
模板字面量 | 字符串插值 |
带有默认值的参数 | 带有默认值的参数 |
数组和对象的解包 | 数组和对象的解包 |
扩展运算符/剩余参数 | 用于数组/对象的 ... 操作符 |
简写属性和方法 | 属性和方法的简写 |
类 | 面向对象编程语法 |
模块(导入/导出) | 模块化代码结构 |
Promise | 异步操作处理 |
唯一符号 | 唯一符号 |
新的集合数据结构 | 新的集合数据结构 |
生成器 | 可产生多个结果的函数 |
for...of 循环 | 遍历可迭代对象的循环 |
弱引用的集合 | 弱引用的集合 |
// #1 - let 和 const 示例
let user = "Mysterio";
const userId = 1908894;
if (true) {
let user = "Batman";
console.log(user); // Batman (块级作用域)
}
console.log(user); // Mysterio
// #2 - 箭头函数
const fullname = (firstname, lastname) => firstname + " " +lastname;
console.log(fullname("Clark", "Kent")); // Clark Kent
// #3 - 模板字符串
const fullnameWithTemplate = (firstname, lastname) => `${firstname} ${lastname}`;
console.log(fullnameWithTemplate("Clark", "Kent")); // Clark Kent
// #4 - 默认参数
const fullnameWithDefaultParams = (firstname="Bruce", lastname="Wayne") => `${firstname} ${lastname}`;
console.log(fullnameWithDefaultParams()); // Bruce Wayne
// #5 - 解构
// 数组解构
const [uid, uname] = [1, "Batman"];
console.log(uid, uname); // 1 Batman
// 对象解构
const response = { id: 1, username: "Batman", email: "[email protected]" };
const { id, username, email } = response;
console.log(id, username, email); // 1 Batman [email protected]
// #6 - 扩展运算符和剩余运算符 (...)
// 扩展运算符
const numbers = [1, 2, 3, 4, 5];
const [first, ...rest] = numbers;
console.log(first, rest); // 1 [2, 3, 4, 5]
// 剩余运算符
const floatingNumber = [1.1, 2.2, 3.3, 4.4, 5.5];
const floatingAndDecimal = [...floatingNumber, ...numbers];
console.log(floatingAndDecimal); // [1.1, 2.2, 3.3, 4.4, 5.5, 1, 2, 3, 4, 5]
// #7 - 简写对象字面量
const newUser = {
id,
username,
email
}
console.log(newUser) // { id: 1, username: 'Batman', email: '[email protected]' }
// #8 - 类 - 原型语法糖
class SuperHero {
constructor(heroname) {
this.heroname = heroname;
}
speak() {
console.log(`${this.heroname} 已经赢得战斗。`);
}
}
class Human extends SuperHero {
isHuman() {
console.log(`${this.heroname} 也是一个普通人。`);
}
}
const humanSuperhero = new Human('Batman');
humanSuperhero.isHuman(); // Batman 也是一个普通人
// #9 - 导入和导出模块
// superhero.js
export const superhero = heroname => `我是,${heroname}`;
// index.js
import { superhero } from './superhero.js';
console.log(superhero('Batman')); // 我是,Batman
// #10 - Promise
const fetchData = () =>
new Promise((resolve) => {
setTimeout(() => resolve("这个Promise将在一秒钟后解决"), 1000);
});
fetchData()
.then(console.log) // 这个Promise将在一秒钟后解决
.catch(console.error); // 不会运行,因为Promise已经解决而没有被拒绝
// #11 - Symbol
const doomsday1 = Symbol("末日");
const doomsday2 = Symbol("末日");
console.log(doomsday1 === doomsday2); // false (唯一的符号)
// #12 - Map 和 Set
// Map
const superHeroMap = new Map();
superHeroMap.set("名称", "Barry Allen");
superHeroMap.set("年龄", 30);
console.log(superHeroMap.get("名称")); // Barry Allen
console.log(superHeroMap.get("年龄")); // 30
// Set
const superHeroSet = new Set(["Batman", "Superman", "Wonder Woman","Flash"]);
console.log(superHeroSet); // Set(4) { 'Batman', 'Superman', 'Wonder Woman', 'Flash' }
superHeroSet.add("Aquaman");
console.log(superHeroSet); // Set(5) { 'Batman', 'Superman', 'Wonder Woman', 'Flash', 'Aquaman' }
superHeroSet.delete("Superman");
console.log(superHeroSet) // Set(4) { 'Batman', 'Wonder Woman', 'Flash', 'Aquaman' }
console.log(superHeroSet.has("蝙蝠侠")); // true
// #13 - 迭代器和生成器
const superHeroIterators = ["Batman", "Superman", "Wonder Woman", "Flash"];
const iterator = superHeroIterators[Symbol.iterator]();
console.log(iterator.next()); // { value: 'Batman', done: false }
console.log(iterator.next()); // { value: 'Superman', done: false }
console.log(iterator.next()); // { value: 'Wonder Woman', done: false }
console.log(iterator.next()); // { value: 'Flash', done: false }
function* generateSuperHeroes() {
yield "Batman";
yield "Superman";
yield "Wonder Woman";
}
const generator = generateSuperHeroes();
console.log(generator.next().value); // 生成器生成了Batman
// #14 for...of 循环
for (const 超级英雄 of superHeroIterators) {
console.log(超级英雄);
} // Batman Superman Wonder Woman Flash
全屏显示,退出全屏
ES7 特性特征 | 描述 |
---|---|
Array.prototype.includes | 检查数组中是否包含特定值 |
指数运算符 ** |
简写幂运算表达式 |
示例代码
// #1 - Array.prototype.includes()
const superheroes = ["Batman", "Superman", "Flash"];
if (superheroes.includes("Batman")) {
console.log("蝙蝠侠布鲁斯·韦恩!");
} // 将会打印 - 蝙蝠侠布鲁斯·韦恩!
// #2 指数运算符
const powerMethod = Math.pow(17, 3);
const exponentiationOperator = 17 ** 3;
console.log(powerMethod) // 4913
console.log(exponentiationOperator) // 4913
全屏显示 退出全屏
ES8 特点特性 | 描述 |
---|---|
async/await | 更简单的异步编程语法 |
Object.values() | 返回对象的属性值作为数组 |
Object.entries() | 返回对象的键值对作为数组 |
Object.getOwnPropertyDescriptors() | 获取对象的所有属性 |
Trailing Commas in Functions | 支持在函数参数和调用中使用尾随逗号 |
SharedArrayBuffer & Atomics | 支持线程间的共享内存和原子操作 |
// #1 - 异步/await - 用于Promise的语法糖衣
const fetchData = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('错误信息:', error);
}
};
fetchData();
// {
// userId: 1,
// id: 1,
// title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
// body: 'quia et suscipit\n' +
// 'suscipit recusandae consequuntur expedita et cum\n' +
// 'reprehenderit molestiae ut ut quas totam\n' +
// 'nostrum rerum est autem sunt rem eveniet architecto'
// }
// #2 - Object.values() - 返回一个给定对象自身可枚举属性值的数组。
const superhero = { id: 9089, name: 'Batman', age: 32 };
console.log(Object.values(superhero)); // [9089, 'Batman', 32]
// #3 - Object.entries() - 返回给定对象自身可枚举属性的键值对数组。
console.log(Object.entries(superhero)); // [ [ 'id', 9089 ], [ 'name', 'Batman' ], [ 'age', 32 ] ]
// #4 - Object.getOwnPropertyDescriptors() - 返回对象所有属性的描述符。
console.log(Object.getOwnPropertyDescriptors(superhero));
/*
{
id: { value: 9089, writable: true, enumerable: true, configurable: true },
name: {
value: 'Batman',
writable: true,
enumerable: true,
configurable: true
},
age: { value: 32, writable: true, enumerable: true, configurable: true }
}
*/
切换到全屏,切换回正常模式
这里没给最后两个示例代码,因为这些代码很少用,或者只在高级编程里出现。
ES9 的特点:特性 | 描述 |
---|---|
使用对象的 Rest/Spread | 用于克隆和合并对象的 ... 语法 |
for await...of 循环 | 流或异步可迭代对象的异步迭代 |
Promise.prototype.finally() | 在 promise 解决或拒绝时执行的代码 |
正则表达式:s 标志(dotAll) | . 在正则表达式中匹配换行符 |
正则表达式:命名捕获组 | 为捕获组添加名称,使理解更清晰 |
示例代码
// #1 - 对象的 Rest/Spread 属性
const superhero = { id: 9810, name: 'Superman', age: 35 };
const { age, ...rest } = superhero;
console.log(rest); // { id: 9810, name: 'Superman' }
const updateSuperHero = { ...superhero, powers: ["flying", "super strength","heat vision"] };
console.log(updateSuperHero) // { id: 9810, name: 'Superman', age: 35, powers: [ 'flying', 'super strength', 'heat vision' ]}
// #2 - 使用 (for await...of) 循环进行异步迭代
async function fetchPosts() {
const urls = ['https://jsonplaceholder.typicode.com/posts/1', 'https://jsonplaceholder.typicode.com/posts/2'];
for await (const url of urls) {
const response = await fetch(url);
const post = await response.json();
console.log(post.title);
}
}
fetchPosts();
// sunt aut facere repellat provident occaecati excepturi optio reprehenderit
// qui est esse
// #3 - Promise.prototype.finally() - 执行一个回调,当 promise 结束(不论是成功还是失败)后调用。
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
.then(data => console.log(data.userId))
.catch(error => console.error('Error:', error))
.finally(() => console.log('请求完成'));
// 1
// 请求完成
// #4 - 正则表达式改进
const regex = /bruce\.wayne/s; // 允许 . 匹配换行符 (\n)。
console.log(regex.test('bruce.wayne')); // true
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; // 使用命名组提高正则表达式的可读性。
const match = dateRegex.exec('2025-02-17');
console.log(match.groups); // { year: '2025', month: '02', day: '17' }
console.log(match.groups.year); // '2025'
全屏模式(进入/退出)
ES10 的特性特性 | 描述 |
---|---|
Array.prototype.flat() | 扁平化嵌套数组 |
Array.prototype.flatMap() | 一步映射并扁平化数组 |
Object.fromEntries() | 将键值对转换为对象 |
String.prototype.trimStart()/trimEnd() | 截取字符串开头或结尾的空格 |
可选的 catch 参数 | catch 不带错误参数 |
Symbol.description | 获取符号描述 |
Function.prototype.toString() | 返回确切的源代码 |
妥善处理 Unicode 字符的 JSON.stringify() | 正确处理 Unicode 字符 |
BigInt (Stage 3) | 支持大整数 |
示例
// #1 flat 和 flatMap 方法用于数组
const nestedNumbers = [1, [2, [3, [4]]]];
console.log(nestedNumbers.flat()); // 一次展平 [1, 2, [3, [4]]]
console.log(nestedNumbers.flat(2)); // 两次展平 [1, 2, 3, [4]]
console.log(nestedNumbers.flat(Infinity)); // 无限次展平 [1, 2, 3, 4]
// 结合 map() 和 flat() 的一种方法。
console.log(nestedNumbers.flat(Infinity).flatMap(x => [x, x * 2])); // [1, 2, 2, 4, 3, 6, 4, 8]
// #2 - Object.fromEntries()
const superHeroArray = [['name', 'Bruce'], ['age', 32]];
const superHeroObject = Object.fromEntries(superHeroArray);
console.log(superHeroObject); // { name: 'Bruce', age: 32 }
// #3 - trimStart 和 trimEnd
const trimmedSuperHero = ' Superman ';
console.log(trimmedSuperHero.trimStart()); // Superman___
console.log(trimmedSuperHero.trimEnd()); // ___Superman
// #4 - try...catch 中的可选 catch 语句
try {
throw new Error('超级英雄未找到!');
} catch {
console.log('出现了错误');
}
// #5 - Symbol.description
const sym = Symbol('布鲁斯的方式是蝙蝠侠');
console.log(sym.description); // 布鲁斯的方式是蝙蝠侠
// #6 - Function.prototype.toString() 修订 - 返回精确的函数主体
function isSuperHero () {
console.log('布鲁斯的方式是蝙蝠侠');
}
console.log(isSuperHero.toString());
// function isSuperHero () {
// console.log('布鲁斯的方式是蝙蝠侠');
// }
// #7 - JSON.stringify() 正确处理表情符号
console.log(JSON.stringify('\uD83D\uDE00')); // 输出: '"😀"'
// #8 - BigInt - 支持超过 Number.MAX_SAFE_INTEGER 的大整数
const bigNumber = 123456789012345678901234567890n;
console.log(bigNumber + 10n); // 123456789012345678901234567900n
切换到全屏模式 退出全屏
ES11 的特性特性 | 描述 |
---|---|
BigInt | 超过 Number.MAX_SAFE_INTEGER 的大整数 |
空值合并运算符 (?? ) |
如果左侧操作数为 null 或 undefined ,则返回右侧操作数,否则返回左侧操作数 |
可选链运算符 (?. ) |
安全地访问嵌套属性而不引发错误 |
Promise.allSettled() | 在所有 Promise 被解决或拒绝后解析 |
globalThis | 在所有 JavaScript 环境中的标准全局对象 |
String.prototype.matchAll() | 返回字符串中所有匹配项的迭代器 |
稳定的 Array.prototype.sort() 方法 | 确保排序稳定(相等的项保持原有的顺序) |
import.meta | 提供当前模块的元数据信息 |
示例
// #1 - 空值合并运算符 (??) - 当左侧操作数为 null 或 undefined 时,返回右侧操作数。
const superhero = null;
const userName = superhero ?? 'Batman';
console.log(userName); // 'Batman'
const human = "Bruce";
const isHuman = human ?? 'Batman';
console.log(isHuman); // Bruce
// #2 - 可选链操作符 (?.) - 如果链中的任何一部分为 null 或 undefined,它会短路并返回 undefined 而不会抛出错误。
const superheroObject = { name: 'Batman', age: 32, human : {name: 'Bruce Wayne'} };
console.log(superheroObject?.name); // 'Batman'
console.log(superheroObject.age); // 32
console.log(superheroObject.human.name.fullName); // undefined (无错误输出)
// #3 - Promise.allSettled() - 返回一个在所有 Promise 完成(无论是被解决还是被拒绝)时解析的 Promise。
const p1 = Promise.resolve("Batman");
const p2 = Promise.reject('No superhero found');
const p3 = Promise.resolve("Superman");
Promise.allSettled([p1, p2, p3])
.then(results => results.forEach(result => console.log(result.status)));
// 'fulfilled', 'rejected', 'fulfilled'
// #4 - globalThis - 适用于所有 JavaScript 环境的全局对象
// #5 - matchAll() - 返回字符串中所有匹配的迭代器
const regex = /man+/g;
const str = 'Superman Batman Flash';
const matches = str.matchAll(regex);
for (const match of matches) {
console.log(match[0]); // man man
}
// #6 - import.meta
console.log(import.meta.url); // 显示当前模块的 URL 地址
全屏模式, 退出全屏
ES12 的特点特性 | 描述 |
---|---|
逻辑赋值操作符 | 结合逻辑运算符与赋值 (&&= , ` |
Promise.any() | 解析出 promises 数组中第一个完成的 promise |
WeakRefs | 允许引用对象而不阻止垃圾回收 |
String.prototype.replaceAll() | 替换字符串中所有子字符串的出现 |
数字分隔符 (_ ) |
使用下划线 _ 使大数字更易读 |
Object.hasOwn() | 检查对象是否具有特定的自有属性(比 hasOwnProperty() 更可靠) |
增强的 Array.prototype.sort() | 数值排序现在可以正确进行,无需自定义比较器 |
示例代码
// #1 - 逻辑赋值操作符 - &&, ||, ??
let x = 1;
x &&= 2; // x 保持为 2,因为 x 是真值
console.log(x); // 2
let y = 0;
y &&= 3; // y 保持为 0,因为 y 是假值
console.log(y); // 0
let a = null;
a ||= 'default'; // a 被赋值为 'default',因为它是假值
console.log(a); // 'default'
let b = null;
b ??= 'fallback'; // b 被赋值为 'fallback',因为它是空值或假值
console.log(b); // 'fallback'
// #2 - Promise.any() - 返回第一个成功的 Promise
const p1 = Promise.reject('找不到超级英雄');
const p2 = Promise.reject('找不到人类');
const p3 = Promise.resolve('找到火星人');
Promise.any([p1, p2, p3])
.then(result => console.log(result)) // '找到火星人'
.catch(err => console.log(err));
// #3 - WeakRefs - 允许你在不阻止对象被垃圾回收的情况下引用它们
let superhero = { name: '蝙蝠侠' };
let weakRef = new WeakRef(superhero);
// 访问对象(如果还没有被垃圾回收)
console.log(weakRef.deref()); // { name: '蝙蝠侠' }
// 当 `superhero` 被解除引用后,可能会被垃圾回收
superhero = null; // superhero 可能会被垃圾回收
// #4 - replaceAll() - 替换字符串中的所有子字符串
const text = '蝙蝠侠拥有氪石以防超人末日来临';
const result = text.replaceAll('o', '0');
console.log(result); // '蝙蝠侠拥有氪0石以防超人0末0日'
// #5 - 数字分隔符 (_) 用于数字
const price = 100000000;
console.log(price) // 100000000
// #6 - Object.hasOwn() 用于检查对象是否具有某个属性
const superheroObject = { name: '蝙蝠侠', age: 32 };
console.log(Object.hasOwn(superheroObject, 'name')); // true
console.log(Object.hasOwn(superheroObject, 'human')); // false
// #7 - 数字排序改进
const numbers = [10, 1, 21, 2];
numbers.sort(); // 默认行为:按字符串顺序排序
console.log(numbers); // ['1', '10', '2', '21']
const sortedNumbers = [10, 1, 21, 2];
sortedNumbers.sort((a, b) => a - b); // 数字排序
console.log(sortedNumbers); // [1, 2, 10, 21]
进入全屏 退出全屏
ES13 特点特性 | 描述 |
---|---|
Array.at() | 允许使用负索引访问数组元素 |
顶级 await | 允许在模块顶层使用 await ,而无需异步函数 |
WeakRefs 与 FinalizationRegistry | 在对象被垃圾回收时管理资源并进行清理 |
Error.cause | 为错误添加一个 cause 属性,以更好地处理错误 |
Object.hasOwn() | 检查对象是否直接拥有某个属性 |
增强的 copyWithin() | 对 copyWithin() 方法进行增强,以便更好地复制数组元素 |
示例
// #1 - 数组 at() 方法
const 超级英雄 = ["蝙蝠侠", "超人", "蜘蛛侠", "钢铁侠", "美国队长"];
console.log(超级英雄.at(1)); // 超人 (从开始位置)
console.log(超级英雄.at(-1)); // 美国队长 (从末尾)
console.log(超级英雄.at(-2)); // 钢铁侠 (从末尾)
// #2 - 顶级 await - 在模块的顶层可以直接使用 await,无需将其包裹在 async 函数中
// 在 ES 模块(例如 `index.mjs`)中
// const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
// const data = await response.json();
// console.log(data);
// #3 - 结合使用 WeakRefs 和 FinalizationRegistry
const 注册表 = new FinalizationRegistry((value) => {
console.log(`对象 ${value} 被垃圾回收`);
});
let obj = { name: 'Bruce' };
注册表.register(obj, 'Bruce');
obj = null; // 对象将被回收,触发回调
// #4 - Error.cause - 为 Error 对象提供添加原因的属性。
try {
throw new Error('出错了', { cause: '假 API 调用' });
} catch (err) {
console.log(err.message); // '出错了'
console.log(err.cause); // '假 API 调用'
}
// #5 - Array copyWithin() 方法
const 数字 = [1, 2, 3, 4, 5];
数字.copyWithin(0, 3); // 将索引 3 的元素复制到索引 0
console.log(数字); // [4, 5, 3, 4, 5]
进入全屏 退出全屏
ES14 的特点特性 | 描述 |
---|---|
Array.prototype.toSorted() | 返回一个排序后的数组副本,不修改原始数组 |
Array.prototype.toReversed() | 返回一个反转后的数组副本,不修改原始数组 |
Array.prototype.toSpliced() | 返回一个修改后的数组副本,其中移除或添加了元素,不改变原始数组 |
Symbol.prototype.description | 一个新的属性,返回符号的描述 |
增强的正则表达式功能 | 增强的正则表达式功能,例如使用 d 标志来启用点全模式 |
改进的错误堆栈跟踪信息 | 更详细和准确的堆栈跟踪信息,包括异步函数 |
Object.hasOwn() 改进 | 更可靠且推荐用于检查对象属性的方法 |
示例代码:
// #1 - Array.prototype.toSorted() - 创建一个数组的排序副本,不改变原数组。
const superheros = ["Superman", "Batman", "Flash"];
const sortedSuperheros = superheros.toSorted();
console.log(sortedSuperheros); // [ 'Batman', 'Flash', 'Superman' ]
console.log(superheros); // 原始数组:[ 'Superman', 'Batman', 'Flash' ]
// #2 - Array.prototype.toReversed() - 返回反转顺序的新数组,不改变原数组。
const reversedSuperheros = superheros.toReversed();
console.log(reversedSuperheros); // [ 'Flash', 'Batman', 'Superman' ]
console.log(superheros); // 原始数组:[ 'Superman', 'Batman', 'Flash' ]
// #3 - Array.prototype.toSpliced() - 返回移除和/或添加元素后的新数组,不改变原数组
const splicedSuperheros = superheros.toSpliced(1, 1, "Aquaman");
console.log(splicedSuperheros); // [ 'Superman', 'Aquaman', 'Flash' ]
console.log(superheros); // 原始数组:[ 'Superman', 'Batman', 'Flash' ]
// #4 - 改进的正则表达式功能,如下所示
const regex = /foo.bar/s;
const result = regex.test('foo\nbar'); // true,因为 `.` 现在可以匹配换行符(如上所示)
console.log(result);
进入全屏 退出全屏
點擊查看更多內容
為 TA 點贊
評論
評論
共同學習,寫下你的評論
評論加載中...
作者其他優質文章
正在加載中
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦