Skip to content

Instantly share code, notes, and snippets.

@etsuo
Created September 2, 2015 21:12
Show Gist options
  • Save etsuo/e23b7618027d08034f37 to your computer and use it in GitHub Desktop.
Save etsuo/e23b7618027d08034f37 to your computer and use it in GitHub Desktop.
Javascript "this" behavior notes
/*************
/ Call #1 Default Binding
**************/
function foo() {
console.log( ": " + this.a );
}
// note var is dropped to make this global even when
// run with node.js that would otherwise cause the call
// site of foo to be called from within a module
// (function (exports, require, module, __filename, __dirname) { ... call site ...} )
a = 'a from global';
console.log('Call 1 (Default Binding): this points to global a');
foo(); // call site > 'default binding'
nl();
/*************
/ Call #2 Implicit Binding
**************/
var obj = {
a: 'a from obj',
foo: foo
};
console.log('Call 2 (Implicit Binding): this points to obj.a');
obj.foo(); // call site > 'implicit binding'
nl();
/*************
/ Call #3 Implicit Binding
**************/
// Note that only the last context of a function call
// establishes the call site
var obj2 = {
a: 'a from obj2',
obj: obj
};
console.log('Call 3 (Implicit Binding): last call site mean this points to obj.a, not obj2.a');
obj2.obj.foo(); // call site > 'implicit binding'
nl();
/*************
/ Call #4 Implicit Binding Lost
**************/
// Watchout for implicit binding in wrapper functions
// this will happen in callbacks
function doFoo(fn) {
fn(); // << this just became the call site
// since there's no "a" in doFoo, this points to global a
}
var bar = obj.foo; // function reference / alias
console.log('Call 4 (Implicit Binding Lost): this points to global since bar is the call site');
bar(); // call site
nl();
/*************
/ Call #5 Implicit Binding Lost
**************/
// what happened with bar() above is what happens when you pass a function
console.log('Call 5 (Implicit Binding Lost): this points to global since doFoo is the call site');
doFoo(obj.foo);
nl();
// this means if doFoo is a callback, this will lose its context for this...
/*************
/ Call #6 Explicit / Hard Binding
**************/
console.log('Call 6 (Explicit / Hard Binding): this points to obj.a because it is hard bound with .call(...)');
console.log('bar.call(obj)');
bar.call(obj);
console.log('bar.call(obj2)');
bar.call(obj2);
nl();
/*************
/ Call #7 Explicit / Hard Binding
**************/
console.log('Call 7 (Hard Binding with built in bind): this points to obj.a becaus it is hard bound with .bind');
bar = foo.bind(obj);
bar();
nl();
// note, if bar took parameters, this would allow them... so, for example you could:
// bar = foo.bind(obj);
// bar(123);
// Assuming bar took parameters
/*************
/ Call #8 New Binding
**************/
function newFoo(a) {
this.a = a;
}
a = 4;
var bar = new newFoo(2);
console.log('Call 8 New Binding): this points to the new newFoo');
console.log(bar.a);
// Binding Order
console.log('new binding');
console.log('explicit biding');
console.log('implicit binding');
console.log('default binding');
//////////
function nl() {
console.log('');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment