前言
我们常说的ES6也就是ECMAScript 2015是在2015年6月发布的。这个版本引入了许多重要的语言特性和改进,对 JavaScript 进行了深刻的扩展和升级,ES6 是 JavaScript 语言的一个里程碑。所以有时也被称为ES6。这是由于规范的发布年份与实际版本号之间的不匹配。然而,标准化组织决定更改命名方式,以便更好地反映年份,从而引入了“ECMAScript [年份]”的命名习惯。
从2015年的ECMAScript 2015(ES6)到现在的ECMAScript 2023。在这几年的发展中,我们见证了JavaScript的成为web开发的主导语言。但是人们在谈论JS时还是习惯性说ES6,然而举例2015已经过去了8年,是不是该更新一下知识库啦。
这篇文章我们介绍一下JavaScript从ES6到ES2023的重要变化。
ECMAScript 2015
这里只介绍一些主要的特性,
-
let 和 const 声明: 引入了块级作用域的变量声明方式。
let
用于声明变量,而const
用于声明常量。 -
箭头函数: 提供了更简洁的函数声明语法,尤其适用于匿名函数。
// 传统函数 function add(a, b) {return a + b; }// 箭头函数 const add = (a, b) => a + b;
-
模板字符串: 允许在字符串中插入表达式,更易读且更灵活。
const name = 'World'; const greeting = `Hello, ${name}!`;
-
默认参数值: 允许在函数声明中为参数设置默认值。
function greet(name = 'World') {console.log(`Hello, ${name}!`); }
-
解构赋值: 允许从数组或对象中提取值并赋给变量。
// 数组解构 const [a, b] = [1, 2];// 对象解构 const { x, y } = { x: 1, y: 2 };
-
类和继承: 引入了更接近传统面向对象编程的类和继承语法。
class Animal {constructor(name) {this.name = name;}speak() {console.log(`${this.name} makes a sound.`);} }class Dog extends Animal {speak() {console.log(`${this.name} barks.`);} }
-
模块化: 引入了模块系统,允许将代码分割为可维护的模块。
// 导出 export const myVar = 42;// 导入 import { myVar } from './myModule';
-
Promise: 提供了更强大的异步编程机制,以解决回调地狱问题。
const myPromise = new Promise((resolve, reject) => {// 异步操作if (/* 操作成功 */) {resolve('Success!');} else {reject('Failure!');} });myPromise.then(result => console.log(result)).catch(error => console.error(error));
-
for…of 和 for…in: 用于迭代对象和数组中的元素。
-
Set和 Mapz:
Set
是一种用于存储唯一值的集合。它不允许重复的元素,并提供了一系列方法来操作这些值。
const uniqueNumbers = new Set([1, 2, 3, 1, 2]);uniqueNumbers.add(4);
console.log(uniqueNumbers); // Set { 1, 2, 3, 4 }console.log(uniqueNumbers.has(2)); // true
Map
是一种键值对的集合,其中的键和值可以是任意数据类型。它提供了一种更灵活的方式来存储和检索数据,相较于对象,Map
在处理键值对的场景中更为直观和高效。
const userMap = new Map();userMap.set('name', 'John');
userMap.set('age', 30);console.log(userMap.get('name')); // 'John'
console.log(userMap.has('gender')); // false
ECMAScript 2016
ECMAScript 2016本质上是一个较小的更新,其中包括了一些相对较小的语法和功能改进。
-
指数操作符(Exponentiation Operator): 引入了指数操作符
**
,用于计算一个数字的幂。let result = 2 ** 3; // 8
-
Array.prototype.includes(): 在数组原型上添加了
includes
方法,用于检查数组是否包含特定元素。const array = [1, 2, 3]; console.log(array.includes(2)); // true console.log(array.includes(4)); // false
ECMAScript 2017
ECMAScript 2017(也称为ES8)是在2017年发布的 JavaScript 语言的一个版本,相对于 ECMAScript 2016 来说,引入了一些新的功能和改进。以下是其中一些主要的变化:
-
异步函数(Async/Await)的改进: ES2017 对异步函数进行了一些改进,使其更加灵活和强大。异步函数是使用
async
关键字声明的函数,而await
关键字可以在异步函数内部等待一个 Promise 解决。async function fetchData() {let response = await fetch('https://api.example.com/data');let data = await response.json();return data; }
-
Object.values() 和 Object.entries(): 引入了
Object.values()
和Object.entries()
方法,分别用于获取对象的值数组和键值对数组。const obj = { a: 1, b: 2, c: 3 };console.log(Object.values(obj)); // [1, 2, 3] console.log(Object.entries(obj)); // [['a', 1], ['b', 2], ['c', 3]]
-
字符串填充方法(String Padding): 引入了字符串填充方法
String.prototype.padStart()
和String.prototype.padEnd()
,用于在字符串前或后填充指定的字符。let str = 'hello'; console.log(str.padStart(8, '*')); // '***hello' console.log(str.padEnd(8, '*')); // 'hello***'
-
共享内存与原子操作(Shared Memory and Atomics): 引入了 SharedArrayBuffer 和 Atomics 对象,用于更好地支持多线程和并行编程。
// 创建共享内存 const buffer = new SharedArrayBuffer(16);// 在共享内存上进行原子操作 Atomics.add(new Int32Array(buffer), 0, 5);
ECMAScript 2019
也不是每一年都有那种很重要的改变,这里ECMAScript 2018 并入了 ECMAScript 2019
-
Array.prototype.flat() 和 Array.prototype.flatMap(): 引入了
flat
和flatMap
方法,用于扁平化嵌套的数组结构。const nestedArray = [1, [2, [3, 4]]]; const flatArray = nestedArray.flat(); // [1, 2, [3, 4]]
flatMap
可以同时扁平化和映射数组。 -
Object.fromEntries(): 提供了从键值对数组创建对象的方法。
const entries = [['a', 1], ['b', 2], ['c', 3]]; const obj = Object.fromEntries(entries); // {a: 1, b: 2, c: 3}
-
String.prototype.trimStart() 和 String.prototype.trimEnd(): 引入了字符串的两个新方法,用于删除字符串开头和结尾的空格。
const str = ' Hello '; console.log(str.trimStart()); // 'Hello ' console.log(str.trimEnd()); // ' Hello'
-
Symbol.prototype.description: 允许通过
Symbol.prototype.description
获取 Symbol 的描述信息。const mySymbol = Symbol('My Symbol'); console.log(mySymbol.description); // 'My Symbol'
-
Function.prototype.toString() 的改进: Function.prototype.toString() 方法现在返回精确的源代码表示,包括空格和注释。
function example() {// This is a commentreturn 'Hello'; }console.log(example.toString()); // 函数源代码中包含注释和缩进
ECMAScript 2020
ECMAScript 2020(也称为ES11)引入了一些新的功能和改进。以下是其中一些主要的变化:
-
可选链操作符(Optional Chaining): 引入了可选链操作符(
?.
),用于简化访问可能不存在的属性或方法的代码。const user = {address: {street: '123 Main St'} };// 传统方式 const street = user && user.address && user.address.street;// 使用可选链操作符 const street = user?.address?.street;
-
空值合并操作符(Nullish Coalescing Operator): 引入了空值合并操作符(
??
),用于提供默认值,但仅在变量为null
或undefined
时。const defaultValue = 'Default'; const userValue = null;// 传统方式 const result = userValue !== null && userValue !== undefined ? userValue : defaultValue;// 使用空值合并操作符 const result = userValue ?? defaultValue;
-
全局对象 globalThis: 引入了
globalThis
,它提供了一种标准的方式来获取全局对象,无论代码在哪里执行(浏览器、Node.js、Web Workers等)。console.log(globalThis === window); // 在浏览器中为 true console.log(globalThis === global); // 在 Node.js 中为 true
-
Promise.allSettled(): 引入了
Promise.allSettled()
方法,它接收一组 Promise,无论这些 Promise 是成功还是失败,都会等待它们全部 settled(已完成,不论是 resolved 还是 rejected)。const promises = [Promise.resolve('Success'), Promise.reject('Error')];Promise.allSettled(promises).then(results => console.log(results));
-
动态导入: 可以将js文件动态导入模块中。
-
BigInt: js代码可以使用更大的整数。
-
matchAll: 是一个用于 String 的新的方法,和正则相关。这个方法将返回一个迭代器,该迭代器一个接一个地返回所有匹配的组。
ECMAScript 2021
- String.prototype.replaceAll: 新增了字符串方法,可以全局替换字符串中的匹配项。
const originalString = 'apple banana apple orange';// 使用 replaceAll 替换所有的 'apple' 为 'grape'
const newString = originalString.replaceAll('apple', 'grape');console.log(newString);
// 输出: 'grape banana grape orange'
- 逻辑赋值运算符: 引入了逻辑赋值运算符,如&&=、||=和??=,用于对变量进行逻辑运算和赋值的组合操作。
let x = 1;// 逻辑与赋值
x &&= 2; // x = x && 2;let y = 0;// 逻辑或赋值
y ||= 3; // y = y || 3;let z = null;// 空值合并赋值
z ??= 4; // z = z !== null && z !== undefined ? z : 4;
- 数字分隔符: 允许在数字中使用下划线作为分隔符,以提高数字的可读性。
const billion = 1_000_000_000;
const binary = 0b1010_0010_0011;
const decimal = 1_000_000.123_456;
- Promise.any: 新增了Promise的静态方法,接受一个Promise可迭代对象,返回第一个解决的Promise的值。
const promise1 = new Promise((resolve, reject) => setTimeout(resolve, 1000, 'one'));
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 500, 'two'));
const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 800, 'three'));Promise.any([promise1, promise2, promise3]).then(result => console.log(result)).catch(error => console.error(error));
- WeakRef: 引入了WeakRef和FinalizationRegistry API,用于处理弱引用和对象的最终化
let obj = { data: 'some data' };
let weakRef = new WeakRef(obj);console.log(weakRef.deref()); // { data: 'some data' }obj = null; // 弱引用不会阻止对象被垃圾回收console.log(weakRef.deref()); // undefined
ECMAScript 2022
顶层 await
在 ECMAScript 2022 中引入了顶层 await,它允许在模块的顶层直接使用 await
关键字,而不需要在异步函数内部包裹。
// 在模块的顶层直接使用 await
const result = await fetchData();console.log(result);
ECMAScript 2023
今年6月份发布了ECMAScript 2023,这将是目前最新版本的规范。
- findLast() 、findLastIndex(): 在 JS中,可以通过 find() 和 findIndex() 从前往后查找数组中的值。
这两个方法支持从后往前查找,用法和find()、findIndex()一样。
const array = [{v: 1}, {v: 2}, {v: 3}, {v: 4}, {v: 5}];array.findLast(elem => elem.v > 3); // {v: 5}
array.findLastIndex(elem => elem.v > 3); // 4
array.findLastIndex(elem => elem.v > 5); // undefined
2.Hashbang 语法:
Hashbang(也称为 shebang)是一种在脚本文件的开头使用 #! 注释的语法,通常用于指定脚本文件的解释器。
#!/usr/bin/env node
- toReversed()、toSorted()、toSpliced()、with()
之前js支持的reverse、sort、splice都是修改原数组的,以前使用这些方法想又不改变原数组,可能是这样:
const originalArray = [3, 1, 4, 1, 5, 9];const reversedArray = originalArray.slice().reverse();
const sortedArray = originalArray.slice().sort();
const splicedArray = originalArray.slice(1, 4);
const arrayWithElement = [...originalArray, 7];console.log(reversedArray); // 输出 [9, 5, 1, 4, 1, 3]
console.log(sortedArray); // 输出 [1, 1, 3, 4, 5, 9]
console.log(splicedArray); // 输出 [1, 4, 1]
console.log(arrayWithElement); // 输出 [3, 1, 4, 1, 5, 9, 7]
然而有以下这些方法返回新的数组,不改变原数组。是不是就简便多了。
- toReversed():返回数组的逆序副本。
- toSorted():返回数组的排序副本。
- toSpliced():返回对数组进行切片后的副本。
- with():可能是返回包含特定元素的副本。
with():该方法会以非破坏性的方式替换给定 index 处的数组元素,即 arr[index]=value 的非破坏性版本。
const arr = ['a', 'b', 'c'];
const arr1 = arr.with(2, 'd');
console.log(arr1); // ['a','b','d']
console.log(arr); // ['a', 'b', 'c']
今天就介绍这些吧,本文介绍并非全部新特性。
注意使用这些方法时看一下浏览器各个版本兼不兼容哦!!!