国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

避免取值時出現Cannot read property 'xx' of unde

fantix / 2993人閱讀

摘要:由于是以空函數為代理對象,我們可以將執行它,觸發。中會遍歷數組依次取值,如果發現無法繼續取值則,跳出循環。

本文來自我的博客,歡迎大家去GitHub上star我的博客

我們在取值特別是鏈式取值的時候,常常會遇到Cannot read property "xx" of undefined的錯誤,如何避免這種情況的發生呢?這里有幾種方法以供參考

使用成熟的庫方法

這是最簡單的一種手段:只用引入lodash,使用_.get方法;或者引入Ramda,使用R.path方法,我們就能規避出現上述錯誤的風險

盡管這種方法十分奏效且方便,但我還是希望你能看完其他方法

巧用&&和||

我們知道,在JavaScript中,使用&&或者||操作符,最后返回的值不一定是boolean類型的,比如下面這個例子:

console.log(undefined && "a"); //undefined
console.log("a" && "b"); //b
console.log(undefined || "a"); //a
console.log("a" || "b"); //a

&&:如果第一項是falsy(虛值,Boolean上下文中已認定可轉換為‘假‘的值),則返回第一項,否則返回第二項

||:如果第一項是falsy,返回第二項,否則返回第一項

我們可以利用這種規則進行取值

我們先擬一個數據

const artcle = {
    authorInfo: {
        author: "Bowen"
    },
    artcleInfo: {
        title: "title",
        timeInfo: {
            publishTime: "today"
        }
    }
};

接下來利用&&和||進行安全取值:

console.log(artcle.authorInfo && artcle.authorInfo.author); //Bowen
console.log(artcle.timeInfo && artcle.timeInfo.publishTime); //undefined
console.log(artcle.artcleInfo &&
        artcle.artcleInfo.timeInfo &&
        artcle.artcleInfo.timeInfo.publishTime
); //today

console.log((artcle.authorInfo || {}).author); //Bowen
console.log((artcle.timeInfo || {}).publishTime); //undefined
console.log(((artcle.artcleInfo || {}).timeInfo || {}).publishTime); //today

不難看出,這兩種方法都不算優雅,只適用短鏈式取值,一旦嵌套過深,使用&&需要寫一長段代碼,而使用||需要嵌套很多括號

利用解構賦值的默認值

我們可以利用es6的解構賦值,給屬性一個默認值,避免出現錯誤。以上文的artcle數據為例,如下:

const { authorInfo: { author } = {} } = artcle;
console.log(author); //Bowen

上面這么做會暴露很多變量出來,我們可以簡單地封裝一個函數,如下:

const getAuthor = ({ authorInfo: { author } = {} } = {}) => author;
console.log(getAuthor(artcle)); //Bowen

這樣做不會將變量暴露出來,同時getAuthor函數也能復用,優雅多了

利用try catch

既然在取值的過程中會出現錯誤,那我們自然可以利用try catch提前將錯誤捕獲:

let author, publishTime;
try {
    author = artcle.authorInfo.author;
} catch (error) {
    author = null;
}
try {
    publishTime = artcle.timeInfo.publishTime;
} catch (error) {
    publishTime = null;
}
console.log(author); //Bowen
console.log(publishTime); //null

這個方法不好的地方在于:我們無法在一個try catch語句里進行多次取值,因為只要有任一錯誤,就會進入catch語句中去

我們可以寫一個通用函數優化這一流程:

const getValue = (fn, defaultVaule) => {
    try {
        return fn();
    } catch (error) {
        return defaultVaule;
    }
};
const author = getValue(() => artcle.authorInfo.author);
const publishTime = getValue(() => artcle.timeInfo.publishTime);
console.log(author); //Bowen
console.log(publishTime); //undefined
利用proxy

這是我在網上看到的一個十分有意思的寫法,利用了es6中的proxy完成的:

const pointer = function(obj, path = []) {
    return new Proxy(function() {}, {
        get: function(target, key) {
            return pointer(obj, path.concat(key));
        },
        apply: function(target, object, args) {
            let value = obj;
            for (let i = 0; i < path.length; i++) {
                if (value == null) {
                    break;
                }
                value = value[path[i]];
            }
            if (value === undefined) {
                value = args[0];
            }
            return value;
        }
    });
};
const proxyArtcle = pointer(artcle);
console.log(proxyArtcle.authorInfo.author()); //Bowen
console.log(proxyArtcle.publishTime()); //undefined

原理比較簡單,我們可以看到,pointer方法返回的是一個以空函數為代理對象的Proxy實例,而在每次取值的時候會將key保存下來,以proxyArtcle.authorInfo.author為例,它其實等價于pointer(artcle, ["authorInfo", "author"])。由于是以空函數為代理對象,我們可以將執行它,觸發apply。apply中會遍歷path數組依次取值,如果發現無法繼續取值則break,跳出循環。

如果你還沒有學習proxy,可以花幾分鐘了解一下:proxy

這種方法在我看來已是比較優雅的解決方法,但由于proxy對瀏覽器和node版本有所限制,且不可能有polyfill,真正應用起來需要考慮太多

optional chaining

這是一個新特性,尚在提案階段,具體可以看tc39/proposal-optional-chaining,不過已經有babel可以使用了:babel-plugin-proposal-optional-chaining

我們可以像下面一樣使用這個特性:

console.log(artcle?.authorInfo?.author); //Bowen
console.log(artcle?.timeInfo?.publishTime) //undefined

這種方法已接近完美,我們可以期待它的真正落實

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101957.html

相關文章

  • antd報錯Cannot read property &#039;filter&#039; of u

    摘要:技術棧問題描述在狀態組件中書寫下的其中涉及點擊某處出現彈框的操作,在中有選框,點擊取消或清空所有表單信息。點擊選框內的各個選項,報錯。在點擊取消之后,清空的是所有組件的內容,再打開新的彈窗后,組件的狀態并沒有刷新。 技術棧: react + dva + antd 問題描述: 在狀態組件中書寫state下的columns,其中涉及點擊某處出現彈框modal的操作,在modal中有sel...

    Tychio 評論0 收藏0
  • Vue “Cannot read property &#039;upgrade&#039; of u

    摘要:最近啟動項目報了個錯誤,如下原因是在中使用了而在中已被刪除了 最近啟動vue-cli3.0項目報了個錯誤,如下showImg(https://segmentfault.com/img/bVbt7w8?w=2088&h=538);原因是在vue.config.js 中使用了 process.env.target 而在.env中 target已被刪除了

    tolerious 評論0 收藏0
  • 解決Mac OS編譯安裝時出 cannot find openssl&#039;s <evp

    摘要:踩坑最近通過安裝擴展時,提示以下錯誤根據提示,通過以下方式安裝后,再次使用安裝,仍然是提示同樣的錯誤問題解決通過安裝的路走不通,還是得通過簡單暴力方式解決,使用源碼包通過編譯方式進行安裝編譯安裝前先安裝下載源代碼包后,在終端進入源碼目錄,執 踩坑 最近通過pecl安裝mongodb擴展時,提示以下錯誤 ...... configure: error: Cannot find OpenS...

    GHOST_349178 評論0 收藏0
  • 【Copy攻城獅日志】踩坑小程序之can&#039;t read property &#039;of

    摘要:根據當時的情境,是在微信開發者工具中刪掉該小程序然后重新載入就解決了,大家給出的結論是微信小程序開發者工具的。 Created 2019-4-2 22:17:34 by huqiUpdated 2019-4-2 23:17:34 by huqishowImg(https://segmentfault.com/img/bVbqOLH?w=1526&h=818); ↑開局一張圖,故事全靠編...

    hsluoyz 評論0 收藏0

發表評論

0條評論

fantix

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<