В моем коде я имею дело с массивом, в котором есть записи со множеством объектов, вложенных друг в друга, а некоторых нет. Это выглядит примерно так:
// where this array is hundreds of entries long, with a mix
// of the two examples given
var test = [{'a':{'b':{'c':"foo"}}}, {'a': "bar"}];
Это вызывает у меня проблемы, потому что мне нужно время от времени перебирать массив, а несогласованность вызывает такие ошибки:
for (i=0; i<test.length; i++) {
// ok on i==0, but 'cannot read property of undefined' on i==1
console.log(a.b.c);
}
Я знаю, что могу сказать if(a.b){ console.log(a.b.c)}
, но это чрезвычайно утомительно в тех случаях, когда имеется до 5 или 6 объектов, вложенных друг в друга. Есть ли другой (более простой) способ сделать так, чтобы он ТОЛЬКО делал console.log, если он существует, но без выдачи ошибки?
javascript
Ari
источник
источник
try..catch
инструкцию. Тем не менее, массив, содержащий крайне разнородные элементы, мне кажется проблемой дизайна.if ("b" in a && "c" in a.b)
. Это может быть «утомительно», но это то, что вы получите за несогласованность ... нормальную логику.Ответы:
Обновление :
Решение для JavaScript до ECMASCript 2020 или TypeScript до версии 3.7 :
Быстрый обходной путь - использование вспомогательной функции try / catch с функцией стрелки ES6 :
Рабочий фрагмент:
Показать фрагмент кода
Подробнее см. В этой статье .
источник
То, что вы делаете, вызывает исключение (и это справедливо).
Вы всегда можете сделать
Но я бы не стал думать о вашем варианте использования.
Почему вы получаете доступ к данным, 6 уровням вложенности, которые вам незнакомы? Какой вариант использования оправдывает это?
Обычно вы действительно хотите проверить, с каким объектом вы имеете дело.
Кроме того, на стороне примечания вы не должны использовать такие утверждения, как,
if(a.b)
потому что он вернет false, если ab равно 0 или даже если оно равно «0». Вместо этого проверьте, еслиa.b !== undefined
источник
typeof a.b === "undefined" && a.b!=null
- ненужно делать вторую часть после первой, и имеет смысл просто сделатьif ("b" in a)
typeof a.b !
== "undefined" && ab! = Null` - обратите внимание на!==
Если я правильно понимаю ваш вопрос, вам нужен самый безопасный способ определить, содержит ли объект свойство.
Самый простой способ - использовать
in
оператор .Конечно, вы можете вложить это так глубоко, как хотите
Не уверен, что это поможет.
источник
window.b
не определено? Вы получите ошибку типа:Cannot use 'in' operator to search for 'c' in undefined
Если вы используете lodash , вы можете использовать их функцию has. Он похож на родной "in", но допускает пути.
источник
_.get()
умолчанию для удобства чтения:_.get(object, 'a.b.c', 'default');
Попробуй это. Если
a.b
не определено,if
оператор оставит оператор без исключения.источник
Это обычная проблема при работе с глубокими или сложными объектами json, поэтому я стараюсь избегать попыток / перехвата или встраивания нескольких проверок, которые могут сделать код нечитаемым. Обычно я использую этот небольшой фрагмент кода во всех своих процедурах для выполнения работы.
источник
Если у вас есть lodash, вы можете использовать его
.get
методили укажите значение по умолчанию
источник
Я неукоснительно использую undefsafe . Он проверяет каждый уровень вашего объекта до тех пор, пока он либо не получит запрошенное вами значение, либо не вернет «undefined». Но ни разу ошибок.
источник
_.get
Если вы используете Babel, вы уже можете использовать необязательный синтаксис цепочки с плагином @ babel / plugin-scheme-optional-chaining Babel . Это позволит вам заменить это:
с этим:
источник
Мне нравится ответ Цао Шоугуана, но я не люблю передавать функцию в качестве параметра в функцию getSafe каждый раз, когда я выполняю вызов. Я модифицировал функцию getSafe, чтобы она принимала простые параметры и чистый ES5.
источник
getSafe(myObj.x.c)
. Пробовал последние версии Chrome и Firefox.В ответе str будет возвращено значение undefined вместо установленного значения по умолчанию, если свойство не определено. Иногда это может вызвать ошибки. Следующее гарантирует, что defaultVal всегда будет возвращаться, если свойство или объект не определены.
источник
В Lodash есть
get
метод, который позволяет использовать значение по умолчанию в качестве необязательного третьего параметра, как показано ниже:источник
Представьте, что мы хотим применить ряд функций к тому
x
и только тогда, когда неx
равно нулю:Теперь предположим, что нам нужно сделать то же самое для
y
:И то же самое
z
:Как видите, без надлежащей абстракции мы в конечном итоге будем дублировать код снова и снова. Такая абстракция уже существует: Возможно монада .
Может быть , монада имеет как значение и вычислительный контекст:
Наивная реализация выглядела бы так:
⚠️ Эта реализация предназначена только для иллюстрации! Так делать не следует, и это неправильно на многих уровнях. Однако это должно дать вам лучшее представление о том, о чем я говорю.
Как видите, ничего не сломается:
Приложение 1
Я не могу объяснить, что такое монады, поскольку это не является целью этого поста, и есть люди, которые справляются с этим лучше, чем я. Однако, как сказал Эрик Эллиот в своем блоге, JavaScript Monads Made Simple :
Приложение 2
Вот как я бы решил вашу проблему с помощью Maybe монаду изmonetjs
источник
Я уже отвечал на этот вопрос раньше и сегодня проводил аналогичную проверку. Упрощение проверки наличия вложенного свойства с точками. Вы можете изменить это, чтобы вернуть значение или какое-то значение по умолчанию для достижения вашей цели.
В своем вопросе вы могли бы сделать что-то вроде:
источник
Я обычно использую вот так:
источник
Чтобы избежать ошибки, укажите значение по умолчанию перед получением свойства.
Это отлично работает и с массивами:
источник