Javascript classes

From wikinotes

Documentation

official docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes


Basics

Constructor

Used to instantiate a class.

class Animal {
    constructor(name) {
        this.name = name  // instance variable (or property)
    }

    speak() {
        console.log('quack')
    }
}

animal = new Animal('maize')
animal.speak()

Fields

Fields declare the availability of an attribute on a class.
They shadow attributes of the same name.

class Animal {
    name
    age = 0
    constructor(name, age) {
        this.name = name
        this.age = age
    }
}

this

The object this refers to the local-context of wherever it is used.
This is different than Java/Cpp where it refers to the instance.

function myFunc() { ... }

class MyClass {
  constructor() { ... }

  myFunc { ... }
}

See https://dmitripavlutin.com/gentle-explanation-of-this-in-javascript/

Access Control

Static Methods/Attrs

static methods/variables are scoped to the class and don't require instantiation.

class Animal {
    static type = 'Cat'
    static do_thing(a, b) { console.log(`${a} ${b}`) }

    foo() {
        this.constructor.do_thing("a", "b");  // call static-method from instance-method
    }
}

Animal.type
Animal.do_thing("a", "b")

Private Methods/Attrs

private methods/attrs are indicated with a # prefix.

class Animal {
    // class
    #CLASS_FIELD
    static #classMethod() { ... }

    // instance
    #instanceField
    #instanceMethod() { ... }

    // usage
    info () {
        this.#classMethod()
        Animal.#CLASS_FIELD

        this.#instanceMethod()
        this.#instanceField
    }
}

Classes

Methods

There are 2x ways to define methods in javascript.

class Foo {
    bar() { ... }             // new way (ecmascript-5+)
    baz: function() { ... }   // old way
}

Methods can be javascript generators.

class Foo {
    * iterate(min, max) { ... }
    iterate: function* (min, max) { ... }
}

Methods can be javascript async methods.

class Foo {
    async* iterate(min, max) { ... }
    iterate: async function* (min, max) { ... }
}

Inheritance

Inheritance is similar to java. Multiple inheritance is not possible.

Extending classes

class Animal {
    constructor(name) {
        this.name = name
    }
}

class Cat extends Animal {  // <-- inherits Animal
    constructor(name) {
        super(name)
    }
}

Extending function classes

const Animal = {
    name() { ... }
}

class Cat {
    // ...
}
Cat.setPrototypeOf(Cat.prototype, Animal)  // <-- inheritance

Interfaces

Javascript does not have interfaces. typescript does though.

Mixins

let FlyerMixin = Base => class extends Base {
    fly() { ... }
    land() { ... }
}

class Animal {
    constructor() { ... }
    speak() { ... }
}

class Bird extends FlyerMixin(Animal) { ... }

let bird = new Bird()
bird.fly()    // from FlyerMixin
bird.speak()  // from Animal

A class can use multiple mixins by nesting them.

class Pelican extends WalkerMixin(SwimmerMixin(FlyerMixin(Animal))) { ... }