Skip to content

Instantly share code, notes, and snippets.

@eiriklv
Created August 30, 2017 06:36
Show Gist options
  • Save eiriklv/f1cceb1a7fa40db53f36125645bf2031 to your computer and use it in GitHub Desktop.
Save eiriklv/f1cceb1a7fa40db53f36125645bf2031 to your computer and use it in GitHub Desktop.
ES6 classes

ES6 Classes

ES2015 has introduced the concept of "classes" in JavaScript.

But be aware - JavaScript classes are just syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax is not introducing a new object-oriented inheritance model to JavaScript.

JavaScript classes provides simpler and clearer syntax to create objects and deal with inheritance (proceed with caution.. inheritance vs. composition = specialization vs. sharing behavior).

The existing model of prototypal inheritance in JavaScript is based on a special kind of function and the new keyword, which really just alters how the function behaves regarding what it returns and how it sets up the prototype chain.

Example "class" in JavaScript before the ES6 class syntax:

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

Animal.prototype.speak = function() {
  console.log(this.name + ' makes a noise.');
};

var blub = new Animal('Blub');

blub.speak();
// Blub makes a noise.

Example of extending a class and using super-calls:

/**
 * Create a function that makes a subClass inherit from
 * a superClass (prototypal)
 */
function _inherits(subClass, superClass) {
  /**
   * Inherit the methods from the superClass
   * into the subClass, and overwrite the
   * constructor function
   */
  subClass.prototype = Object.create(superClass.prototype, {
    constructor: subClass,
  });

  /**
   * Set the prototype the subClass
   * to be the prototype of the superClass
   */
  subClass.__proto__ = superClass;
}

/**
 * Create a base class
 */
function Animal(name) {
  this.name = name;
}

/**
 * Add a method to the baseclass
 */
Animal.prototype.speak = function () {
  console.log(this.name + ' makes a noise.');
};

/**
 * Create a subclass that inherits from
 * the baseclass (we're using an IIFE here)
 */
var Dog = (function (_Animal) {
  /**
   * Make our subclass inherit from
   * the baseclass
   */
  _inherits(Dog, _Animal);

  /**
   * Create a constructor for our subclass
   * which calls the constructor for the
   * superclass (this is a super-call)
   */
  function Dog() {
    return _Animal.apply(this, arguments);
  }

  /**
   * Overload the 'speak' method from the
   * baseclass, but also call the original
   * one (this is a super-call)
   */
  Dog.prototype.speak = function speak() {
    _Animal.prototype.speak.call(this);
    console.log(this.name + ' barks.');
  };

  /**
   * Return the extended class
   */
  return Dog;
}(Animal));

/**
 * Create a new instance of the subclass
 */
var d = new Dog('Mitzie');

d.speak();
// Mitzie makes a noise.
// Mitzie barks.

Now instead - you can use the class syntax:

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

  speak() {
    console.log(this.name + ' makes a noise.');
  }
}

class Dog extends Animal {
  speak() {
    super.speak();
    console.log(this.name + ' barks.');
  }
}

var d = new Dog('Mitzie');

d.speak();
// Mitzie makes a noise.
// Mitzie barks.

These two approaches are identical in functionality, but the class syntax provides a cleaner way of creating classes. It's also important to note that multiple inheritance is not supported out of the box and is something that you'll have to implement yourself (but you'll probably be much better off with composition anyway!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment