#javascript #arrays #optional-chaining
Вопрос:
В JavaScript можно ли сделать что-то похожее на дополнительную цепочку в Array.find? Т. е., как в (неправильном) примере ниже?
let myArray = [{name: "foo", value: 30}, {name: "abc", value: 40}];
myArray.find(entry => entry.name === 'foo')?.value = 50;
Я попробовал приведенный выше синтаксис, но он выдает ошибку, и мне было интересно, есть ли какой-то аккуратный однострочный способ добиться этого без необходимости объявлять другую переменную для хранения массива.найдите результат и проверьте, соответствует ли он действительности, прежде чем вы сможете установить значение = 50.
Комментарии:
1. Эта идея была отклонена комитетом, см. github.com/tc39/proposal-optional-chaining/issues/18
Ответ №1:
Когда вы это сделаете:
({a:1})?.a = 10
То, что вы действительно делаете, это:
1 = 10
Что вызывает ту же ошибку, что и вы наблюдали. Таким образом, вы не можете использовать необязательную цепочку для установки значений.
Предполагая, что вы хотите изменить элемент массива, вы могли бы использовать ??
по умолчанию пустой объект в случае Array#find
возврата null
. Если элемент найден, вы можете изменить его, если нет, вы просто присваиваете 50 объекту, который немедленно отбрасывается:
let myArray = [{name: "foo", value: 30}, {name: "abc", value: 40}];
(myArray.find(entry => entry.name === 'foo') ?? {}).value = 50;
Ответ №2:
Нет, это невозможно. Вы можете использовать только необязательную цепочку для считывания значений.
Необязательная цепочка (?.)
Дополнительный оператор цепочки (?.) позволяет считывать значение свойства, расположенного в глубине цепочки связанных объектов, без необходимости проверять правильность каждой ссылки в цепочке.
Если вы не хотите объявлять дополнительную переменную, вы можете дважды вызвать один и тот же метод, объединенный символом a amp;amp;
, чтобы проверить, имеет ли value
значение, в качестве обходного пути:
let myArray = [
{ name: "foo", value: 30 },
{ name: "abc", value: 40 },
];
myArray.find((entry) => entry.name === "foo").value amp;amp;
(myArray.find((entry) => entry.name === "foo").value = 50);
console.log(myArray);
Другой вариант-просто try
принудительно установить значение…
let myArray = [
{ name: "foo", value: 30 },
{ name: "abc", value: 40 },
];
try { myArray.find((entry) => entry.name === "foo").value = 50; } catch {}
try { myArray.find((entry) => entry.name === "notfound").value = 50; } catch {}
console.log(myArray);
Но ни один из них не является хорошим вариантом.
Комментарии:
1. Дважды-это не нормально)
2. Да, я знаю, что это грязно 🙁
Ответ №3:
Вы не можете использовать необязательную цепочку для установки значений. Он используется только для получения значений.
Ответ №4:
Вы можете использовать это, если вам действительно нужно присвоить значение по ссылке с одной строкой без переменной:
Object.assign(myArray.find(entry => entry.name === 'foo') ?? {}, {value: 50})
Но это грязно