JS 中 Array.find 上的可选链接

Optional chaining on Array.find in JS

在JavaScript中,是否可以在Array.find上做一些类似于可选链的事情?即,就像下面的(不正确的)示例?

let myArray = [{name: "foo", value: 30}, {name: "abc", value: 40}];
myArray.find(entry => entry.name === 'foo')?.value = 50;

我尝试了上面的语法,但它抛出了一个错误,我想知道是否有一些简洁的单行方法来实现这一点,而不必声明另一个变量来存储 Array.find 结果并检查如果在设置值 = 50 之前它是真实的。

您不能使用可选链接来设置值。它仅用于获取值。

不,这不可能。您只能使用可选链接来读取值。

Optional chaining (?.)

The optional chaining operator (?.) enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid.

source

如果您不想声明一个额外的变量,您可以调用相同的方法两次,并通过 && 组合以检查 value 是否有值,解决方法是:

let myArray = [
  { name: "foo", value: 30 },
  { name: "abc", value: 40 },
];
myArray.find((entry) => entry.name === "foo").value &&
  (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);

但这两个都不是好的选择。

如果你真的需要用一行没有变量的引用赋值,你可以这样使用:

Object.assign(myArray.find(entry => entry.name === 'foo') ?? {}, {value: 50})

但是很脏

当你这样做时:

({a:1})?.a = 10

你真正在做的是:

1 = 10

这会导致与您观察到的错误相同的错误。所以你不能使用可选链接来设置值。

假设你想改变数组的元素,你可以做的是使用 ?? 默认为空对象,以防 Array#find returns null。如果找到一个元素,您可以修改它,如果没有,您只是将 50 分配给一个立即被丢弃的对象:

let myArray = [{name: "foo", value: 30}, {name: "abc", value: 40}];
(myArray.find(entry => entry.name === 'foo') ?? {}).value = 50;