Scala.js外观中的具体和抽象定义

时间:2016-08-29 16:10:44

标签: scala.js

它在documentation中说

  

在原生JS类型中,所有具体定义必须具有= js.native作为主体。任何其他正文将被处理,就像它是= js.native,并将发出警告。 (在Scala.js 1.0.0中,这将成为错误。)

这是对的。然而,我发现我可以省略身体(从而使定义抽象)并且没有警告,生成的js似乎与js.native身体相同。

所以我的问题是:抽象定义与具有{{1}}主体的具体定义之间的区别是什么?

1 个答案:

答案 0 :(得分:1)

不同之处在于抽象定义是抽象的,而且,从Scala的类型系统的角度来看,具体的定义(使用= js.native)是具体的。

但那又怎么样?从类或特征的 use 站点来看,并没有什么不同。这类似于普通的Scala(或Java):当使用方法时,它是否是抽象的并不重要。

所以真正的区别在于定义网站。从理论上讲,选择抽象或具体可归结为这个标准:

  • 此方法在JavaScript代码中是否具有实际的实现(不仅是文档化合同)?如果是,那应该是具体的;如果没有,它应该是抽象的。

实际上,务实地注意,抽象方法只能出现在抽象类或特征中,并且必须在子类/子特征中实现。

就外观而言,在本地类中,大多数方法应该是具体的(如果不是全部的话)。那是因为在JS中,类通常具有具体的方法。事实上,JS中甚至不存在抽象方法。在本机类中定义抽象方法的唯一合理情况是"合同/文档"该类的规定比a)它应该是子类,b)子类应该实现一个特定的方法(不在超类中实现)。这个记录的合同与JS可以接近抽象方法一样接近。

在JS traits 中,方法通常应该是抽象的(特征本身是@ScalaJSDefined而不是@js.native)。那是因为特征/接口本身甚至不存在于JS中。它们仅存在于其记录的合同中,该合同规定了满足此接口的类必须/将要实现的方法。

@js.native)JS特征中具体方法的唯一合理用例是DRYness。如果本机API的多个类实现相同(大)的方法集,那么在本机特征中收集这些方法是合理的。为了不必在所有类中重复它们的定义,它们可以在特征中具体化(如果它们是抽象的,则类需要提供具体版本以满足合同)。请注意,非本机(@ScalaJSDefined)JS类不能扩展此类特征。

如果你不想弄清楚上述"理论"标准,使用以下经验法则:

  • 该方法是否在本机JS类中?如果是的话,几乎肯定是具体的。
  • 是否属于JS特质?如果是,那几乎肯定是抽象的(特征应该是@ScalaJSDefined)。