Skip to content

Instantly share code, notes, and snippets.

@gasparrobi
Last active June 19, 2018 07:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gasparrobi/a4c5096999310000c43733a9fda7f7ba to your computer and use it in GitHub Desktop.
Save gasparrobi/a4c5096999310000c43733a9fda7f7ba to your computer and use it in GitHub Desktop.

THIS

To understand this binding, we have to understand the call-site: the location in code where a function is called (not where it's declared). We must inspect the call-site to answer the question: what's this this a reference to?

default binding

The first rule we will examine comes from the most common case of function calls: standalone function invocation. Think of this this rule as the default catch-all rule when none of the other rules apply.

function foo() {
	console.log( this.a );
}

var a = 2;

foo(); // 2

implicit binding

Another rule to consider is: does the call-site have a context object, also referred to as an owning or containing object, though these alternate terms could be slightly misleading.

function foo() {
	console.log( this.a );
}

var obj = {
	a: 2,
	foo: foo
};

obj.foo(); // 2

Implicitly Lost

If you take the function out of context by passing its reference, it'll lose reference to this, or will switch back to default binding.

function foo() {
	console.log( this.a );
}

var obj = {
	a: 2,
	foo: foo
};

var bar = obj.foo; // function reference/alias!

var a = "oops, global"; // `a` also property on global object

bar(); // "oops, global"

Explicit binding

Invoking foo with explicit binding by foo.call(..) allows us to force its this to be obj.

function foo() {
	console.log( this.a );
}

var obj = {
	a: 2
};

foo.call( obj ); // 2

new keyword Binding

By calling foo(..) with new in front of it, we've constructed a new object and set that new object as the this for the call of foo(..). So new is the final way that a function call's this can be bound.

function foo(a) {
	this.a = a;
}

var bar = new foo( 2 );
console.log( bar.a ); // 2

ES6 Arrow functions

Instead of using the four standard this rules, arrow-functions adopt the this binding from the enclosing (function or global) scope.

function foo() {
	setTimeout(() => {
		// `this` here is lexically adopted from `foo()`
		console.log( this.a );
	},100);
}

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