#javascript #arrays #null #object-destructuring #nullish-coalescing
Вопрос:
Есть ли лучший способ обработки null
значений в приведенном ниже примере. В записях 5, 7 и 10 присутствует null
значение.
Следующие ошибки отображаются независимо от того, является ли значение null
или undefined
.
#5 - Uncaught TypeError: Cannot read property 'id' of null
#7 - Uncaught TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))
#10 - Uncaught TypeError: Cannot read property 'id' of null
const data = [
{ id: 1, children: [{ id: 'A' }] }, /* 1 */
{ id: 2, children: [{ id: 'B' }] }, /* 2 */
{ id: 3, children: [{ id: 'C' }] }, /* 3 */
{ id: 4, children: [{ }] }, /* 4 */
//{ id: 5, children: [null] }, /* 5 */
{ id: 6, children: [] }, /* 6 */
//{ id: 7, children: null }, /* 7 */
{ id: 8 }, /* 8 */
{ }, /* 9 */
//null /* 10 */
];
const ids = data.map(
({
id = -1,
children: [
{
id: childId = -1
} = {}
] = []
} = {}) =>
({ id, childId })
);
console.log(ids);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Следующее работает, но менее элегантно. Это требует использования операторов, объединяющих нулевое значение (или логических операторов ИЛИ), необязательной цепочки и нескольких назначений.
const data = [
{ id: 1, children: [{ id: 'A' }] }, /* 1 */
{ id: 2, children: [{ id: 'B' }] }, /* 2 */
{ id: 3, children: [{ id: 'C' }] }, /* 3 */
{ id: 4, children: [{}] }, /* 4 */
{ id: 5, children: [null] }, /* 5 */
{ id: 6, children: [] }, /* 6 */
{ id: 7, children: null }, /* 7 */
{ id: 8 }, /* 8 */
{ }, /* 9 */
null /* 10 */
];
const ids = data.map(item => {
const
ref = item ?? {},
children = ref.children ?? [],
child = children[0] ?? {};
return {
id: ref?.id ?? -1,
childId: child?.id ?? -1
};
});
console.log(ids);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Я мог бы переписать это как вложенную ЖИЗНЬ, но следовать ей сложнее… Как вы можете видеть, я избегал использовать значения параметров по умолчанию, потому что вы можете только деструктировать undefined
значения. Значение null
является допустимым, поэтому я должен использовать логическое » ИЛИ » (операция слияния нулей тоже сработала бы), чтобы определить альтернативу.
const data = [
{ id: 1, children: [{ id: 'A' }] }, /* 1 */
{ id: 2, children: [{ id: 'B' }] }, /* 2 */
{ id: 3, children: [{ id: 'C' }] }, /* 3 */
{ id: 4, children: [{ id: null }] }, /* 4 (NEW) */
{ id: 5, children: [{}] }, /* 5 */
{ id: 6, children: [null] }, /* 6 */
{ id: 7, children: [] }, /* 7 */
{ id: 8, children: null }, /* 8 */
{ id: 9 }, /* 9 */
{ }, /* 10 */
null /* 11 */
];
const ids = data.map(item =>
(ref =>
((id, children) =>
(child =>
((childId) =>
({ id, childId }))
(child.id || -1))
(children[0] || {}))
(ref.id || -1, ref.children || []))
(item || {}));
console.log(ids);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Ответ №1:
Вы могли бы отказаться от множества заданий. Я не вижу никаких проблем с использованием нулевого объединения и необязательной цепочки.
const data = [
{ id: 1, children: [{ id: 'A' }] }, /* 1 */
{ id: 2, children: [{ id: 'B' }] }, /* 2 */
{ id: 3, children: [{ id: 'C' }] }, /* 3 */
{ id: 4, children: [{ id: null }] }, /* 4 (NEW) */
{ id: 5, children: [{}] }, /* 5 */
{ id: 6, children: [null] }, /* 6 */
{ id: 7, children: [] }, /* 7 */
{ id: 8, children: null }, /* 8 */
{ id: 9 }, /* 9 */
{ }, /* 10 */
null /* 11 */
];
const ids = data.map(item => ({
id: item?.id ?? -1,
childId: item?.children?.[0]?.id ?? -1
}));
console.log(ids);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Комментарии:
1. Может быть, это я, но я думаю, что на самом деле это намного более читабельно, чем любой из вариантов в вопросе