Рубрики
Без рубрики

Доступ к вложенным объектам в JavaScript

Доступ к вложенным объектам в JavaScript, не задыхаясь «Невозможно прочитать свойство неопределенной ошибки»

Автор оригинала: Dinesh Pandiyan.

TLDR; Безопасно доступа к вложенным объектам в JavaScript в супер прохладно.

JavaScript удивительно, мы все уже знаем это. Но несколько вещей в JavaScript действительно странно, и они заставляют нас поцарапать наши головы много. Одним из тех вещей является конфронтация с этой ошибкой, когда вы пытаетесь получить доступ к вложенному объекту,

Не может прочитать свойство ‘foo’ не определено

В большинстве случаев, когда мы работаем с JavaScript, мы будем иметь дело со вложенными объектами, и часто нам нужно будет безопасно получить доступ к внутреннему вложенным значениям.

Давайте возьмем этот вложенный объект в качестве примера.

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

Чтобы получить доступ к названию нашего пользователя, мы напишем

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

Это легко и прямо вперед.

Но по какой-то причине, если личная информация нашей пользователя недоступна, структура объекта будет такой,

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

Теперь, если вы попробуете добраться до имени, вы будете брошены Не удается прочитать свойство «имя» undefined Отказ

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

Это потому, что мы пытаемся получить доступ Имя ключ от объекта, который не существует.

Обычный способ, как большинство Devs справится с этим сценарием,

const name = user && user.personalInfo ? user.personalInfo.name : null;
// undefined error will NOT be thrown as we check for existence before access

Это нормально, если ваша вложенная структура проста, но если у вас есть данные вложены 5 или 6 уровней, то ваш код будет выглядеть очень грязно, как это,

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

Есть несколько трюков для решения этой грязной структуры объектов.

Узор доступа к объектам оливера Стил

Это мой личный любимый, как это делает код выглядеть чистый и простой Отказ Я выбрал этот стиль из Stackoverflow некоторое время назад, и он довольно бросился, когда вы понимаете, как это работает.

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

С этой записью вы никогда не столкнетесь в Не удается прочитать свойство «имя» undefined Отказ Вы в основном проверяете, существует ли пользователь, если нет, вы создаете пустой объект на лету. Таким образом, ключ следующего уровня будет Всегда доступны от объекта, который существует или пустой объект , но никогда от неопределенного.

К сожалению, Вы не можете получить доступ к вложенным массивам с этим трюком

Доступ к вложенным объектам с помощью массива уменьшить

Метод уменьшения массива очень мощный, и его можно использовать для безопасного доступа к вложенным объектам.

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

// pass in your object structure as array elements
const name = getNestedObject(user, ['personalInfo', 'name']);

// to access nested array, just pass in array index as an element the path array.
const city = getNestedObject(user, ['personalInfo', 'addresses', 0, 'city']);
// this will return the city from the first address item.

Типично

Если вы думаете, что вышеупомянутые методы – это слишком мейнстрим, тогда вы должны попробовать Типистые Библиотека, которую я написал. В дополнение к безопасно доступу к вложенным объектам, он делает много более удивительных вещей. 🎉.

Это доступно как пакет NPM – Типично

Если вы используете Типистые Ваш код будет выглядеть так,

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

Снимание Там несколько других библиотек, таких как Лодаш и Рамда, которые могут сделать это. Но в световых передних проектах, особенно если вам нужно понадобиться только один или два метода от этих Libs, это хорошая идея, чтобы выбрать альтернативный весовой вес Lib, или лучше, напишите свой собственный.

Счастливый «безопасно доступ к вложенным объектам в JavaScript»! 💥.