溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

在JavaScript中如何訪問(wèn)暫未存在的嵌套對(duì)象

發(fā)布時(shí)間:2020-09-23 10:21:56 來(lái)源:腳本之家 閱讀:131 作者:前端小智 欄目:web開發(fā)

前言

JavaScript 是個(gè)很神奇的東西。但是 JavaScript中的一些東西確實(shí)很奇怪,讓人摸不著頭腦。其中之一就是當(dāng)你試圖訪問(wèn)嵌套對(duì)象時(shí),會(huì)遇到這個(gè)錯(cuò)誤

Cannot read property 'foo' of undefined

在大多數(shù)情況下,處理嵌套的對(duì)象,通常我們需要安全地訪問(wèn)最內(nèi)層嵌套的值。 來(lái)個(gè)粟子:

const user = {
  id: 101,
  email: 'jack@dev.com',
  personalInfo: {
    name: 'Jack',
    address: {
      line1: 'westwish st',
      line2: 'washmasher',
      city: 'wallas',
      state: 'WX'
    }
  }
}

當(dāng)我們要訪問(wèn)user里面的name及city時(shí),我們會(huì)這樣寫。

const name = user.personalInfo.name;
const userCity = user.personalInfo.address.city;

這是簡(jiǎn)單而直接的。

但是,由于某種原因,user 中的 personal不可用,對(duì)象結(jié)構(gòu)將是這樣的:

const user = {
  id: 101,
  email: 'jack@dev.com'
}

現(xiàn)在,如果你在試著訪問(wèn) name ,將會(huì)得到一個(gè) Cannot read property 'name' of undefined 的錯(cuò)誤。

const name = user.personalInfo.name; // Cannot read property 'name' of undefined

這是因?yàn)槲覀冊(cè)噲D訪問(wèn)對(duì)象中不在的 key 為 name 的屬性。

大多數(shù)開發(fā)人員處理這種情況的常用方法如下,

const name = user && user.personalInfo ? user.personalInfo.name : null;

如果你的嵌套結(jié)構(gòu)很簡(jiǎn)單,這是可以的,但是如果數(shù)據(jù)嵌套五或六層深,那么你的代碼就會(huì)看起很混亂:

let city;
if (
  data && data.user && data.user.personalInfo &&
  data.user.personalInfo.addressDetails &&
  data.user.personalInfo.addressDetails.primaryAddress
  ) {
  city = data.user.personalInfo.addressDetails.primaryAddress;
}

有一些技巧可以處理這種混亂的對(duì)象結(jié)構(gòu)。

Oliver Steele的嵌套對(duì)象訪問(wèn)模式

這是我個(gè)人的最愛,因?yàn)樗勾a看起來(lái)干凈簡(jiǎn)單。 我從 stackoverflow 中選擇了這種風(fēng)格,一旦你理解它是如何工作的,它就非常吸引人了。

const name = ((user || {}).personalInfo || {}).name;

使用這種表示法,永遠(yuǎn)不會(huì)遇到無(wú)法讀取未定義的屬性“name”。做法是檢查用戶是否存在,如果不存在,就創(chuàng)建一個(gè)空對(duì)象,這樣,下一個(gè)級(jí)別的鍵將始終從存在的對(duì)象訪問(wèn)。

不幸的是,你不能使用此技巧訪問(wèn)嵌套數(shù)組。

使用數(shù)組Reduce訪問(wèn)嵌套對(duì)象

Array reduce 方法非常強(qiáng)大,可用于安全地訪問(wèn)嵌套對(duì)象。

const getNestedObject = (nestedObj, pathArr) => {
  return pathArr.reduce((obj, key) =>
    (obj && obj[key] !== 'undefined') ? obj[key] : null, nestedObj);
}

// 將對(duì)象結(jié)構(gòu)作為數(shù)組元素傳入
const name = getNestedObject(user, ['personalInfo', 'name']);

// 要訪問(wèn)嵌套數(shù)組,只需將數(shù)組索引作為數(shù)組元素傳入。.
const city = getNestedObject(user, ['personalInfo', 'addresses', 0, 'city']);
// 這將從 addresses 中的第一層返回 city

Typy

如果你認(rèn)為上面的方法太過(guò)非主流,那么可以使用 Typy庫(kù)。除了安全訪問(wèn)嵌套對(duì)象之外,它還可以做很多很棒的事情。

如果使用Typy,代碼將如下所示

import t from 'typy';

const name = t(user, 'personalInfo.name').safeObject;
const city = t(user, 'personalInfo.addresses[0].city').safeObject;
// address is an array

這里還有一些其他的庫(kù),如 Lodash 和 Ramda,可以做到這一點(diǎn)。但是在輕量級(jí)前端項(xiàng)目中,特別是如果你只需要這些庫(kù)中的一兩個(gè)方法時(shí),最好選擇另一個(gè)輕量級(jí)庫(kù),或者編寫自己的庫(kù)。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI