投稿の内容
本投稿では、JavaScript側で定義されているグローバルオブジェクトをScala.jsで使えるようにする方法をご紹介します。
JS側のオブジェクト
JS側で以下のグローバルオブジェクトが定義されていたとします。
const Hoge = {
name: 'Hoge',
saySomething: (message) => console.log(message),
};
これを例えばHTMLファイル内でロードすると、このHTML内のJSからHogeオブジェクトが使えるようになります。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hoge</title>
</head>
<body>
<script type="text/javascript" src="hoge.js"></script>
</body>
</html>
このHogeオブジェクトをFFIしてScala.js側のコードから使えるようにします。
Scala.js側の定義
JS側のグローバルオブジェクトは、Scala.jsではobjectとして定義できます。ただし、@js.nativeと@JSGlobalの2つのアノテーションが必要です。
objectの名前もJS側のオブジェクトと同じ名前にし、js.Object`を継承する必要があります。
そして、オブジェクトのメンバも同じ名前で定義します。それぞのメンバの挙動は、JS側で実装してあるので、Scala.jsでは実装する必要なく、その代わりにjs.nativeを使います。
import scala.scalajs.js
import scala.scalajs.js.annotation.JSGlobal
@js.native
@JSGlobal
object Hoge extends js.Object {
val name: String = js.native
def saySomething(message: String): Unit = js.native
}
これでScala.js側からHoge.nameやHoge.saySomething("Hello")などのように呼び出すことができるようになりました。