SyntaxError: new keyword cannot be used with an optional chain

JavaScript 异常“new 关键字不能与可选链一起使用”发生于 new 表达式的构造函数是可选链,或者构造函数和带括号的参数列表之间存在可选链时。

消息

SyntaxError: Invalid optional chain from new expression (V8-based)
SyntaxError: new keyword cannot be used with an optional chain (Firefox)
SyntaxError: Cannot call constructor in an optional chain. (Safari)

错误类型

SyntaxError

哪里出错了?

有两种方式会导致此错误。第一种是构造函数表达式是一个可选链表达式,像这样:

js
new Intl?.DateTimeFormat();
Number?.[parseMethod]`Hello, world!`;

第二种是 ?. 出现在构造函数和参数列表之间,像这样:

js
new Intl.DateTimeFormat?.();

显式禁止可选 new 是因为其语法复杂(带参数和不带参数的 new),并且结果不明确(这将是 new 不求值为对象值的唯一情况)。你需要将可选链转换为其底层条件(有关更多信息,请参阅可选链)。

js
const result =
  Intl.DateTimeFormat === null || Intl.DateTimeFormat === undefined
    ? undefined
    : new Intl.DateTimeFormat();

请记住,可选链只在带括号的单元内短路。如果你将构造函数表达式括起来,可选链将不会导致错误,因为此时构造函数不会短路,并且结果是明确的(构造函数将产生 undefined,然后导致 new 表达式抛出错误)。

js
new (Intl?.DateTimeFormat)(); // Throws if Intl?.DateTimeFormat is undefined

然而,这在某种程度上是无意义的,因为可选链阻止了属性访问链中的错误,但随后在调用 new 时肯定会产生错误。你可能仍然希望使用条件检查。

请注意,可选链仅作为构造函数表达式被禁止。你可以在参数列表内使用可选链,或者在整个 new 表达式上使用可选链。

js
new Intl.DateTimeFormat(navigator?.languages);
new Intl.DateTimeFormat().resolvedOptions?.();

请注意,没有必要在 new 表达式本身上使用 ?.new a()?.b,因为 new 保证会产生一个非空ish 的对象值。

另见