2022 前端應該掌握的 10 個 JS 小技巧

來自:掘金,作者:LBJ 鏈接:https://juejin.cn/post/7072274726940311588

你知道 0 ?? 1等於多少嗎?

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

現在前端發展很快,各種技術和框架層出不窮、百花齊放,很多人都喊學不動啦!事實上JavaScript 作爲前端的主要語言,雖然它的發展很快,每年都會出一些新特性,但視乎 JavaScript 開發者的發展速度更快一些,因爲很多相對較新的功能都已經有很高的採用率

下面來看看那些具有較高採用率的新特性,2022你應該瞭解的10個 JS 小技巧

1. 用??代替||,用於判斷運算符左側的值爲nullundefined時,才返回右側的值

??運算符是 ES2020 引入,也被稱爲null判斷運算符 (Nullish coalescing operator)

它的行爲類似||,但是更嚴

||運算符是左邊是空字符串或false0falsy 值,都會返回後側的值。而??必須運算符左側的值爲nullundefined時,纔會返回右側的值。因此 0||1 的結果爲 1,0??1 的結果爲 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. 使用?.簡化&&和三元運算符

?.也是 ES2020 引入,有人稱爲鏈判斷運算符(optional chaining operator)

?.直接在鏈式調用的時候判斷,判斷左側的對象是否爲nullundefined,如果是的,就不再往下運算,返回 undefined,如果不是,則返回右側的值

例如

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
複製代碼

注:常見寫法

瀏覽器支持情況

3. 使用動態導入 import() 實現按需加載(優化靜態 import)

我們可以使用 import 語句初始化的加載依賴項

import defaultExport from "module-name";
import * as name from "module-name";
//...
複製代碼

但是靜態引入的import 語句需要依賴於 type="module" 的script標籤,而且有的時候我們希望可以根據條件來按需加載模塊,比如以下場景:

這個時候我們就可以使用動態引入import(),它跟函數一樣可以用於各種地方,返回的是一個 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 函數

其實上面的代碼就有用到

let module = await import('/modules/my-module.js');
複製代碼

頂層 await 允許開發者在 async 函數外部使用 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僅替換第一次出現的子字符串,而replaceAll會替換所有

例如需要替換所有 a 爲 A:

// 以前
console.log('aaa'.replace(/a/g,'A')) //AAA

// 簡化後
console.log('aaa'.replaceAll('a','A')) //AAA
複製代碼

瀏覽器支持情況

6. 使用 Proxy 替代 Object.defineProperty

爲什麼使用 Proxy 替代 Object.defineProperty,簡單總結Proxy的幾點優勢

使用也很簡單,Proxy本質是構造函數,通過 new 即可產生對象,它接收兩個參數:

例如響應式reactive的基本實現:

function reactive(obj) {
    return new Proxy(obj, {
        get(target, key) {
            // 可以做依賴收集
            track(target, key)
            return target[key]
        },
        set(target, key, val) {
            target[key] = val
            // 觸發依賴
            trigger(target, key)
        }
    })
}
複製代碼

瀏覽器支持情況

7. Promise.any 快速獲取一組Promise實例中第一個fulfilledpromise

Promise.any 接收一組Promise實例作爲參數

寫法推薦

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 支持大整數計算問題

ES2020[1] 引入了一種新的數據類型 BigInt,用來表示任意位數的整數

例如

// 超過 53 個二進制位的數值(相當於 16 個十進制位),無法保持精度
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 來聲明一個大整數,還可以使用數字後面加 n 的形式,如

1234 // 普通整數
1234n // BigInt
複製代碼

需要了解 BigInt 數字操作時的支持情況,以免踩坑

rCEMEd

瀏覽器支持情況

9. 使用 Array.prototype.at() 簡化 arr.length

Array.prototype.at()接收一個正整數或者負整數作爲參數,表示獲取指定位置的成員

參數正數就表示順數第幾個,負數表示倒數第幾個,這可以很方便的某個數組末尾的元素

例如

var arr = [1, 2, 3, 4, 5]
// 以前獲取最後一位
console.log(arr[arr.length-1]) //5
// 簡化後
console.log(arr.at(-1)) // 5
複製代碼

10. 使用哈希前綴#將類字段設爲私有

在類中通過哈希前綴#標記的字段都將被私有,子類實例將無法繼承

例如

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都被私有化了,在實例中無法獲取到

最後

很多新特性都有很多人在用了,特別是???.以及動態引入import(),不知道你都用過哪些?

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/YyuZFDpXhZBq5Ua7fpcqNA