(Over)thinking JavaScript objects 2

tally-clicker

Objects with constructors and prototyped methods

In this installment, I am going to look at building a tally clicker using what seems to be the canonical form for building class-like entities in JavaScript. The idea is simple:

  • Use a constructor function to create a scope/context with the object’s properties.
  • Use the┬áconstructor function’s prototype property to attach methods.

Attaching methods to the constructor’s prototype allows a single method instance to be shared among all objects instantiated from the constructor function.

Here’s how we might do it:

// == Begin Clicker2 definition =====================
// -- Constructor -----------------------------------
var Clicker2 = function() {
  // properties:
  this._numClicks = 0;

  // initialize state:
  this._update();
};

// -- Methods ---------------------------------------
Clicker2.prototype.click = function() {
  this._numClicks++;
  this._update();
};

Clicker2.prototype.reset = function() {
  this._numClicks = 0;
  this._update();
};

Clicker2.prototype._update = function() {
  console.log("Clicker2 obj: " + this._numClicks);
};

Clicker2.prototype.showInfo = function() {
  alert("I am a Clicker2 object who is at " +
    this._numClicks + " clicks.");
};
// == End Clicker 2 definition ======================

The HTML might then have something like:

<button onclick="yourClicker.click();">Click</button>
<button onclick="yourClicker.reset();">Reset</button>
<button onclick="yourClicker.showInfo();">Info</button>
...
<script>
  // Wait for DOM to be ready and then instantiate a
  // Clicker2 object:
  document.addEventListener('DOMContentLoaded',
    function() {
      document.yourClicker = new Clicker2();
    });
</script>

Compared to the approach using object literals, this approach has the following advantages:

  • It allows for automatic object initialization.
  • The object abstraction has, “Reuse me!” written all over it.

However, it still has a couple issues:

  • It violates encapsulation because everything is still public.*
  • It still pollutes the global namespace.

In the next installment, we’ll look at a way to fix these remaining problems. Just as a reminder, I am not (yet) taking on the following:

  • Inheritance-like stuff
  • “Class” (i.e., static) members*
  • Polymorphism

*An issue of religious importance.

One thought on “(Over)thinking JavaScript objects 2”

Leave a Reply

Your email address will not be published. Required fields are marked *