Object-oriented JavaScript



TunJS - April 2015

By Nader Toukabri

Program


  • prototype
  • ES5 "classical" inheritence
  • ES5 prototyping
  • ES6 classes and inheritence

define prototype


  • an object prototype is a reference to standard object defining both structure and default values

  • the following statements are equevelent:
    • B prototypes A
    • B have A as prototype
    • A is the prototype of B

define prototype


  • Prototyping is transitive (hello Algebra!)
    • if A prototypes B
    • and B prototypes C
    • then A prototypes C
    • prototype chain!
  • Object.prototype is a prototype for all objects
    • last one in the prototype chain
    • kind of! (Object.create(null))


var o1 = {a: 1};
var o2 = Object.create(o1);
o2.b = 2;

              
Playground

ES5 "classical" inheritence

Meetup class



// define constructor
function Meetup(name) {
  // property initialisation
  this.id = Date.now();
  this.name = name;
}

// override native method
Meetup.prototype.toString = function () {
  return '[object Meetup(name=' + this.name + ')]';
};

// define method
Meetup.prototype.start = function () {
  console.log('Starting ' + this.name + '!');
}

// define method
Meetup.prototype.is = function (that) {
  Meetup.is(this, that);
};

// define static method
Meetup.is = function ( /* Meetup */ a, /* Meetup */ b) {
  return a.id === b.id;
};

              

ES5 "classical" inheritence

TechMeetup class



// define constructor
function TechMeetup(name, technology) {
  // call to superclass constructor
  Meetup.call(this, name);
  // initialize properties
  this.technology = technology;
}

// prototype the prototype!
TechMeetup.prototype = Object.create(Meetup.prototype);
TechMeetup.prototype.constructor = TechMeetup;

// override native method
TechMeetup.prototype.toString = function () {
  return '[object TechMeetup(name=' + this.name + ')]';
};

TechMeetup.prototype.go = function () {
  Meetup.prototype.start.call(this);
  // or simply this.start();
};

              

ES5 "classical" inheritence

Outcome



this.tunjs1 = new Meetup("TunJS");

this.tunjs2 = new TechMeetup("TunJS", "JavaScript");

tunjs1 instanceof Meetup; // ==> true
tunjs1 instanceof TechMeetup; // ==> false

tunjs2 instanceof TechMeetup; // ==> true
tunjs2 instanceof Meetup; // ==> true

              

ES6 classes and inheritence

Meetup class



// define class
class Meetup {

  // define constructor
  constructor(name) {
    //  initialize properties
    this.id = Date.now();
    this.name = name;
  }

  // ovverride native method
  toString() {
    return '[object Meetup(id=' + this.name + ')]';
  }

  // define method
  start() {
    console.log('Starting ' + this.name + '!');
  }

  is(that) {
    Meetup.is(this, that);
  }

  static is( /* Meetup */ a, /* Meetup */ b) {
    return a.id === b.id;
  }

}

              

ES6 classes and inheritence

TechMeetup class



// define class
class TechMeetup extends Meetup {

  // define constructor 
  constructor(name, technology) {
    // call to superclass constructor
    super(name);
    // initialize properties
    this.technology = technology;
  }

  // ovverride method
  toString() {
    return '[object TechMeetup(id=' + this.name + ')]';
  }

  go() {
    super.start();
  }

}

              

ES5 prototyping

Meetup factory



var Meetup = {

  // define initialiser 
  create: function (name) {
    // create an instance object that prototypes the reference object
    var instance = Object.create(this.prototype);
    // initialize properties
    this.init.call(instance, name);
    return instance;
  },

  init: function (name) {
    this.id = Date.now();
    this.name = name;
  },

  prototype: {
    // override native method
    toString: function () { // method definition
      return '[object Meetup(id=' + this.name + ')]';
    },
    // define method
    start: function () {
      console.log('Starting ' + this.name + '!');
    },
    is(that) {
      Meetup.is(this, that);
    }
  },

  is: function ( /* Meetup */ a, /* Meetup */ b) {
    return a.id === b.id;
  }

};

              

ES5 prototyping

TechMeetup factory



var TechMeetup = {

  // define initialiser 
  create: function (name, technology) {
    // create an instance object that prototypes the reference object
    var instance = Object.create(this.prototype);
    // initialize properties
    this.init.call(instance, name, technology);
    return instance;
  },

  init: function (name, technology) {
    Meetup.init.call(this, name)
    this.technology = technology;
  },

  // create a reference object that inherits another reference object's behaviour
  prototype: Object.create(Meetup.prototype)

};

// override native method
TechMeetup.prototype.toString = function () {
  return '[object TechMeetup(name=' + this.name + ')]';
};

TechMeetup.prototype.go = function () {
  Meetup.prototype.start.call(this);
  // or simply this.start();
};

              

ES5 prototyping

Outcome



this.tunjs1 = Meetup.create("TunJS");

this.tunjs2 = TechMeetup.create("TunJS", "JavaScript");

              

Refenrences

THE END