成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

避免取值時(shí)出現(xiàn)Cannot read property 'xx' of unde

fantix / 3064人閱讀

摘要:由于是以空函數(shù)為代理對(duì)象,我們可以將執(zhí)行它,觸發(fā)。中會(huì)遍歷數(shù)組依次取值,如果發(fā)現(xiàn)無法繼續(xù)取值則,跳出循環(huán)。

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

我們?cè)谌≈堤貏e是鏈?zhǔn)饺≈档臅r(shí)候,常常會(huì)遇到Cannot read property "xx" of undefined的錯(cuò)誤,如何避免這種情況的發(fā)生呢?這里有幾種方法以供參考

使用成熟的庫方法

這是最簡(jiǎn)單的一種手段:只用引入lodash,使用_.get方法;或者引入Ramda,使用R.path方法,我們就能規(guī)避出現(xiàn)上述錯(cuò)誤的風(fēng)險(xiǎn)

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

巧用&&和||

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

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

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

||:如果第一項(xiàng)是falsy,返回第二項(xiàng),否則返回第一項(xiàng)

我們可以利用這種規(guī)則進(jìn)行取值

我們先擬一個(gè)數(shù)據(jù)

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

接下來利用&&和||進(jìn)行安全取值:

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

不難看出,這兩種方法都不算優(yōu)雅,只適用短鏈?zhǔn)饺≈?,一旦嵌套過深,使用&&需要寫一長(zhǎng)段代碼,而使用||需要嵌套很多括號(hào)

利用解構(gòu)賦值的默認(rèn)值

我們可以利用es6的解構(gòu)賦值,給屬性一個(gè)默認(rèn)值,避免出現(xiàn)錯(cuò)誤。以上文的artcle數(shù)據(jù)為例,如下:

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

上面這么做會(huì)暴露很多變量出來,我們可以簡(jiǎn)單地封裝一個(gè)函數(shù),如下:

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

這樣做不會(huì)將變量暴露出來,同時(shí)getAuthor函數(shù)也能復(fù)用,優(yōu)雅多了

利用try catch

既然在取值的過程中會(huì)出現(xiàn)錯(cuò)誤,那我們自然可以利用try catch提前將錯(cuò)誤捕獲:

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

這個(gè)方法不好的地方在于:我們無法在一個(gè)try catch語句里進(jìn)行多次取值,因?yàn)橹灰腥我诲e(cuò)誤,就會(huì)進(jìn)入catch語句中去

我們可以寫一個(gè)通用函數(shù)優(yōu)化這一流程:

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

這是我在網(wǎng)上看到的一個(gè)十分有意思的寫法,利用了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

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

如果你還沒有學(xué)習(xí)proxy,可以花幾分鐘了解一下:proxy

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

optional chaining

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

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

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

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/101957.html

相關(guān)文章

  • antd報(bào)錯(cuò)Cannot read property &#039;filter&#039; of u

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

    Tychio 評(píng)論0 收藏0
  • Vue “Cannot read property &#039;upgrade&#039; of u

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

    tolerious 評(píng)論0 收藏0
  • 解決Mac OS編譯安裝時(shí)出現(xiàn) cannot find openssl&#039;s <evp

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

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

    摘要:根據(jù)當(dāng)時(shí)的情境,是在微信開發(fā)者工具中刪掉該小程序然后重新載入就解決了,大家給出的結(jié)論是微信小程序開發(fā)者工具的。 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 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

fantix

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<