In ES5, I could check the existence of a "class" (constructor function) on the window object:
if (window.MyClass) {
... // do something
}
In ES6, according to this article, globally-declared classes are globals, but not properties of the global object (window
, on browsers):
But there are now also global variables that are not properties of the global object. In global scope, the following declarations create such variables:
let
declarationsconst
declarations- Class declarations
So if I can't use if (window.MyClass)
, is there a way to do the same?
Actually is there a proper way to do this without using window object ?
Only if the constructor function was a global, which is poor practice.
Correct. (The same is true of
let
andconst
declarations at global scope.) This is defined in §8.1.1.4: Global Environment Records:(My emphasis) So the things that used to go on the global object in ES5 and earlier still do (plus generators, because it would have been even more confusing if they didn't), but the new things (
let
,const
, andclass
declarations) don't. They're globals, but not properties of the global object.Back to your question...
You could use
...since
typeof
on an unresolvable symbol doesn't throw aReferenceError
. This also has the advantage of checking whetherMyClass
is in scope for the code, even if it's not global.There's a gotcha there though: If that code is in the same scope where
MyClass
is declared viaclass
(orlet
orconst
) but it's aboveMyClass
in that scope, even thetypeof
check will throw aReferenceError
, because you can't access the binding it creates at all (not even withtypeof
) before theclass
(orlet
orconst
).E.g., this will throw:
The space from the beginning of the scope to the
class
,let
, orconst
line is called the temporal dead zone (TDZ) and you can't access the variable binding at all. Consequently, you have to catch theReferenceError
:Until JavaScript modules make it to broad browser support, there are a couple of ways:
Use an Asynchronous Module Definition library of some kind to handle loading your modules. Some examples: RequireJS, SystemJS, CommonJS
Have a single global variable that you'll use to refer to an object, and make your various application globals properties of that object. Here's a typical way to do that:
This also gives you a handy scope (the anonymous function) in which to put any module-level globals.