新聞中心
大家好,我是 ??LBJ??,今天我們聊聊??2022??一些值得掌握的新特性!

現(xiàn)在前端發(fā)展很快,各種技術(shù)和框架層出不窮、百花齊放,很多人都喊學(xué)不動(dòng)啦!事實(shí)上??JavaScript?? 作為前端的主要語言,雖然它的發(fā)展很快,每年都會(huì)出一些新特性,但視乎 ??JavaScript?? 開發(fā)者的發(fā)展速度更快一些,因?yàn)楹芏嘞鄬?duì)較新的功能都已經(jīng)有很高的采用率
下面來看看那些具有較高采用率的新特性,??2022??你應(yīng)該了解的??10??個(gè) ??JS?? 小技巧
1. 用??????代替??||??,用于判斷運(yùn)算符左側(cè)的值為??null??或??undefined??時(shí),才返回右側(cè)的值
??????運(yùn)算符是 ??ES2020?? 引入,也被稱為??null??判斷運(yùn)算符( Nullish coalescing operator)
它的行為類似??||??,但是更嚴(yán)
??||??運(yùn)算符是左邊是空字符串或??false??或??0??等falsy值,都會(huì)返回后側(cè)的值。而??????必須運(yùn)算符左側(cè)的值為??null??或??undefined??時(shí),才會(huì)返回右側(cè)的值。因此0||1的結(jié)果為1,0??1的結(jié)果為0
例如
const response = {
settings: {
nullValue: null,
height: 400,
animationDuration: 0,
headerText: '',
showSplashScreen: false
}
};
const undefinedValue = response.settings.undefinedValue ?? 'some other default'; // result: 'some other default'
const nullValue = response.settings.nullValue ?? 'some other default'; // result: 'some other default'
const headerText = response.settings.headerText ?? 'Hello, world!'; // result: ''
const animationDuration = response.settings.animationDuration ?? 300; // result: 0
const showSplashScreen = response.settings.showSplashScreen ?? true; // result: false
瀏覽器支持情況
2. 使用???.??簡化??&&??和三元運(yùn)算符
???.??也是ES2020 引入,有人稱為鏈判斷運(yùn)算符(optional chaining operator)
???.??直接在鏈?zhǔn)秸{(diào)用的時(shí)候判斷,判斷左側(cè)的對(duì)象是否為??null??或??undefined??,如果是的,就不再往下運(yùn)算,返回undefined,如果不是,則返回右側(cè)的值
例如
var street = user.address && user.address.street;
var fooInput = myForm.querySelector('input[name=foo]')
var fooValue = fooInput ? fooInput.value : undefined
// 簡化
var street = user.address?.street
var fooValue = myForm.querySelector('input[name=foo]')?.value
注:常見寫法
- ?
?obj?.prop?? 對(duì)象屬性 - ?
?obj?.[expr]?? 對(duì)象屬性 - ?
?func?.(...args)?? 函數(shù)或?qū)ο蠓椒ǖ恼{(diào)用
瀏覽器支持情況
3. 使用動(dòng)態(tài)導(dǎo)入import()實(shí)現(xiàn)按需加載(優(yōu)化靜態(tài)import)
我們可以使用 ??import?? 語句初始化的加載依賴項(xiàng)
import defaultExport from "module-name";
import * as name from "module-name";
//...
但是靜態(tài)引入的??import?? 語句需要依賴于 ??type="module"?? 的??script??標(biāo)簽,而且有的時(shí)候我們希望可以根據(jù)條件來按需加載模塊,比如以下場景:
- 當(dāng)靜態(tài)導(dǎo)入的模塊很明顯的降低了代碼的加載速度且被使用的可能性很低,或者并不需要馬上使用它
- 當(dāng)靜態(tài)導(dǎo)入的模塊很明顯的占用了大量系統(tǒng)內(nèi)存且被使用的可能性很低
- 當(dāng)被導(dǎo)入的模塊,在加載時(shí)并不存在,需要異步獲取
- 當(dāng)被導(dǎo)入的模塊有副作用,這些副作用只有在觸發(fā)了某些條件才被需要時(shí)
這個(gè)時(shí)候我們就可以使用動(dòng)態(tài)引入??import()??,它跟函數(shù)一樣可以用于各種地方,返回的是一個(gè) ??promise??
基本使用如下兩種形式
//形式 1
import('/modules/my-module.js')
.then((module) => {
// Do something with the module.
});
//形式2
let module = await import('/modules/my-module.js');
瀏覽器支持情況
4. 使用頂層 await(top-level await)簡化 async 函數(shù)
其實(shí)上面的代碼就有用到
let module = await import('/modules/my-module.js');
頂層 ??await?? 允許開發(fā)者在 ??async?? 函數(shù)外部使用 ??await?? 字段
因此
//以前
(async function () {
await Promise.resolve(console.log(''));
// →
})();
//簡化后
await Promise.resolve(console.log(''));
瀏覽器支持情況
5. 使用String.prototype.replaceAll()簡化replace一次性替換所有子字符串
??String.prototype.replaceAll()??用法與??String.prototype.replace()??類似
但是??replace??僅替換第一次出現(xiàn)的子字符串,而??replaceAll??會(huì)替換所有
例如需要替換所有a為A:
// 以前
console.log('aaa'.replace(/a/g,'A')) //AAA
// 簡化后
console.log('aaa'.replaceAll('a','A')) //AAA
瀏覽器支持情況
6. 使用Proxy替代Object.defineProperty
為什么使用 ??Proxy?? 替代 ??Object.defineProperty??,簡單總結(jié)??Proxy??的幾點(diǎn)優(yōu)勢(shì)
- Proxy 是對(duì)整個(gè)對(duì)象的代理,而 Object.defineProperty 只能代理某個(gè)屬性
- 對(duì)象上新增屬性,Proxy 可以監(jiān)聽到,Object.defineProperty 不能
- 數(shù)組新增修改,Proxy 可以監(jiān)聽到,Object.defineProperty 不能
- 若對(duì)象內(nèi)部屬性要全部遞歸代理,Proxy 可以只在調(diào)用的時(shí)候遞歸,而 Object.definePropery 需要一次完成所有遞歸,性能比 Proxy 差
使用也很簡單,??Proxy??本質(zhì)是構(gòu)造函數(shù),通過new即可產(chǎn)生對(duì)象,它接收兩個(gè)參數(shù):
- ?
?target??表示的就是要攔截(代理)的目標(biāo)對(duì)象 - ?
?handler??是用來定制攔截行為(13種)
例如響應(yīng)式??reactive??的基本實(shí)現(xiàn):
function reactive(obj) {
return new Proxy(obj, {
get(target, key) {
// 可以做依賴收集
track(target, key)
return target[key]
},
set(target, key, val) {
target[key] = val
// 觸發(fā)依賴
trigger(target, key)
}
})
}
瀏覽器支持情況
7. Promise.any快速獲取一組??Promise??實(shí)例中第一個(gè)??fulfilled??的??promise???
??Promise.any?? 接收一組??Promise??實(shí)例作為參數(shù)
- 只要其中的一個(gè) ?
?promise?? 成功,就返回那個(gè)已經(jīng)成功的 ??promise?? - 如果這組可迭代對(duì)象中,沒有一個(gè) ?
?promise?? 成功,就返回一個(gè)失敗的 ??promise?? 和 ??AggregateError?? 類型的實(shí)例
寫法推薦
try {
const first = await Promise.any(promises);
// Any of the promises was fulfilled.
} catch (error) {
// All of the promises were rejected.
}
或者
Promise.any(promises).then(
(first) => {
// Any of the promises was fulfilled.
},
(error) => {
// All of the promises were rejected.
}
);
瀏覽器支持情況
8. 使用BigInt支持大整數(shù)計(jì)算問題
ES2020[1] 引入了一種新的數(shù)據(jù)類型 BigInt,用來表示任意位數(shù)的整數(shù)
例如
// 超過 53 個(gè)二進(jìn)制位的數(shù)值(相當(dāng)于 16 個(gè)十進(jìn)制位),無法保持精度
Math.pow(2, 53) === Math.pow(2, 53) + 1 // true
// BigInt
BigInt(Math.pow(2, 53)) === BigInt(Math.pow(2, 53)) + BigInt(1) // false
除了使用BigInt來聲明一個(gè)大整數(shù),還可以使用數(shù)字后面加n的形式,如
1234 // 普通整數(shù)
1234n // BigInt
需要了解BigInt數(shù)字操作時(shí)的支持情況,以免踩坑
|
操作 |
是否支持 |
|
單目 (+) 運(yùn)算符 |
N |
|
? |
Y |
|
\ 除法運(yùn)算符 |
帶小數(shù)的運(yùn)算會(huì)被取整 |
|
? |
N |
|
其他位移操作符 |
Y |
|
與 Number 混合運(yùn)算 |
N(必須轉(zhuǎn)換為同類型) |
|
Math 對(duì)象方法 |
N |
|
Number 與 BigInt 比較(排序) |
Y(寬松相等 ==) |
|
Boolean 表現(xiàn) |
類型 Number 對(duì)象 |
|
JSON 中使用 |
N |
瀏覽器支持情況
9. 使用Array.prototype.at()簡化arr.length
??Array.prototype.at()??接收一個(gè)正整數(shù)或者負(fù)整數(shù)作為參數(shù),表示獲取指定位置的成員
參數(shù)正數(shù)就表示順數(shù)第幾個(gè),負(fù)數(shù)表示倒數(shù)第幾個(gè),這可以很方便的某個(gè)數(shù)組末尾的元素
例如
var arr = [1, 2, 3, 4, 5]
// 以前獲取最后一位
console.log(arr[arr.length-1]) //5
// 簡化后
console.log(arr.at(-1)) // 5
10. 使用哈希前綴??#??將類字段設(shè)為私有
在類中通過哈希前綴??#??標(biāo)記的字段都將被私有,子類實(shí)例將無法繼承
例如
class ClassWithPrivateField {
#privateField;
#privateMethod() {
return 'hello world';
}
constructor() {
this.#privateField = 42;
}
}
const instance = new ClassWithPrivateField()
console.log(instance.privateField); //undefined
console.log(instance.privateMethod); //undefined
可以看到,屬性??privateField??和方法??privateMethod??都被私有化了,在實(shí)例中無法獲取到
最后
很多新特性都有很多人在用了,特別是??????和???.??以及動(dòng)態(tài)引入??import()??,不知道你都用過哪些?
本文名稱:2022前端應(yīng)該掌握的十個(gè)JS小技巧
網(wǎng)站地址:http://fisionsoft.com.cn/article/dpohphc.html


咨詢
建站咨詢
