"this" keyword in javascript
One of the most confused mechanisms in JavaScript is the "this" keyword. It's a special identifier keyword that's automatically defined in the scope of every function. When a function is invoked, an execution context is created. This execution context contains information about where the function was called from (the call-stacks), how the function was invoked, what parameters were passed, etc. One of the properties of this execution context is the this reference, which will be used for the duration of the function's execution.
To understand this, we first have to learn what this is not. this is neither a reference to the function itself, nor it is a reference to the function's lexical scope. this is actually a binding that is made when a function is invoked, and what it references is determined entirely by the call-site where the function is called.
Call-Site
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). Finding the call-site is generally "go locate where a function is called from".
function first()
? ? //call-site is in the global scope
? ? console.log("first");
? ? second(); //call-site for second
}
function second() {
? ? //call-site is in "first"
? ? console.log("second");
? ? third(); //call-site for "third"
}
function third() {
? ? //call-site is in "second"
? ? console.log("third");
}
first(); //call-site for "first"
There are 4 rules to how the call-site determines where this will point during the execution of a function.
The first rule we will examine comes from the most common case of function calls: standalone function invocation. This is default catch-all rule when none of the other rules apply.
For example:
function first()
? ? console.log(this.a)
}
var a = 5;
first(); //output is: 5
Here default binding gets applied because variable a is declared in the global scope and call-site for first function is global scope hence when first() is called, this.a resolves to our global variable a.
2. Implicit Binding
Another rule to consider is whether the call-site has a context object, also referred to as an owning or containing object.
Example:
var a = 10; //global
function first()
? ? console.log(this.a);
}
var obj = {
? ? a: 5,
? ? first: first
}
obj.first(); //Output: 5
Here, the call-site uses the obj context to reference the function. We could say that the obj object "owns" or "contains" the function reference at the time the function is called.
领英推荐
3. Explicit Binding
If we want to force a function call to use a particular object for the this binding, without putting a property function reference on the object JavaScript have inbuild methods which are call(..) and apply(..). How call and apply works? They both take, as their first parameter, an object to use for the this, and then invoke the function with that this specified. Since we are directly stating what we want the this to be, we call it explicit binding.
Example:
function first()
? ? console.log(this.a);
}
var obj = {
? ? a: 5
}
first.call(obj); //Output: 5
The difference between call and apply is that call() method takes arguments separately and apply() method takes arguments as an array.
4. New Binding
The fourth and final rule of this binding is New Binding. When a function is invoked with new in front of it, otherwise known as a constructor call, the following things are done automatically:
Example:
function first()
? ? this.a = a;
}
var second = new first(5);
console.log(second.a); //Output: 5
By calling first(...) with new in front of it, we've constructed a new object and set that new object as the this for the call of first(...).
"The this keyword and prototypes are pivotal, because they are foundational to doing real programming with JavaScript." - Nick Berardi
Reference from "You Don't Know JS" by Kyle Simpson