JavaScript’s prototypal inheritance

In this final part of our series on JavaScript prototypes, we’re going to discuss using them to implement inheritance as it’s typically thought of in classical object-oriented design. Having said that, I once again suggest that you try to put aside what you may already know about how objects and inheritance work in other languages and treat the way JavaScript works as its OwnThing.

So, let’s get on with it.

Continue reading “JavaScript’s prototypal inheritance”

JavaScript and ‘this’, arrow function edition

In a previous installment, we took a dive into the this variable and how it behaves in different ES5 situations. In this installment, we’ll do the same but for so-called arrow functions, introduced in ES6.

Continue reading “JavaScript and ‘this’, arrow function edition”

The JavaScript prototype chain

So far we’ve learned what the relationship is between an object and its constructor’s prototype and what happens when we change properties set on the prototype. In particular, we learned that if you try to access a property of on object, the JavaScript engine will first look in the object itself for the property, and it if doesn’t find it there it looks in its __proto__ property, which is also the constructor’s prototype.

This leads to a good question: What happens if the property isn’t in the constructor’s prototype either? One possible answer is that the JavaScript engine gives up and says the property is undefined. But that’s not what happens.

Continue reading “The JavaScript prototype chain”

JavaScript prototypes

This is the first in a series of posts intended as a gentle guide through the realm of JavaScript prototypes. If you’re coming here from a class-based language like Java, PHP, C#, or C++ I suggest you put aside everything you know about how objects and inheritance work in those languages. Try to treat the way JavaScript works as its OwnThing.

Continue reading “JavaScript prototypes”

JavaScript and ‘this’

Keeping your head square about JavaScript’s this variable can be a little challenging. A wonderfully concise summary on the issue is found in chuckj’s answer to a StackOverflow question (modified here to account for differences between ECMAScript 5’s strict and non-strict modes):

this can be thought of as an additional parameter to the function that is bound at the call site. If the function is not called as a method then the global object (non-strict mode) or undefined (strict mode) is passed as this.”

Let’s see what this means (pun intended?) for various scenarios.

Continue reading “JavaScript and ‘this’”

(Over)thinking JavaScript objects 3

tally-clicker

Defining objects inside self-invoked anonymous functions

In our previous episode, we saw a canonical way to create objects in JavaScript that suggested code reuse and facilitated automatic object initialization, but it didn’t let you implement private attributes nor did it go out of its way to keep from polluting the global namespace.

What follows is the simplest way I’ve seen that accomplishes all of the above. And boy is it a ride! We are going to create a self-invoking anonymous function and inside the function we will define the object and create a single point of connection to the window with a closure.

Here we go:

// == Begin definition ==============================
(function(window) {
  // -- Constructor ---------------------------------
  var Clicker3 = function() {

    // -- Private properties --
    var _numClicks = 0;

    // -- Private methods --
    // Methods defined in this scope and not on
    // 'this' are private'.
    var _update = function() {
      console.log("Clicker3 obj: " + _numClicks);
    };

    // -- Public methods --
    // Methods defined on 'this' are public, can
    // access private and public members.
    this.click = function () {
      _numClicks++;
      _update();
    };

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

    this.getNumClicks = function () {
      return _numClicks;
    };

    // -- Initialize state --
    this.reset(); // reset is redundant here;
                  // for demo only.
    _update();
  }; // !Clicker3()

  // -- "Hyper-public" methods ----------------------
  // Methods defined on the prototype can only access
  // public members!
  Clicker3.prototype.showInfo = function() {
    alert("I am a Clicker3 object who is at " +
      this.getNumClicks() + " clicks.");
  };

  // -- Publish -------------------------------------
  // Expose Clicker3 (and only Clicker3) to the
  // global window (i.e., make it public).
  window.Clicker3 = Clicker3;

}(window));
// == End definition ================================

The self-invoking function creates a new scope in which everything is defined. Passing in window as a parameter allows easy access to global window from within that new scope. This setup lets you:

  • Prevent pollution of global namespace.
  • Expose what you want to the global window and keep the rest private.

