2

我已经设法从一个可编写脚本的对象包装器返回一个 Native DateTime,但是它涉及到具有对范围和上下文的引用的包装器。有没有更好的方法来做到这一点,也许不需要通过这些参考?(这是在 Scala 中使用 JodaTime 库和 Sugar JS 实现的)

测试评估

import org.joda.time.DateTime
import org.mozilla.javascript._

object RhinoTest {

  val sugarScript = {
    val c= Context.enter
    val scope = c.initStandardObjects()
    c.compileString(FileUtil.readAllText("sugar-1.3.7.min.js"), "sugar", 1, null)
  }

  def main(args:Array[String]): Unit = {
    val cx = Context.enter
    val scope = cx.initStandardObjects()
    sugarScript.exec(c1, scope)

    val testDate = new DateTime(2010,10,10, 0, 0)
    val wrapper = Wrapper(Map("date" -> testDate),cx, scope)
    ScriptableObject.putProperty(scope, "map", wrapper)
    println(c1.evaluateString(scope,"Date.create('Tuesday').isBefore(map.date)", "Source", 1, null))
  }
}

和包装类

case class Wrapper(map:Map[String,Any], cx:Context, scope:Scriptable) extends ScriptableObject {

  def getClassName() = "Wrapper"

  override def get(name:String, start:Scriptable):Object =
    (map.getOrElse(name, null) match {
      case d:DateTime => {
        val a = List[AnyRef](d.getMillis.asInstanceOf[java.lang.Long]).toArray
        cx.newObject(scope, "Date", a)
      }
      case a => a
    }).asInstanceOf[AnyRef]
}
4

1 回答 1

0

没有办法Date以原子方式转换NativeDate。您必须自己执行转换。

在此处查看类似问题的答案

默认情况下,Rhino 不会将 Java Number 和 String 对象转换为相应的原始类型。相反,它将它们包装到一个特殊的脚本对象中,就像它通过 LiveConnect 将任何其他 JavaObject 暴露给脚本一样,它只将原始 Java 值转换为相应的脚本值。要覆盖它,您需要提供一个自定义 WrapHandler(即将推出的 Rhino 1.5R4 中的 WrapFactory)。

JavaScript 中的 java.util.Date 和 Date 对象的不同之处不仅在于它们的 API,还在于其内部表示。特别是,Script 中的 Date 可以保存 NaN 值,而 java.util.Date 不能。由于这些原因,最好留给应用程序来决定如何将一个转换为另一个。

要考虑的一件事是在运行脚本之前执行转换,避免任何包装器:

Object nativeDate = cx.newObject(scope, "Date", new Object[] {new Date().getTime()})
ScriptableObject.putProperty(scope, "date", nativeDate)
于 2016-08-26T22:58:41.063 回答