它在documentation中说
在原生JS类型中,所有具体定义必须具有= js.native作为主体。任何其他正文将被处理,就像它是= js.native,并将发出警告。 (在Scala.js 1.0.0中,这将成为错误。)
这是对的。然而,我发现我可以省略身体(从而使定义抽象)并且没有警告,生成的js似乎与js.native
身体相同。
所以我的问题是:抽象定义与具有{{1}}主体的具体定义之间的区别是什么?
答案 0 :(得分:1)
不同之处在于抽象定义是抽象的,而且,从Scala的类型系统的角度来看,具体的定义(使用= js.native
)是具体的。
但那又怎么样?从类或特征的 use 站点来看,并没有什么不同。这类似于普通的Scala(或Java):当使用方法时,它是否是抽象的并不重要。
所以真正的区别在于定义网站。从理论上讲,选择抽象或具体可归结为这个标准:
实际上,务实地注意,抽象方法只能出现在抽象类或特征中,并且必须在子类/子特征中实现。
就外观而言,在本地类中,大多数方法应该是具体的(如果不是全部的话)。那是因为在JS中,类通常具有具体的方法。事实上,JS中甚至不存在抽象方法。在本机类中定义抽象方法的唯一合理情况是"合同/文档"该类的规定比a)它应该是子类,b)子类应该实现一个特定的方法(不在超类中实现)。这个记录的合同与JS可以接近抽象方法一样接近。
在JS traits 中,方法通常应该是抽象的(特征本身是@ScalaJSDefined
而不是@js.native
)。那是因为特征/接口本身甚至不存在于JS中。它们仅存在于其记录的合同中,该合同规定了满足此接口的类必须/将要实现的方法。
(@js.native
)JS特征中具体方法的唯一合理用例是DRYness。如果本机API的多个类实现相同(大)的方法集,那么在本机特征中收集这些方法是合理的。为了不必在所有类中重复它们的定义,它们可以在特征中具体化(如果它们是抽象的,则类需要提供具体版本以满足合同)。请注意,非本机(@ScalaJSDefined
)JS类不能扩展此类特征。
如果你不想弄清楚上述"理论"标准,使用以下经验法则:
@ScalaJSDefined
)。