Lets start off by making a simple script to test the scope of a function using the Firebug console.
What is Firebug?
In the above example, we assigned a variable to the global
window object called
name. We then defined a function in the window scope that will log a string to the console and then we gave it a run. The line of most interest is where we used the
this variable. As our function is within the global window scope,
this resolves to the window object, and as such, we can get to our
name variable and concatenate it to our
In this example, we neatly packaged our
name variable and
action function into an object literal. We also see that the value of
this changed to the containing object, which is no longer
Losing Scope and Getting it Back
Our function requires a bit more logic, as many functions do. To handle this, we will nest a function within our
action function called
nestedAction. It is here when things go awry.
nestedAction function is indeed contained within
this is instead pointing to
window. This is due to how we are executing the
action function is defined and executed within
window scope. As such, the
nestedAction function is actually executing globally even though it is defined locally within the
That is more like it. By using
apply, we are able to specify what scope our
nestedAction should resolve to. The
apply functions are sent to a function and carry two parameter types, the scope the function should resolve to and the parameters it should use at run-time. You will notice that the scope we are wiring the
nestedAction function to resolve to is
this. We can do so as
this resolves to
object until we nest our code another function deeper.
You will also notice that
apply perform exactly the same, except for one key difference. The
call function first accepts the object to resolve scope to, and then the parameters to be passed to the function. On the other hand,
apply accepts the object to resolve scope to and an array of parameters to be passed to the function. This difference is noteworthy, as one interface may be easier to implement into our code then another.
So, how flexible are
In this example, the nefarious Eve is able to impersonate both Alice and the window object by passing
apply to her
talk function. Between the this and the previous example, we can definitely see how
bind function and do just that. Take a look:
talk function into another function that is properly scoped. The explanation is as follows:
- We first define a new prototype to the Function class called
bind, which takes scope as a parameter.
- As we are working with a function,
binddefinition function will resolve to the function being sent the
- We then return a function, that when executed, will actually execute the original function while applying the scope specified with the arguments passed.
- Finally, we can cleanly bind our
talkfunction to the appropriate scope at its definition and call it normally at its execution.
In this example, we can see how
apply is a better fit then
arguments which acts like an Array, we can pass it to
apply and keep our function parameters intact. Now that we have a method for hard-wiring scope on definition, we can return to our previous problem and make it work how we anticipated.
this and then how it can be controlled via