メインコンテンツまでスキップ

Scala.jsでObjectをFFIする

· 約2分

投稿の内容

本投稿では、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.nameHoge.saySomething("Hello")などのように呼び出すことができるようになりました。