By default, Scala.js classes, objects, methods and properties are not available
annotated explicitly as exported, using
A simple example
This allows to call the
sayHello() method of
HelloWorld like this in
HelloWorld exports the object
to call methods of
HelloWorld. This is why we also have to export the
In general, things that should be exported on the top-level, such as top-level
objects and classes, are exported with
@JSExportTopLevel, while things that
should be exported as properties or methods in JavaScrit are exported with
Exporting top-level objects
Put on a top-level object, the
@JSExportTopLevel annotation exports that
must be specified as an argument to
Pre 0.6.15 note: Before Scala.js 0.6.15, objects were exported as 0-argument
@JSExport, rather than directly with
is deprecated in 0.6.x, and not supported anymore in Scala.js 1.x.
@JSExportTopLevel annotation can also be used to export Scala.js classes
will log the string
"Foo(3)" to the console. This particular example works
because it calls
methods must be exported explicitly as shown in the next section.
As is the case for top-level objects, classes can be exported under a namespace,
by using dots in the argument to
Pre 0.6.15 note: Before Scala.js 0.6.15, classes were exported using
@JSExport instead of
@JSExportTopLevel, with the same meaning. This is
deprecated in 0.6.x, and not supported anymore in Scala.js 1.x.
Exports with modules
Instead, they are genuinely exported from the module.
In that case, an
@JSExportTopLevel annotation has the semantics of an ECMAScript 2015 export.
Similarly to objects, methods of Scala classes, traits and objects can be
@JSExport. Unlike for
@JSExportTopLevel, the name argument is
@JSExport, and defaults to the Scala name of the method.
Given this definition, and some variable
foo holding an instance of
you can call:
they have the same name in Scala, or because they have the same explicit
@JSExport). In that case, run-time overload
resolution will decide which method to call depending on the number and run-time
types of arguments passed to the the method.
For example, given these definitions:
the following calls will dispatch to each of the three methods:
If the Scala.js compiler cannot produce a dispatching code capable of reliably disambiguating overloads, it will issue a compile error (with a somewhat cryptic message):
[error] HelloWorld.scala:16: double definition: [error] method $js$exported$meth$foobar:(i: Int)Any and [error] method $js$exported$meth$foobar:(y: Int)Any at line 14 [error] have same type [error] @JSExport("foobar") [error] ^ [error] one error found
Hint to recognize this error: the methods are named
Note: Since Scala.js 0.6.11,
@JSExportNamed is deprecated, and is not supported anymore in Scala.js 1.x.
Refer to the Scaladoc for migration tips.
It is customary in Scala to call methods with named parameters if this eases understanding of the code or if many arguments with default values are present:
Note that default parameters are not required.
foo can then be called like this:
x in this case will fail at runtime (since it does not have a default value).
@JSExportNamed takes the name of the exported method as an optional argument.
Exporting top-level methods
@JSExported method inside an
@JSExportTopLevel can also be used directory on a method of a top-level
object, which exports the method as a truly top-level function:
defs without parentheses, as well as
defs whose name
_=, have a single argument and
Unit result type, are
using, again, the
Given this weird definition of a halfway mutable point:
As usual, explicit names can be given to
def setters, the
JS name must be specified without the trailing
def setters must have a result type of
Unit and exactly one parameter. Note
def setters with different types for their argument can be
In case you overload properties in a way the compiler cannot
disambiguate, the methods in the error messages will be prefixed by
If you want to export fields that are directly declared in a class constructor, you’ll have to use the
@field meta annotation to avoid annotating the constructor arguments (exporting an argument is nonsensical and will fail):
Export fields to the top level
Similarly to methods, fields (
vars) of top-level objects can be
exported as top-level variables using
foobar to the top-level, so that they can be used from
Note that for
code cannot assign a new value to an exported
var. However, if Scala.js code
consistent with exporting a
let binding in ECMAScript 2015 modules.
Instead of writing
@JSExport on every member of a class or object, you may use the
@JSExportAll annotation. It is equivalent to adding
@JSExport on every public (term) member directly declared in the class/object:
This is strictly equivalent to writing:
It is important to note that this does not export inherited members. If you wish to do so, you’ll have to override them explicitly:
Deprecated: Automatically exporting descendent objects or classes
Pre 0.6.15 note: Before Scala.js 0.6.15, this deprecated feature used to be
often used to “reflectively” instantiate classes and load objects. This use case
has been replaced by the
This feature is not supported anymore in Scala.js 1.x.
When applied to a class or trait,
@JSExportDescendentObjects causes all
objects extending it to be automatically exported as 0-arg functions, under
their fully qualified name. For example:
@JSExportDescendentClasses causes all non-abstract classes
the annotated class or trait to be exported under their fully qualified name.