先ほどのScala.jsのチュートリアルサンプルに加えて、JavaScriptでのArrayやリテラルなどをいくつか。
とりあえず、こんな感じにimportしたとしまして。
import scala.scalajs.js import scala.scalajs.js.Dynamic.{global, literal}
Array。
val array = new js.Array[String] array(0) = "zero" array(1) = "one" array(2) = "two" array.push("last") array.foreach(v => global.console.log(v.toString)) // => zero, one, two, last
何気に、ちゃんとジェネリクスが効いているので型安全です。
Arrayオブジェクトのapplyで、JavaScriptのArrayリテラルの代わり?
val forSumArray = js.Array(1, 2, 3, 4, 5) global.console.log(forSumArray.reduceLeft((acc, i) => acc + i))
オブジェクトリテラルらしきもの。
val obj = literal(foo = "bar", num = 3) global.console.log(obj.foo) // => "bar" global.console.log(obj.num) // => 3
キーワード引数でメンバを指定します。
ネストや
val objNested = literal(topLevel = literal(nextLevel = "bar", num = 3)) global.console.log(objNested.topLevel.nextLevel) // => "bar" global.console.log(objNested.topLevel.num) // => 3
関数の保持もできます。
val objHasFunction = literal(func = (s: String) => global.console.log(s"Hello $s!!")) objHasFunction.func("Scala.js") // => Hello Scala.js!!
これらの仕組みは、だいたいScalaのDynamicで実現されているみたいです。
Dictionary。オブジェクトと同じなのかな?添字というか、キーアクセスができます。
val dic = js.Dictionary(("key1", 1), ("key2", 2)) // "key1" -> 1 だと、うまくいかない global.console.log(dic("key1")) // => 1 global.console.log(dic("key2")) // => 2
ただ、タプルを作る時に->はうまく動きませんでした。ここでのStringは、js.Stringに変換されるため、->でのImplicit Conversionと衝突するんでしょうねぇ。
あと、literalを使った時の「this」の表現方法がどうしてもわかりませんでした。classとかを使うべきなのかなぁ?
class SampleClass(val name: String) { def message(pre: String, suf: String): String = s"$pre$name$suf" } val s = new SampleClass("Scala.js") global.console.log(s.message("[", "]")) // => "[Scala.js]"
まあ、これなら普通に使えますが…。
Scala.jsはドキュメントに乏しいので、現時点ではどうしてもソースコードを追うことになりそうです。
今回は、こちらのパッケージから情報を仕入れました。
https://github.com/scala-js/scala-js/tree/master/library/src/main/scala/scala/scalajs/js
あと、作成したソースは以下にアップしています。
https://github.com/kazuhira-r/scala-js-examples/tree/master/scala-js-literals