目錄

過去的 JS 互通性

此頁面說明 Dart 先前版本的 JS 互通性,這些版本被視為舊版。它們尚未被棄用,但未來可能會被棄用。因此,請優先使用 dart:js_interop,並盡可能遷移舊互通性函式庫的使用。雖然 dart:html 和其他 Web 函式庫密切相關,但它們會在 package:web 頁面中說明。

dart:js

#

dart:js 公開了一個具體的 物件包裝器,以便與 JS 物件互通。此包裝器包含基於字串的方法,以動態取得、設定和呼叫包裝的 JS 物件上的屬性。由於包裝成本,它的效能較差,而且在人體工學上更難使用。例如,您無法取得程式碼完成,因為您無法宣告互通成員,而是依賴字串。dart:js 中公開的許多功能 (例如 allowInterop) 後來透過其他互通性函式庫重新公開。

自從發佈 package:jsdart:js_util 以來,這個函式庫就一直是一個舊版。它很可能會是第一個被棄用的。

package:js

#

package:js 引入了宣告互通性類型和成員的功能。它允許使用者撰寫互通性類別,而不是互通性擴充類型。在執行階段,這些類別會被刪除為類似於 dart:js_interopJSObject 的類型。

dart
@JS()
class JSType {}

package:js 的使用者會發現 dart:js_interop 的語法和語意很熟悉。您或許可以透過將類別定義替換為擴充類型來遷移至 dart:js_interop,並使其在許多情況下都能運作。

但是,存在顯著差異

  • package:js 類型無法用於與瀏覽器 API 互通。dart:js_interop 類型可以。
  • package:js 允許動態分派。這表示如果您將 package:js 類型轉換為 dynamic 並在其上呼叫互通成員,它會轉送到正確的成員。使用 dart:js_interop 已不再可能。
  • package:js@JS 沒有健全性保證,因為未檢查 external 成員的傳回類型。dart:js_interop 是健全的。
  • package:js 類型無法重新命名實例成員或擁有非 external 成員。
  • package:js 類型可以子類別化,並成為非互通類別的超類型。這通常用於模擬。使用 dart:js_interop,模擬是透過替換 JS 物件來完成。請參閱關於模擬的教學
  • @anonymous 類型是宣告具有物件常值建構子的互通性類型的一種方式。dart:js_interop 不會以這種方式區分類型,任何 external 具名引數建構子都是物件常值建構子。

@staticInterop

#

除了 @JS@anonymous 之外,package:js 後來也公開了 @staticInterop,這是互通性擴充類型的原型。它與 dart:js_interop 一樣具有表達力且具有限制性,並且旨在成為擴充類型可用之前的過渡語法。

@staticInterop 類型會隱式刪除為 JSObject。它需要使用者在擴充中宣告所有實例成員,以便只能使用靜態語意,並具有更強的健全性保證。使用者可以使用它與瀏覽器 API 互動,並且它也允許重新命名和非 external 成員之類的事情。與互通性擴充類型一樣,它不支援動態分派。

幾乎總是可將 @staticInterop 類別遷移至互通性擴充類型,只需將類別變更為擴充類型並移除註解即可。

dart:js_interop 公開了 @staticInterop (以及 @anonymous,但僅當也使用 @staticInterop 時) 以支援靜態互通性語意,直到將擴充類型新增至語言。所有這些類型現在都應遷移至擴充類型。

dart:js_util

#

dart:js_util 提供了一些無法在 package:js 類型中宣告或對於來回傳遞值所必需的實用函式。這包括如下成員:

  • allowInterop (現在是 Function.toJS)
  • getProperty/setProperty/callMethod/callConstructor (現在位於 dart:js_interop_unsafe 中)
  • 各種 JS 運算子
  • 類型檢查協助程式
  • 模擬支援
  • 等等。

dart:js_interopdart:js_interop_unsafe 現在包含這些協助程式,可能具有替代語法。