什么时候使用 asInstanceOf?

When to use asInstanceOf?

我正在试用 scalajs,我对如何使用 org.scalajs.dom.html 包访问 DOM 元素感到很困惑。 通过反复试验,我发现有些元素需要使用 asInstanceOf 转换为特定类型,但有些则不需要。是否有关于何时何地需要使用 asInstanceOf 的一般规则?

例如,假设我有一个 ID 为 myinputinput 元素。为了访问输入的值,我需要使用 asInstanceOf:

val content = document.getElementById("myinput").asInstanceOf[html.Input].value

但是当需要在我的div of id contentdiv中显示content时,编译器没有在我没有使用asInstanceOf时报错div 元素:

val mydiv = document.getElementById("contentdiv")
mydiv.innerHTML = content

此外,作为奖励,是否有一个中心位置可以找到所有可能的 asInstanceOf 参数并将它们映射到实际的 HTML 元素?

getElementById的签名是

def getElementById(id: String): DOMElement

DOMElement定义为

trait DOMElement extends js.Object {
  var innerHTML: String = js.native

  def appendChild(child: DOMElement): Unit = js.native
}

因此,每当您调用 getElementById 时,您都会得到一个 DOMElement 返回,您可以对其执行的唯一操作是 innerHTMLappendChild

这就是为什么你的最后一个例子没有显式转换就可以工作的原因。

但是DOMElement是一个非常通用的类型。有时您 知道 getElementById 会 return - 比如说 - <input> 元素。

此时您可以使用 asInstanceOf 将您拥有的这一额外知识告知编译器。

document.getElementById("myinput").asInstanceOf[html.Input].value
                                      ^
                                      |
          hey compiler, I KNOW this is going to be an html.Input,
            please let me do my things and explode otherwise.

不用说了,使用asInstanceOf需要小心。如果你错了,这次编译器将无法将你从运行时崩溃中拯救出来。

回答你问题的第二部分:

is there a central place to find all the possible asInstanceOf arguments and a mapping of them to actual HTML elements?

您可以在 Html.scala 中搜索 "extends HTMLElement"。