JavaScript and this confusion for this Java developer

The this keyword will be immediately obvious to almost all Java developers.  If that doesn’t include you then you probably won’t be interested in reading the rest of this!

In JavaScript we cannot assume that this works the same way as it does in Java. In fact there are four different scenarios that we have to cater for.  I’m not going to cover the constructor invocation pattern and the apply invocation pattern as these ones are that bit more esoteric than the other two.

Disclaimer: I am currently reading JavaScript: The Good Parts.

This is a superb book and I’m reading it so that I can understand this maligned language better.  If I get something wrong or write something misleading then hit me up in the comments!

The method invocation pattern is what strikes me as the closest to what we are familiar with as Java developers.  This pattern is where this is used from the public methods of a JavaScript object to refer to the object in which these methods are defined.  This pattern makes sense to me as a Java developer and is illustrated in this simple example.

// Create an object with a public method
// called print.  this is bound to the enclosing
// object
var messageObject = {
  message: "Hello, method invocation pattern",
  print: function () {
    document.writeln(this.message);
  }
}

// invoke the method
messageObject.print();

The function invocation pattern is what confused me when I looked at it first.  This pattern comes about where a function is not a member of an object.  This sort of function may be used as a helper function of sorts.  This can happen in JavaScript because functions are objects, and they can contain nested functions themselves.  Crockford notes that the way this is bound is a mistake in the language, and that in the helper message this is bound to the global object, and not the object that the helper function is contained in.  The global object is an intrinsic object that is created when the scripting engine is initialised.  It is like the global scope.

We can introduce a variable in our objects, usually called that, but could be called banana if you so wish (don’t).  This variable will be a member of our object, so we can use it to reference this in our helper function.

// Create the object just like we did before
// We just change the value of 'message'
var messageObject = {
  message: "Hello, function invocation pattern",
  print: function () {
    document.writeln(this.message);
  }
}

// Now say that we want to add a new method
// called pretty print.
messageObject.prettyPrint = function () {
  // Grab a re-usable reference to this
  // this is bound to messageObject because
  // prettyPrint is a public method
  var that = this;

  // This is the nested helper function
  // Contrived example, but in the context
  // of this helper function 'this' would
  // refer to the global object, and not
  // the enclosing object, messageObject.
  // We can use 'that' though thanks to 
  // lexical scoping!
  var helper = function () {
    document.writeln(that.message);
    document.writeln('<br />');
  };

  //invoke it
  helper();
};

// Call it
messageObject.prettyPrint();

I hope that I helped clear that up for other people who may have been slightly confused by this and that like I was.  For the JavaScript gurus I hope I didn’t cause too much face-palming if I butchered Crockford’s elegant explanations!

One thought on “JavaScript and this confusion for this Java developer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s