Categories
Modern JavaScript

Best of Modern JavaScript — Super Calls and Private Variables

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.

Superconstructor Calls

We’ve to call super before we call anything else.

For example, we can’t write:

class Foo {}

class Bar extends Foo {
  constructor(foo) {
    this.foo = foo;
    super();
    this.bar = bar;
  }
}

The first line must be the super call.

Instead, we write:

class Foo {}

class Bar extends Foo {
  constructor(foo) {
    super();
    this.foo = foo;
    this.bar = bar;
  }
}

Removing the super call also gives us an error. So we can’t write:

class Foo {}

class Bar extends Foo {
  constructor() {}
}

Overriding the Result of a Constructor

We can override the result of a constructor by returning something we want in the constructor .

For example, we can write:

class Foo {
  constructor() {
    return {};
  }
}

Then when we log:

console.log(new Foo() instanceof Foo);

We get false returned.

It doesn’t matter whether this is initialized or not since we’re returning an object instead returning this implicitly in our constructor.

We don’t have to call super in the child constructor if we override the result as we did in the example.

Default Constructors for Classes

We don’t need to specify an empty constructor if we don’t put anything in there.

So if we have:

`constructor()` `{}`

we can remove it.

For derived classes, we don’t need to add a constructor just to call the super constructor.

So we don’t have to write:

constructor(...args) {
  super(...args);
}

in our code.

Subclassing Built-in Constructors

We can create subclasses of built-in constructors.

For example, we can write:

class SomeError extends Error {}
throw new SomeError('error');

We create a subclass of Error with the extends keyword.

Then we can throw it like any other Error instance.

We can also create subclasses of the Array constructor.

For example, we can write:

class Stack extends Array {
  get first() {
    return this[0];
  }
}

Then we can create a new Stack instance and use the available Array properties:

class Stack extends Array {
  get first() {
    return this[0];
  }
}

const stack = new Stack();
stack.push('foo');
stack.push('bar');
console.log(stack.first);
console.log(stack.length);

We called pusg to push entries to our Stack instance.

Then we get the first and length properties.

first is the getter we defined.

And length is inherited from Array .

Private Data for Classes

JavaScript classes have no private members.

If we want private data, then we’ve to hide them somewhere else.

Or we can just create public members with a special naming scheme to indicate that they’re private.

We can just add an underscore before the property to indicate that they’re private.

For example, we can write;

class Foo {
  constructor() {
    this._count = 0;
  }
}

we add the this._count instance property to indicate that count is private.

We can also store private properties with weak maps and symbols.

For instance, we can write:

const _count = new WeakMap();

class Counter {
  constructor(count) {
    _count.set(this, count);
  }

  increment() {
    let count = _count.get(this);
    count++;
    _count.set(this, count);
  }
}

We create 2 weak maps and use this as the key for both weak maps.

The values are set to what we pass into the constructor.

Then we can get the value with the weak map’s get method.

And set the value with the set method.

Weak maps are useful since we can access the values with this , preventing the items inside from being accessed any other way.

Conclusion

There are several things we’ve to look at when we call super .

Also, there are no easy ways to keep variables private.

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 *