Необязательная цепочка в массиве.найти в JS

#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})
 

Но это грязно