Last Updated: May 31, 2021
·
778
· jiewmeng

JavaScript Classes

Defining a class in JavaScript:

var Person = function(name, email) {
    this.name = name;
    this.email = email;

    // 1 possible way to define a "composite property"
    Object.defineProperty(this, "nameWithEmail", {
        get: function() {
            return this.name + " <" + this.email + ">";
        }
    });

    // I think a simpler way might be to just use a function (see `toString`) 
};

// things defined under prototype will be "shared/inheried" by all classes,
// as opposed to name and email for example 
Person.prototype.sayHi = function() {
    console.log("Hello, my name is " + this.toString());
};

Person.prototype.toString = function() {
    return this.name + " <" + this.email + ">";
};

Now, we can extend the Person class:

// we define the object properties in the constructor function
var Employee = function(name, email, position) {
    Person.call(this, name, email); // calling person constructor: something like super() in other languages
    this.position = position;
};

// extend the Employee class with Person
Employee.prototype = Object.create(Person.prototype);

// override some functions
Employee.prototype.sayHi = function() {
    Person.prototype.sayHi.call(this);
    console.log("I am a " + this.position);
};

An alternative: with underscore.js

// instead of 
// Employee.prototype = Object.create(Person.prototype);
_.extend(Employee.prototype, Person.prototype);

With underscore.js, we can also do multiple inheritance very easily

_.extend(Employee.prototype, Person.prototype);
_.extend(Employee.prototype, {
    doSomething: function() { ... }
});

It doesn't appear to make the prototype chain any longer. However, when you console.log() the prototypes, it appears the one with pure JS is cleaner than the underscore version (less extra methods etc). I posted a question on StackOverflow regarding this.