Using “this” Responsibly

Over the past few weeks, I’ve come across a number of libraries that have decided to manipulate the value of this in a callback function. Presumably, to provide additional functionality to the callback by way of methods of the this keyword. To offer a somewhat trivial example:

// lib.js
lib.method = function(callback) {
    var newThis = {};
    newThis.function1 = function() {};
    newThis.function2 = function() {};
    callback.call(newThis);
}

// your-source.js
lib.method(function() {
    this.function1('a');
    this.function2('b');
});

Imagine if you only had access to “your-source.js”, or the source of “lib.js” was obfuscated. For a more real-world instance of this pattern, we can take a look at how Backbone Marionette allows a developer to define a module:

var app = new Backbone.Marionette.Application();

app.module('mymodule', function() {
    this.add = function(x, y) {
        return x + y;
    };
});

It may already be obvious why this might not be such a great idea (pardon the pun), especially when sharing code. Without looking at the source of the library, or having its documentation on hand, there isn’t much clue as to where the value of this is being set, and what it actually refers to. How does a reader know that our new module, “mymodule”, now has a method called “add”? Or that this refers to the module and not the actual app? The code within the callback is far too ambiguous. Thankfully, Backbone Marionette also offers a much more readable approach:

app.module('mymodule', function(myModule) {
    myModule.add = function(x, y) {
        return x + y;
    };
});

Here, you can plainly see that the library is passing the module back to the callback function, and a new method is being defined on that module. You can also name the parameter as descriptively as you see fit. With this approach, what the developer is trying to achieve becomes much more obvious. As an added bonus, the name of the variable is also a candidate for minification when optimizing your source code for production.

This is all not to say that the this keyword should be avoided like the plague. There are instances where it makes complete sense to use, such as when defining prototype methods.

var Person = function(name) {
    this.name = name;
};
Person.prototype.sayHello = function() {
    return 'Hello, ' + this.name;
}

In this context, this refers to an instance of the object you’re defining in the same file. Another example, DOM events:

element.onclick = function(event) {
  // `this` refers to the element that was clicked
};

In both these examples, the value of this is immediately available to the reader. The mention of this and its subsequent uses are grouped together in one cohesive unit. Much more readable, no?

About these ads

2 thoughts on “Using “this” Responsibly

  1. Interesting post. I normally work with C++ where I’ve seen some horribly obfuscated code by misuse of ‘this’. Good to see that you’re proselytizing restraint in the use of the ‘this’ keyword!

    Reply
  2. Pingback: Using β€œthis” Responsibly | I read stuff.

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