Understanding Scope and Binding in JavaScript
At the heart of binding, it’s merely a means to control execution scope—Function x executions in the scope of object y. It can be tough to grasp at first, but with the right amount of ninja references, anything can be explained so someone can understand it.
What’s my name fool
To get a basic understanding of binding, check out this example.
var Car = function() { this.name = 'car'; }
var Truck = function() { this.name = 'truck'; }
var func = function() { alert(this.name); }
var c = new Car();
var t = new Truck();
func.apply(c);
func.apply(t);
You can pop this in Firebug and you should get two alerts with car and truck respectively. To understand why this works, you need to understand a few basic things. Functions are objects in JavaScript, and apply allows you to apply the method of one object in another object, which basically means your controlling the execution scope.
You might say that func belongs to no object, but you’d be wrong, it belongs to the window object. You could envision that all functions that aren’t scoped within a visible object (meaning one written in front of your face) can be viewed as something like this:
// Don't ever write code like this, it's just an example to help you see things clearly
function window() {
this.func = function() { alert(this.name); }
}
Hopefully this graphic will hammer the point home.

For the Ruby Folk
While I’ve never had to write anything like this in Ruby, it could be done in much the same fashion.
class Car
attr_accessor :name
def initialize
@name = 'car'
end
end
class Truck
attr_accessor :name
def initialize
@name = 'truck'
end
end
def func
puts @name
end
c = Car.new
t = Truck.new
eval "func", c.send(:binding)
Prototype and those damn blocks
A common cause of confusion amongst developers using Prototype is binding, specifically in blocks and events— the two primary places where binding is used within Prototype and JavaScript written using Prototype. Take a look at the example below.
var Ninja = Class.create();
Ninja.prototype = {
initialize: function(abilities) {
this.abilities = [
'Kick you in the face',
'Rip out your spleen'
];
this.abilities.each(function(ability) {
this.executeAbility(ability)
});
},
executeAbility: function(ability) {
console.log(ability);
}
}
// Notice this function has the same name as a method on our Ninja class.
function executeAbility(ability) {
console.log("I was called from the window object:" + ability);
}
new Ninja();
Give this interesting piece of JavaScript a run in Firebug. This should print two lines to the console that were printed from the window object. The reason this happens is because this inside the anonymous function passed to each is the window object, not our class. This is obviously not what we want, so lets use bind so we can control the execution scope. Add bind to your code like the example below and run it again.
this.abilities.each(function(ability) {
this.executeAbility(ability)
}.bind(this));
When you execute the code above, the executeAbility from within our class should be executed. This is because we bound the execution of executeAbility to our Ninja class. Because you can never have enough visual aids, below is an overview of this in color.

Binding and Events
In PAJ™ (Plain Ass JavaScript) , this inside a callback is actually the element which invoked the event, so it’s fairly easy to do the code like below.
var ninja = document.getElementById('ninja');
ninja.addEventListener('click', function () {
alert(this.tagName);
}, false);
However, in Prototype this points to the window (Update: In > 1.6 this is now the element) object inside a callback so we need to use bind in order to bind it to the object the method belongs to.
var Ninja = Class.create();
Ninja.prototype = {
...
addObservers: function() {
$('item').observe('click', this.kickSomeone.bindAsEventListener(this));
},
kickSomeone: function(event) {
// Works because `this` is the Ninja instance
// Without binding it would be the window
this.someOtherMove();
}
...
}
The only real difference between bind and bindAsEventListener is that bindAsEventListener ensures the event object is passed as the first argument.
Bonus Mojo: Early Binding
Sometimes you need to pass an additional argument to a callback function, and you need the value of the argument at the time it was bound. To understand what I’m talking about, check out this example:
var phrase = "This is SPAARRTTAAAA!";
$('somelink').observe('click', sayIt);
function sayIt(event) {
console.log(phrase);
}
phrase = "Red sauce on PAASTAAAA!"
When somelink is clicked, you might think the value of phrase would be ”This is SPAARRTTAAAA!”, but this isn’t true. Even though the value of phrase is ”This is SPAARRTTAAAA!” at the time the event listener is registered, it’s value is changed before the event fires. So, what you actually get printed to the console is ”Red sauce on PAASTAAAA!”. Not quiet the dramatic effect we wanted. To correct this, we can pass the value of phrase to the callback at the time the binding was created.
var phrase = "This is SPAARRTTAAAA!";
$('somelink').observe('click', sayIt.bindAsEventListener(this, phrase));
function sayIt(event, phrase) {
console.log(phrase);
}
phrase = "Red sauce on PAASTAAAA!";
Now, even though the value of phrase has changed later on in our code, we’ll actually get ”This is SPAARRTTAAAA!” because we bound the value at runtime instead of execution time.
Wrapping up
As you can see, binding isn’t really that confusing, it’s just hard to explain in a way people can understand it. Hopefully I achieved that, but if I didn’t I’ll chalk it up to not enough ninja references. For some further reading check out:
Sorry, comments are closed for this article.



Discussion
Nice writeup!
You have a small typo on the first picture /* func.apply© where it should be func.apply(t) */, but other than that it was a nice explanation.
Of the new additions on Prototype to Function I’m giving the prize to curry, by far the best one, with methodize a distant second :)
Nice article, hopefully, more people will be able to grasp the concept of scopes and binding, since it’s an important aspect of JavaScript. It’s also part of what makes JavaScript so powerful.
You’ve reminded me that I need to correct the Prototype docs —
bindAsEventListenerdoesn’t need to be used unless you’re assigning an event the old-fashioned way (e.g.,foo.onclick = ...). When you’re usingEvent.observe,bindwill suffice.Thanks for the correction Nicolás. One fresh graphic coming up.
@andrew: I’m glad you cleared that up. I never fully understood where bindAsEventListener would perform different than bind.
I love the use of color in your diagrams…it makes much more sense that way.
Now we need a text editor with similarly color-coded scopes!
Really great article. I ran into the bind problem yesterday and couldn’t find a solution to it, so your timing couldn’t be better :)
It takes a while learning javascript but I’m getting there. Mainly thanks to Prototype and the JS communty. Thx guys.
Terrific write up, very useful. Definitely going into my del.icio.us bookmarks….
Impressive writeup, binding is a tough subject to understand, never seen it written so clear and concise before. Thanks!
Nice post Justin – more people need to understand binding since it’s a crucial first step in being able to incredible things with Prototype.
Thanks Justin.
I’ve never grasped Binding properly which does let down alot of the functionality of Javascript. However, i’ve never seen it presented so simply and a light bulb has just gone off inside the old “noggen” so to speak.
I’m doing some experimentation using your examples, and this is the most success i’ve ever had using binding.
Much appreciated, Carly!
Thanks for the great article. I have been looking for how to do this for quite a while. I’ll add that this technique is very useful for handling complex events THE RIGHT WAY.