簡介
ES12是ECMA協會在2021年6月發行的一個版本,因為是ECMAScript的第十二個版本,所以也稱為ES12.
ES12發行到現在已經有一個月了,那麼ES12有些什麼新特性和不一樣的地方呢?一起來看看吧。
基本上ES12引入了replaceAll方法用於對String進行操作,Promise.any用於對Promise進行組合操作,AggregateError用於表示多個錯誤的集合,新的邏輯操作符??=, &&=, ||=,弱引用WeakRef,FinalizationRegistry用於垃圾回收的註冊,一個數字的分隔符1_000,更加精準的陣列sort方法Array.prototype.sort。
下面本文將會一一進行講解。
replaceAll
熟悉java的朋友應該都知道,java中有兩個進行字串替換的方法,分別是replace和replaceAll,他們的區別在於replace是替換字串,而replaceAll是進行正規表示式匹配。
但是在javascript中兩者的涵義有所不同,在JS中replace是替換第一個出現的字串,而replaceAll就是字面上的意思替換所有的字串,我們舉個例子:
const string="flydean is a good fly"
console.log(string.replace("fly", "butterfly"));
上面的值返回:
butterflydean is a good fly
如果改用replaceAll:
const string="flydean is a good fly"
console.log(string.replaceAll("fly", "butterfly"));
butterflydean is a good butterfly
私有方法
自從JS有了類的概念之後,就可以在類中定義方法,並通過例項化之後的類進行呼叫,如下所示:
class Student {
getAge() {
console.log("永遠18歲")
}
}
student= new Student();
student.getAge();
上面程式碼執行結果:
"永遠18歲"
但是如果我們不希望getAge()方法直接暴露給外部使用,也就是說希望getAge()是一個私有方法,那麼只需要在方法前面加上#即可。
class Student {
#getAge() {
console.log("永遠18歲")
}
}
student= new Student();
student.getAge();
同樣執行,那麼會得到下面的錯誤提示:
Error: student.getAge is not a function
怎麼處理呢?我們知道私有方法是可以在方法內部呼叫的,那麼只需要建立一個公有方法,然後在這個公有方法中呼叫私有方法即可,如下所示:
class Student {
#getAge() {
console.log("永遠18歲")
}
getPublicAge(){
this.#getAge();
}
}
student= new Student();
student.getPublicAge();
我們可以得到同樣的結果。
私有屬性
上面講到了私有方法,那麼對於私有屬性是怎處理的呢?
通常,對於屬性,我們可以以get修飾符來進行修飾,然後就可以直接通過屬性名來訪問了:
class Student {
get Age() {
return 18;
}
}
student= new Student();
console.log(student.Age);
結果我們會得到18這個輸出。
同樣,可以在屬性名前面加上#,讓其變成私有變數,如下所示:
class Student {
get #Age() {
return 18;
}
}
student= new Student();
console.log(student.Age);
上面程式碼將會輸出undefined。
要想訪問上述的私有屬性,則可以用公有屬性去呼叫私有屬性方法:
class Student {
get #Age() {
return 18;
}
get publicAge() {
return this.#Age
}
}
student= new Student();
console.log(student.publicAge);
非常好用。
Promise.any() 和 AggregateError
promise.any可以返回任意一個提前resolve的結果,在現實的應用中,這種情況是非常常見的,我們來模擬一個例子:
const prom1 = new Promise((resolve, reject) => {
setTimeout(
() => resolve("promise one"),
Math.floor(Math.random() * 100)
);
});
const prom2 = new Promise((resolve, reject) => {
setTimeout(
() => resolve("promise two"),
Math.floor(Math.random() * 100)
);
});
const prom3 = new Promise((resolve, reject) => {
setTimeout(
() => resolve("promise three"),
Math.floor(Math.random() * 100)
);
});
(async function() {
const result = await Promise.any([prom1, prom2, prom3]);
console.log(result);
})();
上述程式碼可以隨機輸出promise one,promise two,promise three。
如果將上述程式碼改成所有的都reject,那麼會丟擲AggregateError:
const prom1 = new Promise((resolve, reject) => {
setTimeout(
() => reject("promise one rejected"),
Math.floor(Math.random() * 100)
);
});
const prom2 = new Promise((resolve, reject) => {
setTimeout(
() => reject("promise two rejected"),
Math.floor(Math.random() * 100)
);
});
const prom3 = new Promise((resolve, reject) => {
setTimeout(
() => reject("promise three rejected"),
Math.floor(Math.random() * 100)
);
});
try{
(async function() {
const result = await Promise.any([prom1, prom2, prom3]);
console.log(result);
})();
} catch(error) {
console.log(error.errors);
}
報的錯如下:
Uncaught (in promise) AggregateError: No Promise in Promise.any was resolved
注意,必須是所有的promise都被reject之後才會丟擲AggregateError,如果有部分成功,那麼將會返回成功的結果。
數字分隔符
這個新特性是為了方便程式設計師看程式碼而出現的,如果數字比較大,那麼看起來就不是那麼一目瞭然,比如下面的長數字:
const number= 123456789;
一眼看不出這個數字的體量到底是多大,所以ES12提供了數字分隔符_。
分隔符不僅可以分割十進位制,也可以分割二淨值或者十六淨值的資料,非常好用。
const number = 1_000_000_000_000;
const binary = 0b1010_0101_1111_1101;
const hex = 0xAF_BF_C3;
上面例子分別代表了十進位制,二進位制和十六進位制的資料,非常直觀好用。
新的邏輯操作符
我們知道&& 和 || 是被來進行邏輯操作的運算子。
比如:
1 && 2
1 || 2
等操作,ES12提供了&& 和||的二元操作符,如下:
var x = 1;
var y = 2;
x &&= y;
x ||= y;
另外還提供了??的二元操作符,如:
var x;
var y = 2;
x ??= y;
上面程式碼的意思是,判斷x是不是空,如果是空那麼將y的值賦給x。
總結
ES12的幾個新特性還是挺實用的,大家可以嘗試一下。
本文已收錄於 http://www.flydean.com/ecmascript-12/
最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!