Categories
Modern JavaScript

Best of Modern JavaScript — Class Checks and Instantiation

Spread the love

Since 2015, JavaScript has improved immensely.

It’s much more pleasant to use it now than ever.

In this article, we’ll look at how to define classes with JavaScript.

Class Details

There are many details in classes.

The value we extend can be an arbitrary expression.

For example, we can extend a class that’s resulted from calling a function:

class Foo extends combine(Foo, Bar) {}

Checks

The JavaScript interpreter makes some checks when we create our classes.

A class name can’t be eval or arguments .

Duplicate class names aren’t allowed.

The name constructor can be used for a normal method and not getters, setters, or generator methods.

Classes can’t be called as a function.

If we do, a TypeError will be thrown.

Prototype methods can’t be used as constructors.

So we can’t write something like:

class Foo {
  bar() {}
}
new Foo.prototype.bar();

If we run that, we’ll get the ‘Uncaught TypeError: Foo.prototype.bar is not a constructor’ error.

Property Descriptors

Static properties of a class Bar are writable and configurable but not innumerable.

Bar.prototype isn’t writable, enumerable, or configurable.

Bar.prototype.constructor isn’t writable or enumerable, but it’s configurable.

Properties of Bar.prototype are writable and configurable, but it’s not enumerable.

This means we can update many properties dynamically.

Classes have Inner Names

A class has its own name property to return to its inner name.

Its name can also be used in the class itself.

For example, we can write:

class Foo {
  bar() {
    console.log(Foo.baz);
  }
}
Foo.baz = 1;

We referenced Foo to get the static property.

This is true even if we assign the class to a variable.

For instance, if we have:

const Bar = class Foo {
  bar() {
    console.log(Foo.baz);
  }
}
Bar.baz = 1;new Bar().bar();

Then the bar method call still logs 1.

This means we can refer it with the original name internally.

Subclassing

We create subclasses by using the extends keyword.

For static methods, they’re inherited directly by the subclass.

For instance, if we have:

class Person {
  static logName() {
    console.log(Person.name)
  }
}

class Employee extends Person {}
console.log(Person.logName === Employee.logName)

Then the console log will log true .

The prototype of a JavaScript class is Function.prototype .

This means that the JavaScript class is actually a function.

We can see this by writing:

class Person {
  static logName() {
    console.log(Person.name)
  }
}

console.log(Object.getPrototypeOf.call(Object, Person) === Function.prototype)

We call the Object.getPrototypeOf method to get the prototype of the Person class.

Then we checked that against the Function.prototype .

And this logs true .

So we know classes are functions underneath the hood.

Initializing Instances

Class instances are initialized by writing:

function Person(name) {
  this.name = name;
}

in ES5.

In ES6, the base constructor is created with the super method.

This triggers a parent constructor call.

In ES5, the super constructor is called when we use new to call the constructor.

It’s invoked with the function call.

Conclusion

When we create classes, JavaScript interpreter does many checks.

Also, static methods are inherited by subclasses, and classes are functions.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *