【譯】Javascript中你須要知道的最出色的新特性:Optional Chaining

對於使用Javascript的每一個人來講,可選鏈(Optional chaining)是遊戲的規則的改變者。它與箭頭函數或letconst同樣重要。咱們討論下它能夠解決什麼問題,它如何工做,以及它如何使得你的生活更加輕鬆。javascript

問題

想象如下場景:java

你正在使用片斷代碼來從一個API加載數據。返回數據是深度嵌套的對象,這就意味着你須要遍歷很長的對象屬性。git

// API response object
const person = {
    details: {
        name: {
            firstName: "Michael",
            lastName: "Lampe",
        }
    },
    jobs: [
        "Senior Full Stack Web Developer",
        "Freelancer"
    ]
}
// Getting the firstName
const personFirstName = person.details.name.firstName;
複製代碼

如今,保留這樣的代碼也是不錯的。不過,有個更好的解決方法,以下:github

// Checking if firstName exists
if( person &&
    person.details &&
    person.details.name ) {
        const personFirstName = person.details.name.firstName || 'stranger';
}
複製代碼

正如示例中你所看到的,即便是簡單的事情,好比獲取一我的的名字,也很難正確獲取。web

因此,這就是爲何咱們使用相似lodash庫去處理這樣的事情:數組

_.get(person, 'details.name.firstName', 'stranger');
複製代碼

lodash使得代碼更具可讀性,可是你得在你的代碼庫中引入不少的依賴。你須要更新它,而後,若是你在一個團隊中工做,你須要在團隊中推廣使用它。因此,這也不是一個理想的解決方案。瀏覽器

解決方案

可選鏈爲這些(除了團隊的問題)提供了一個解決方案。babel

它是怎麼工做的

初次看到可選鏈的新語法,你可能會感到陌生,可是,幾分鐘後你會習慣它的。函數

const personFirstName = person?.details?.name?.firstName;
複製代碼

好了,如今你腦子可能有不少問號(雙關語義)。上面語法的?是個新的事物。這就是你要想一想的地方了。在屬性前(原文應該改成屬性後比較準確)有?.,就是在問你屬性person存在嗎?或者,更加javascript的表達方式--person屬性的值是nullundefined嗎?若是是,將不會返回一個錯誤,而是返回undefined。因此personFirstName將返回undefined。對details?name?會進行重複的詢問。若是任意一個的值爲nullundefined,以後personFirstName都會返回undefined。這被稱爲Short-circuiting(短路)。一旦javascript找到值爲nullundefined,它就會短路並不會再深刻查詢下去。ui

默認值

咱們還須要學學Nullish coalescing operator(空位合併運算符)。好吧,這聽起來很難學。可是實際上,一點也不難。咱們看看下面的例子:

const personFirstName = person?.details?.name?.firstName ?? 'stranger';
複製代碼

Nullish coalescing operator??來表示。它也很容易去解讀。若是??左側返回的內容是undefined,那麼personFirstName會將??右側的值賦值給它。這太容易了。

動態屬性

有時候你須要獲取動態的值。它多是一個數組的值,或者是一個對象的動態屬性。

const jobNumber = 1;
const secondJob = person?.jobs?.[jobNumber] ?? 'none';
複製代碼

這裏須要重點理解的地方是jobs?.[jobNumber],它和jobs[jobNumber]表達的同樣,可是不會拋出一個錯誤;相反,它會返回none值。

函數或方法調用

有時候,你會處理對象,而你不知道它們是否帶有方法。這裏咱們可使用?.()語法或帶參數?.({ some: 'args'})語法。它會根據你的需求運行。若是在那個對象中不存在這個方法,它會返回值undefined

const currentJob = person?.jobs.getCurrentJob?.() ?? 'none';
複製代碼

上面的例子中,若是沒有getCurrentJob方法,那麼currentJob將會返回none

今天開始使用它

目前沒有瀏覽器支持此功能--Babel作轉換了。

這裏已經有一個babel.js插件,若是你已經有了Babel設置,那就很容易集成了。

babel-plugin-proposal-optional-chaining

參考和後話

相關文章
相關標籤/搜索