Skip to content

Instantly share code, notes, and snippets.

@jayjariwala
Created January 18, 2018 00:52
Show Gist options
  • Save jayjariwala/cdc4714e88ae6c01464bbb78458bce1e to your computer and use it in GitHub Desktop.
Save jayjariwala/cdc4714e88ae6c01464bbb78458bce1e to your computer and use it in GitHub Desktop.
This is not an author-time binding but a runtime binding.
this has nothing to do with where a function is declared, but has everthing to do with the manner in which the function is called.
when a function is invoked, an activation record, otherwise known as an exection context, is created.
it contains information about where the function was called from (the call-stack), how the function was invoked, what parameters where passed. etc.
one of the properties of this record is this reference, which will be used for the duration of that function's execution.
To understand the this binding, we have to understand the call-site.
call site and call stack
Default binding
function foo()
{
console.log (this.a);
}
var a = 2;
foo() // 2
if strict mode is in effect, the global object is not eligible for the default binding, so the this is instead set to undefined.
e.g function foo()
{
"use strict"
console.log(this.a);
}
var a = 2;
foo(); // typeError : 'this' is 'undefined'
Implicit Binding
Another rule to conside is whether the call-site has a context object, also reffered to as an owning or containing object.
e.g
function foo()
{
console.log(this.a);
}
var obj = {
a:2,
foo:foo
};
obj.foo(); // 2
// when there is a context object for a function reference, the implicit binding rule says that it's that object that should be used for the function call's this binding. because obj is the this for the foo() call
Implicity Loss
one of the most common frustration that this binding creates is when an implicity bound function loses that binding, which usually means it falls back to the default binding of either the global object or undefined , depends on strict mode.
function foo()
{
console.log(this.a);
}
var obj = {
a:2,
foo:foo
}
var bar = obj.foo; // function reference/alias;
var a = "opps, global";
bar(); // "oops, global"
call-site is what matter // here the call-site is bar which is plain, undecorated call, this the default binding applies.
The more subtle, mode common, and more unexpected way this occure is when we consider passing a callback function.
What if the function you’re passing your callback to is not your own,
but built into the language? No difference, same outcome:
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
var a = "oops, global"; // `a` also property on global object
setTimeout( obj.foo, 100 ); // "oops, global"
// Explicit Binding
function foo() {
console.log( this.a );
}
var obj = {
a: 2
};
foo.call( obj ); // 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment