摘要:比如的,的提供訪問安全對象的支持。在使用的情況下,這意味著表達(dá)式在達(dá)到其第一個(gè)假值后將停止向后執(zhí)行。這便可用于安全地訪問嵌套屬性。與上述短路示例類似,此方法通過檢查值是否為假來進(jìn)行操作。該方法優(yōu)于該方法的地方是避免屬性名稱的重復(fù)。
Uncaught TypeError: Cannot read property "foo" of undefined.這種錯(cuò)誤想必在我們?nèi)粘i_發(fā)中都到過,這有可能是我們的api返回了一個(gè)空的狀態(tài)而我們沒有預(yù)料到,也可能是其他,我們無從得知,因?yàn)檫@種問題十分的常見且涉及的因素相當(dāng)多。
我最近遇到了一個(gè)問題,某些環(huán)境變量由于某種原因沒有被引入,導(dǎo)致各種各樣的問題,一堆錯(cuò)誤出現(xiàn)在我的眼前。無論原因是什么,它可能是一個(gè)災(zāi)難性的錯(cuò)誤,那么我們?nèi)绾尾拍苁紫确乐顾兀?/p>
讓我們來看看解決辦法。
工具庫如果你已經(jīng)使用了某種工具庫,很可能內(nèi)部就包含了相關(guān)的錯(cuò)誤處理函數(shù)。比如lodash的_.get,Ramda的R.path提供訪問安全對象的支持。
如果沒有使用呢?那就看看下面的解決辦法。
使用&&實(shí)現(xiàn)「短路與」在Javascript中一個(gè)有趣的事情是,邏輯運(yùn)算操作不一定返回boolean值。根據(jù)規(guī)范,&&和||運(yùn)算符返回的值不一定需要為boolean類型,它的返回值為該運(yùn)算符左右兩邊表達(dá)式的其中一個(gè)。
&&中,如果第一個(gè)表達(dá)式為false則直接返回,否則就用第二個(gè)。舉個(gè)例子:0&&1 -> 0,2&&3 -> 3。如果是鏈?zhǔn)绞褂?b>&&的話,將會(huì)判斷第一個(gè)假值或者最后一個(gè)真值。比如:1 && 2 && 3 && null && 4? -> null,1 && 2 && 3 -> 3。
這對安全地訪問嵌套對象屬性有什么作用呢?JavaScript中的邏輯運(yùn)算符將「短路」。在使用&&的情況下,這意味著表達(dá)式在達(dá)到其第一個(gè)假值后將停止向后執(zhí)行。
??const foo = false && destroyAllHumans(); ??console.log(foo); // false, and humanity is safe
在上面代碼中,因?yàn)?b>&&遇到了false值,destroyAllHumans將永遠(yuǎn)不會(huì)被執(zhí)行。
這便可用于安全地訪問嵌套屬性。
const meals = { ?? breakfast: null, // I skipped the most important meal of the day! :( ?? lunch: { ?? protein: "Chicken", ?? greens: "Spinach", ?? }, ?? dinner: { ?? protein: "Soy", ?? greens: "Kale", ?? }, ??}; ?? ??const breakfastProtein = meals.breakfast && meals.breakfast.protein; // null ??const lunchProtein = meals.lunch && meals.lunch.protein; // "Chicken
這種辦法不僅簡單,而且在處理短鏈時(shí)也非常的簡潔。但是當(dāng)訪問更深層的對象時(shí),這可能就會(huì)變得非常冗長。
const favorites = { ?? video: { ?? movies: ["Casablanca", "Citizen Kane", "Gone With The Wind"], ?? shows: ["The Simpsons", "Arrested Development"], ?? vlogs: null, ?? }, ?? audio: { ?? podcasts: ["Shop Talk Show", "CodePen Radio"], ?? audiobooks: null, ?? }, ?? reading: null, // Just kidding -- I love to read ??}; ?? ??const favoriteMovie = favorites.video && favorites.video.movies && favorites.video.movies[0]; ??// Casablanca ??const favoriteVlog = favorites.video && favorites.video.vlogs && favorites.video.vlogs[0]; ??// null
嵌套的對象越深,它就越難以描述。
Maybe MonadOliver Steele提出了這種方法,并在他的博客文章Monads on the Cheap I:The Maybe Monad中進(jìn)行更詳細(xì)地介紹。我將在這里作一個(gè)簡單的解釋。
const favoriteBook = ((favorites.reading||{}).books||[])[0]; // undefined ??const favoriteAudiobook = ((favorites.audio||{}).audiobooks||[])[0]; // undefined ??const favoritePodcast = ((favorites.audio||{}).podcasts||[])[0]; // "Shop Talk Show"
與上述短路示例類似,此方法通過檢查值是否為假來進(jìn)行操作。如果是,它將嘗試訪問空對象上的下一個(gè)屬性。在上面的例子中,favorites.reading為null,所以books從一個(gè)空對象進(jìn)行訪問。而此時(shí)的返回值也將是undefined,于是[0]將從一個(gè)空數(shù)組中獲取。
該方法優(yōu)于該&&方法的地方是避免屬性名稱的重復(fù)。在更深層的對象上,這可能是一個(gè)非常重要的優(yōu)勢。主要的缺點(diǎn)是可讀性較差。它不是一種常見的模式,可能需要讀者花一點(diǎn)時(shí)間來解析它是如何工作的。
try/catch在JavaScript中??try...catch語句允許某函數(shù)安全地訪問屬性。
try { ?? console.log(favorites.reading.magazines[0]); ??} catch (error) { ?? console.log("No magazines have been favorited."); ??}
但問題在于,??try...catch不是一個(gè)表達(dá)式,在某些語言中它不具備直接返回值的能力,一種可行的方法是直接在try...catch定義變量。
let favoriteMagazine; ??try { ?? favoriteMagazine = favorites.reading.magazines[0]; ??} catch (error) { ?? favoriteMagazine = null; /* any default can be used */ ??};
即使要寫不少的代碼,但其實(shí)你也只能定義一個(gè)變量,但如果同時(shí)定義多個(gè)話,就會(huì)有問題。
let favoriteMagazine, favoriteMovie, favoriteShow; ??try { ?? favoriteMovie = favorites.video.movies[0]; ?? favoriteShow = favorites.video.shows[0]; ?? favoriteMagazine = favorites.reading.magazines[0]; ??} catch (error) { ?? favoriteMagazine = null; ?? favoriteMovie = null; ?? favoriteShow = null; ??}; ?? ??console.log(favoriteMovie); // null ??console.log(favoriteShow); // null ??console.log(favoriteMagazine); // null
如果訪問該屬性的任何嘗試失敗,則會(huì)導(dǎo)致所有這些嘗試都回退到其默認(rèn)值。
另一種方法是將try...catch可重用的實(shí)用程序函數(shù)包裝起來。
const tryFn = (fn, fallback = null) => { ?? try { ?? return fn(); ?? } catch (error) { ?? return fallback; ?? } ??} ?? ??const favoriteBook = tryFn(() => favorites.reading.book[0]); // null ??const favoriteMovie = tryFn(() => favorites.video.movies[0]); // "Casablanca"未完待續(xù)...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/106244.html
摘要:當(dāng)未捕獲的錯(cuò)誤通過處理程序引發(fā)的錯(cuò)誤,而不是捕獲在中被瀏覽器的跨域策略限制時(shí),會(huì)產(chǎn)生這類的腳本錯(cuò)誤。例如,如果您將您的代碼托管在上,則任何未被捕獲的錯(cuò)誤將被報(bào)告為腳本錯(cuò)誤而不是包含有用的堆棧信息。 譯者按: null/undefined引發(fā)的錯(cuò)誤在10大錯(cuò)誤中比例很高。而它們很可能導(dǎo)致嚴(yán)重問題,所以要重視起來。 原文: Top 10 JavaScript errors from 10...
摘要:由于是以空函數(shù)為代理對象,我們可以將執(zhí)行它,觸發(fā)。中會(huì)遍歷數(shù)組依次取值,如果發(fā)現(xiàn)無法繼續(xù)取值則,跳出循環(huán)。 本文來自我的博客,歡迎大家去GitHub上star我的博客 我們在取值特別是鏈?zhǔn)饺≈档臅r(shí)候,常常會(huì)遇到Cannot read property xx of undefined的錯(cuò)誤,如何避免這種情況的發(fā)生呢?這里有幾種方法以供參考 使用成熟的庫方法 這是最簡單的一種手段:只用引入...
摘要:表示錯(cuò)誤沒有被語句捕獲,是錯(cuò)誤的名字。如何修復(fù)錯(cuò)誤確保方法名正確。這個(gè)錯(cuò)誤的行號將指出正確的位置。相關(guān)錯(cuò)誤代碼調(diào)用的方法在當(dāng)前狀態(tài)無法調(diào)用。通常由引起,在方法準(zhǔn)備完畢之前調(diào)用它會(huì)引起錯(cuò)誤。原文翻譯出處涂鴉碼農(nóng)錯(cuò)誤以及如何修復(fù) (看到一篇調(diào)試JS很有用的文章,收藏一下) JavaScript 調(diào)試是一場噩夢:首先給出的錯(cuò)誤非常難以理解,其次給出的行號不總有幫助。有個(gè)查找錯(cuò)誤含義,及修復(fù)...
摘要:常出現(xiàn)的錯(cuò)誤前十位為了可讀性,錯(cuò)誤名稱進(jìn)行了一定的簡寫。讓我們深入了解每個(gè)錯(cuò)誤發(fā)生的原因以及解決方法。這個(gè)問題很容易解決。當(dāng)未捕獲的錯(cuò)誤跨越違法跨域策略的域邊界時(shí),會(huì)發(fā)生腳本錯(cuò)誤。這是當(dāng)你在中試圖調(diào)用的方法時(shí)出現(xiàn)的錯(cuò)誤。 JavaScript常出現(xiàn)的錯(cuò)誤前十位 showImg(https://segmentfault.com/img/bV3Z1z?w=1116&h=691); 為了可讀...
摘要:做法是檢查用戶是否存在,如果不存在,就創(chuàng)建一個(gè)空對象,這樣,下一個(gè)級別的鍵將始終從存在的對象訪問。使用數(shù)組訪問嵌套對象方法非常強(qiáng)大,可用于安全地訪問嵌套對象。除了安全訪問嵌套對象之外,它還可以做很多很棒的事情。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! JavaScript 是個(gè)很神奇的東西。但是 JavaScript中的一些東西確實(shí)很奇怪,讓人摸不著頭腦。...
閱讀 2160·2023-04-25 18:49
閱讀 1872·2019-08-30 14:02
閱讀 2676·2019-08-29 17:24
閱讀 3349·2019-08-28 18:10
閱讀 2956·2019-08-28 18:03
閱讀 516·2019-08-26 12:01
閱讀 3342·2019-08-26 11:31
閱讀 1460·2019-08-26 10:29