前言
我們常說的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']
今天就介紹這些吧,本文介紹并非全部新特性。
注意使用這些方法時看一下瀏覽器各個版本兼不兼容哦!!!