ScalaJS中js.Dictionary传入JS Map出现size与内容不一致问题
问题原因
Scala.js中的js.Dictionary对应的是JavaScript原生普通对象(即通过{}创建的键值对结构),不是JavaScript ES6新增的Map类型。你直接将JS的Map实例传给接收js.Dictionary的Scala方法属于类型不匹配,这类跨JS/Scala边界的动态类型错误编译期无法识别。
出现打印内容和size不一致的原因:
- 调用
dom.console.log(mapping)时,控制台会按变量实际的原生类型(Map)输出内容,所以能正确展示存储的键值对。 - 而
js.Dictionary的size、foreach、遍历逻辑都是基于普通对象的可枚举自有属性实现的,Map的键值对存储在内部槽中,不会挂载为对象的自有属性,所以这些方法识别不到任何内容,返回size为0。
解决办法
- 方案1:JS侧传入普通对象而非
Map
改造成本最低,不需要修改Scala侧代码:const colorSetting = { "1": "black" }; ScalaJSExample.A(colorSetting) - 方案2:Scala侧修改入参类型为
js.Map
如果JS侧必须使用Map结构,直接将Scala方法的参数改为对应JS原生Map的类型映射即可,所有方法都能正常工作:import scala.scalajs.js def A(mapping: js.Map[String, String]): Unit = { dom.console.log(mapping) dom.console.log(mapping.size) // 正确输出1 } - 方案3:Scala侧做类型转换
如果两端入参类型都不能修改,可在Scala侧做一次类型转换再操作:import scala.scalajs.js import scala.scalajs.js.JSConverters._ def A(mapping: js.Map[String, String]): Unit = { val dict = mapping.toMap.toJSDictionary dom.console.log(dict.size) }
内容的提问来源于stack exchange,提问作者idwx
相关产品推荐
相关产品推荐

