travis jeffery


What is this? i don't even... bind this to your object in javascript!

In JavaScript, a function’s this keyword is always bound to an object, what object that is depends on how the current function was called, so it could be different each time the function is called.

In this example, as we and anyone else would expect after reading this code, this refers to MyObject,

var MyObject = {
  my_method: function(){
    console.log(this)
  },

  inspect: function(){
    return "I'm MyObject!"
  }
}

MyObject.my_method()

// > I'm MyObject!

The next example is a little weird. As you can see my_method is now being called within the context of the global object.

In the previous case my console.log(this) was equivalent to console.log(MyObject) and here it is equivalent to console.log(global).

var MyObject = {
  // ...
}

global.inspect = function(){
  return "I'm the Global Object!"
}

var my_same_method = MyObject.my_method
my_same_method()

// > I'm the Global Object!

But the really interesting stuff happens when using something like jQuery’s Events with bind/trigger. I’ve seen this be a fairly common gotcha. You expect this to refer to your object, but it’s actually the object you triggered your event on,

var myDiv = $("body").append("<div id='js-my-div'></div>")

var CarlDouglas = {
  lyrics: "OhohOhoOh... Everybody was Kung fu fighting! Ha!",

  sing: function(){
    this.lyrics || (this.lyrics = "Where are Carl Douglas's lyrics?! What this is _this_??")

    console.log(this.lyrics)
  }
}

myDiv.bind("kungfu:fight", CarlDouglas.sing)

$("div#js-my-div").trigger("kungfu:fight")

// > Where are Carl Douglas's lyrics?! What this is _this_??

Thankfully, this is fixable! All we have to do in bind our object’s methods to that object, to be run in the context of our object whenever they are invoked.

Underscore.js provides this functionality with its bind/bindAll functions, check out the docs and annotated sources for more detail.

So we add this after defining our object,

_.bindAll(CarlDouglas)

And this behaves as we expect! Everybody was Kung fu fighting! Ha!

var myDiv = $("body").append("<div id='js-my-div'></div>")

var CarlDouglas = {
  lyrics: "OhohOhoOh... Everybody was Kung fu fighting! Ha!",

  sing: function(){
    this.lyrics || (this.lyrics = "Where are Carl Douglas's lyrics?! What this is _this_??")

    console.log(this.lyrics)
  }
}

_.bindAll(CarlDouglas)

myDiv.bind("kungfu:fight", CarlDouglas.sing)

$("div#js-my-div").trigger("kungfu:fight")

// > OhohOhoOh... Everybody was Kung fu fighting! Ha!

what is this i don't even