So, now we  have something that:

  • Has, “Reuse me!” written all over it.
  • Allows for automatic object initialization.
  • Lets you fully encapsulate objects.*
  • Protects the global namespace.

But it’s not totally cool because none of the above are code-level constructs. In other words, it’s neither readable or writable. JavaScipt is/isn’t fun. :-\

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.

(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.

(Over)thinking JavaScript objects 1

tally-clicker

I’ve always found JavaScript’s approach(es) to OOP a little cumbersome. I’m not talking here about prototypal vs. class-based OOP. Rather, I’m talking about the readability, etc. of the actual code you have to write to build objects. I want to take a few blog entries to try to put the maze into some kind of cohesive perspective.

I like to use a tally clicker to explore objects in languages I am learning. A tally clicker is a real-world object with a minimal set of features that are easy to implement and that map to basic but salient OOP concepts.

Object literals

I’m going to start this exploration with plain-Jane object literals. This is one of the canonical ways and often the first way shown to implement objects in JavaScript. Here’s how I might implement a tally clicker with a JavaScript literal:

// == Create a tally clicker ========
var myClicker = {

    // pseudo-private property
    _numClicks: 0,         

    // pseudo-private method
    _update: function() {
        console.log("myClicker1: " + this._numClicks);
    },

    // public methods
    click: function() {
        this._numClicks++;
        this._update();
    },

    reset: function() {
        this._numClicks = 0;
        this._update();
    },

    showInfo: function() {
        alert('I am "myClicker" and am at ' +
            this._numClicks + ' clicks.');
    }
}; // == End tally clicker ========

I might then stick something like this into the HTML:

<button onclick="myClicker.click();">Click</button>
<button onclick="myClicker.reset();">Reset</button>
<button onclick="myClicker.showInfo();">Info</button>

The object literal approach is a seductively easy and pretty readable way to build an object—but it’s got issues. Namely:

  • There’s no automatic initialization apart from property values.
  • It violates encapsulation because everything is public.*
  • It pollutes the global namespace (sort of). As is, the name of the object is in the global namespace.
  • The object abstraction doesn’t scream, “Reuse me!” (This may be a cognitive style issue more than anything else.)

In the next couple installments, I’ll consider some alternative implementations specifically with regard to the above criteria. For the moment, I will not deal with:

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

*An issue of religious importance.

Getting closure in JavaScript

wooden heart

If you’re coming from an imperative programming background, closures in JavaScript can be pretty hard to grok. Here is yet another attempt to explain them. It assumes you are familiar with how lexically scoped, imperative languages like C, C++, and Java work.

In JavaScript every function call creates its own lexically scoped context. Normally that context is destroyed at the end of the function call. However, you can keep that context alive by creating a closure.

The function inner below creates a closure. Because there exists a reference to the inner function from the calling code after the function returns, neither the inner function nor its context are destroyed. In other words, inner‘s context (including vars local to countFrom) lives on after the call to countFrom returns.

function countFrom(num) {
    var counter = num;
    var inner = function() {
        // return the value of counter before increment.
        return counter++;
    }
    // return a reference to the inner function.
    return inner;
}

var countFromOne = countFrom(1);
/* countFromOne now refers to inner()
   with a unique, persistent context. */

window.alert( countFromOne() );  // alerts 1
window.alert( countFromOne() );  // alerts 2
window.alert( countFromOne() );  // alerts 3

var countFrom42 = countFrom(42);
/* countFrom42 refers to inner()
   with different, persistent context. */

window.alert( countFrom42() );  // alerts 42
window.alert( countFrom42() );  // alerts 43
window.alert( countFrom42() );  // alerts 44

/* The context associated with the inner from
   countFromOne is not affected by the above. */
window.alert( countFromOne() ); // alerts 4

Once you get the basic concept, you should be able to follow other examples that show how they can be useful.

P.S. Neckbeards think not naming things is cool, so here’s an anonymousy version of the function above.

var countFrom = function(num) {
    var counter = num;
    return function() {
        return counter++;
    };
};