Web Development

You Should Learn JavaScript

My Automattic colleague Beau Lebens says that JavaScript is the next (or first) programming language you should learn, and I couldn’t agree more. His reasons are great, but his conclusion resonated with me:

there’s never been a better time to get started with coding, and if you’re going to do it, I suggest starting with JavaScript. Start small, work your way up. View Source. Get on Github. Go nuts.

It’s the “never been a better time” part that really resonated with me. You could argue that I missed the boat on the early days of the web: I hacked together some web pages in the Netscape 1–3 era and gave up when this intimidating DHTML thing showed up. I didn’t understand the difference between JS the language and JS the interface to the utterly bewildering, buggy, non-standardized DOM.1 There were no resources, and definitely no browser compatibility, as the browser wars continued to escalate.2

Fast forward 17 years (!) later, a return to a love of building for the web, and now JS is the most interesting thing to me, the very thing that drove me away from web development initially. It started with jQuery and its simplification of the DOM, but that just proved the gateway into eventually diving deeper into JavaScript proper, and beginning to understand that there was even a difference between DOM and JS (much as WordPress did with PHP for me). If you’re reading this on a modern desktop browser, you have everything you need to start playing around with JavaScript. There’s loads of resources out there (like Khan Academy) to get you on your way.


  1. Ditto for basically everyone else for at least another decade. 
  2. “Best viewed in ___” anyone? 
Standard
Web Development

JavaScript Context Confusion

Or: how I learned to stop crossing my fingers about this.

The mutability of this is one of the hardest things to understand when writing JavaScript (the other is prototypal inheritance). Callbacks make this especially confusing and easy to lose track of.

Here’s a fairly common (and over-simplified) pattern:

var module = {
  init: function() {
    // alias "this"
    var self = this;
    // attach event handlers
    $("#foo").on( 'click', function( event ) {
      // this.takeAction() would throw a TypeError since jQuery
      // makes "this" a DOM Element rather than "module"
      self.takeAction( event );
    });
  },
  takeAction: function( event ) {
    // I need to have (this === module) to work properly
  }
}

module.init();

The problem modular code runs into is that jQuery assigns this to be the DOM Element that was clicked on in the above example. This is good for writing typical jQuery spaghetti code, but not when we want more modular code. So we alias this to something like self or that to be used inside a nested function’s scope. ECMAScript 5 solves this problem with Function.prototype.bind, ensuring that a function is always called in a specified context:

var module = {
  init: function() {
    // attach event handlers
    $("#foo").on( 'click', this.takeAction.bind( this ) );
  },
  takeAction: function( event ) {
    // I need to have (this === module) to work properly
  }
}

// helpful here too!
$( document ).ready( module.init.bind( module ) );

Now, if you find yourself in a situation where you need contextual information from both the DOM Element and the this context bound via Function.prototype.bind, you’re probably doing it wrong. (And anyway, you can still grab it from event.target.)

It would be great if we could just code like this today, but Function.prototype.bind is only supported in IE >= 9. But this is a common problem, and most frameworks solve this in some manner.

// jQuery.proxy
var module = {
  init: function() {
    // attach event handlers
    $("#foo").on( 'click', $.proxy( this.takeAction, this ) );
  },
  takeAction: function( event ) {
    // I need to have (this === module) to work properly
  }
}

// _.bind
var module = {
  init: function() {
    // attach event handlers
    $("#foo").on( 'click', _.bind( this.takeAction, this ) );
  },
  takeAction: function( event ) {
    // I need to have (this === module) to work properly
  }
}

I would recommend, whenever possible, to use Underscore’s _.bind over jQuery.proxy, since the latter can create some oddness (see docs) when unbinding event handlers. Plus Underscore is awesome.

And now I have some old code to go cringe at.

Standard