For example, one can define a variable
foo at the top-level of a script:
which then makes it available in the global scope, so that another script can read or write it:
The facade types reference explains how we can define facades for global variables. Here is a recap of the different ways:
@JSGlobalScopespecifies that the annotated object represents the global scope itself, which means its members are global variables.
With the above definitions, the snippet
would “translate” to
There are two “consequences” to that.
First, in any of the 4 above statements, if the referenced variable is not declared as a global variable, a
ReferenceError will be thrown at run-time.
val x = Globals.foo translates to
var x = foo,
g could assume, such that
g.foo would evaluate to the global variable
foo (until ECMAScript 5.1,
g could have been the global object, and this is what Scala.js 0.6.x did).
In general, any “dynamic” reference to a global-scope object is a compile-time error in Scala.js 1.x.
After the above introduction, here is a reference of the compile-time restrictions of global-scope objects.
Globals is an
@JSGlobalScope object, then any use of
Globals must satisfy all of the following requirements:
- It is used as the left-hand-side of a dot-selection, i.e., in
- Either of the 3 alternatives:
foobarrefers to a method annotated with
Global.foobar("ident")is valid but
- Otherwise, if
For the purposes of this test, the special identifier
Here are some concrete examples. Given the following definitions:
Only the following uses of
Globals would be valid:
All of the following uses are compile-time errors:
The case of
js.Dynamic.global is an
@JSGlobalScope object that lets you read and write any field and call any top-level function in a dynamically typed way.
For example, the following uses are valid:
but the following uses are not valid:
The example means that it is not possible to dynamically look up a global variable given its name.
Testing whether a global variable exists
In Scala.js 0.6.x, it was possible to test whether a global variable exists (e.g., to perform a feature test) as follows:
In modern Scala.js, accessing
js.Dynamic.global.Promise will throw a
Promise is not defined, so this does not work anymore.
Instead, you must use
typeof Promise is special, so is
e is a member of a global-scope object (i.e., a global variable).
If the global variable does not exist,
"undefined" instead of throwing a
Dynamically lookup a global variable given its name
If absolutely necessary, one typically has to detect the global object, and use a normal field selection on it.
globalObject is a
js.Dynamic representing the global object, we can do
- Either the global object is available as the global variable named
global(e.g., in Node.js)
- Or the “global”
thiskeyword refers to the global object.
The global variable
global can of course be read with
js.Dynamic.global.global (the double
global is intended).
this can be read with
Together, these can be used to correctly detect the global scope in most environments: