如何覆盖 JS 对象的 toString() 方法以使用 JSON.stringify()?
How to override the toString() method on JS objects to use JSON.stringify()?
我厌倦了在处理我的DTO对象时写blah: "${JSON.stringify(target)}"
,我只想写blah: "$target"
。
我的 DTO 看起来像:
@js.native
trait AuthConnectionDetails extends js.Object {
def clientId: String = js.native
def accountHostname: String = js.native
}
这些 DTO 用于解析某些 REST API 调用的内容,例如:
val response = js.JSON.parse(xmlHttpRequest.responseText).
asInstanceOf[AuthConnectionDetails]
我不介意更改我定义 DTO 对象的方式来执行此操作(也许我应该为我的 DTO 或其他东西使用 case 类,而不是原生 js 特征?),但我可以'不知道该怎么做。
我尝试编写一个我可以混合的特征,但没有用,我尝试编写一个隐式扩展方法,但也没有用。
我的隐式代码似乎不适用于 toString:
object JsonToString {
implicit class JsObjectExtensions(val target: js.Object) extends AnyVal {
override def toString:String = JSON.stringify(target)
def json:String = JSON.stringify(target)
}
}
所以我可以 blah: "${target.json}"
,这更好 - 但我特别想去掉那些牙套。
有什么方法可以用 scala.js 做到这一点吗?
不,没有办法做到这一点。这是因为字符串插值将始终使用对象本身的toString()
方法,无论其类型或隐含的声明是什么类(这通常是 Scala 的事情)。
实现此目的的唯一方法是在每次创建对象时使用自定义 toString()
方法修补它们来实际修改对象。这将包括当您从 JSON 字符串解析它们时。我很确定这比在将它们字符串化时调用 .json
更糟糕。
如果你真的想要,你可以编写你的自定义字符串插值器:
implicit class JsonHelper(private val sc: StringContext) extends AnyVal {
def dejson(args: Any*): JSONObject = {
sc.checkLengths(args)
s(args.map(jsonify))
}
private def jsonify(arg: Any) = arg match {
case obj: js.Object => JSON.stringify(obj)
case _ => arg.toString
}
}
您现在可以像这样使用它:
dejson"hello: $target, world: $target2"
我厌倦了在处理我的DTO对象时写blah: "${JSON.stringify(target)}"
,我只想写blah: "$target"
。
我的 DTO 看起来像:
@js.native
trait AuthConnectionDetails extends js.Object {
def clientId: String = js.native
def accountHostname: String = js.native
}
这些 DTO 用于解析某些 REST API 调用的内容,例如:
val response = js.JSON.parse(xmlHttpRequest.responseText).
asInstanceOf[AuthConnectionDetails]
我不介意更改我定义 DTO 对象的方式来执行此操作(也许我应该为我的 DTO 或其他东西使用 case 类,而不是原生 js 特征?),但我可以'不知道该怎么做。
我尝试编写一个我可以混合的特征,但没有用,我尝试编写一个隐式扩展方法,但也没有用。
我的隐式代码似乎不适用于 toString:
object JsonToString {
implicit class JsObjectExtensions(val target: js.Object) extends AnyVal {
override def toString:String = JSON.stringify(target)
def json:String = JSON.stringify(target)
}
}
所以我可以 blah: "${target.json}"
,这更好 - 但我特别想去掉那些牙套。
有什么方法可以用 scala.js 做到这一点吗?
不,没有办法做到这一点。这是因为字符串插值将始终使用对象本身的toString()
方法,无论其类型或隐含的声明是什么类(这通常是 Scala 的事情)。
实现此目的的唯一方法是在每次创建对象时使用自定义 toString()
方法修补它们来实际修改对象。这将包括当您从 JSON 字符串解析它们时。我很确定这比在将它们字符串化时调用 .json
更糟糕。
如果你真的想要,你可以编写你的自定义字符串插值器:
implicit class JsonHelper(private val sc: StringContext) extends AnyVal {
def dejson(args: Any*): JSONObject = {
sc.checkLengths(args)
s(args.map(jsonify))
}
private def jsonify(arg: Any) = arg match {
case obj: js.Object => JSON.stringify(obj)
case _ => arg.toString
}
}
您现在可以像这样使用它:
dejson"hello: $target, world: $target2"