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 的物件值。

另見