Modern JavaScript: Class Scoping
Welcome to the Class Scoping lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
We usually define classes at the top level of a module. However, classes follow the same scoping rules as regular variables. We can define them inside a function, or even inside a conditional.
>
function createKoko() {class Gorilla {constructor(name) {this.name = name;}}return new Gorilla('Koko');}createKoko().name;Result:
'Koko'
>
function createGorilla(name) {if (name === undefined) {return undefined;} else {class Gorilla {constructor(name) {this.name = name;}}return new Gorilla(name);}}[createGorilla(undefined), createGorilla('Koko').name];Result:
[undefined, 'Koko']
Just to be clear: there are very few cases where a class should be defined in a function. There are even fewer (and maybe none) where a class should be defined inside a conditional. But JavaScript allows us to do these things!
Here's a much better version of the previous code example, where the
Gorillaclass is defined at the top level of the module. Notice how much easier it is to read now thatGorillais defined separately.>
class Gorilla {constructor(name) {this.name = name;}}function createGorilla(name) {if (name === undefined) {return undefined;} else {return new Gorilla(name);}}[createGorilla(undefined), createGorilla('Koko').name];Result:
[undefined, 'Koko']
A class defined dynamically (like inside of a function or even inside of an
if) can see all of the variables that are currently in scope.In the next example, notice that the class's constructor doesn't take a
nameargument. Instead, the class is "capturing" the containing function'snameargument!>
function createGorilla(name) {class Gorilla {constructor() {this.name = name;}}return new Gorilla();}createGorilla('Michael').name;Result:
'Michael'
We can't define a class inside another class. That causes an error, whether we use the class or not.
>
class Zoo {class Gorilla {constructor(name) {this.name = name}}}Result:
SyntaxError: on line 2: Unexpected token
Classes are only visible inside the scope where they were defined, just like variables defined with
letorconst. If we try to reference a class outside of its scope, we'll get an error.>
if (true) {const x = 1;}x;Result:
ReferenceError: x is not defined
>
function createGorilla() {class Gorilla {constructor(name) {this.name = name;}}return new Gorilla('Koko');}new Gorilla('Koko');Result:
ReferenceError: Gorilla is not defined
>
if (true) {class Cat { }}new Cat();Result:
ReferenceError: Cat is not defined