"this" keyword in javascript
Photo by Emile Perron on Unsplash

"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.

  1. Default Binding

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:

  1. A brand new object is created (aka constructed) out of thin air.
  2. The newly constructed object is [[prototype]]-linked.
  3. The newly constructed object is set as the this binding for that function call.
  4. Unless the function returns its own alternate object, the new-invoked function call will automatically return the newly constructed object.

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

要查看或添加评论,请登录

iProgrammer Solutions的更多文章

社区洞察

其他会员也浏览了