语法错误: new 关键字不能与可选链一起使用

new 表达式的构造函数是一个 可选链,或者在构造函数和括号内的参数列表之间存在可选链时,会发生 JavaScript 异常 "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)

错误类型

哪里出错了?

有两种方法会导致此错误。第一种是如果构造函数表达式是可选链表达式,例如:

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 保证会产生一个非空值的对象值。

另请参阅