Everything you want to know about this is here

Source: Internet
Author: User
This has a very high attendance rate in the daily use of javascript or in the front-end interview process. This undoubtedly illustrates the importance of this. However, this is very flexible, making it hard for many people to understand this behavior. This article summarizes the six rules of this from why this should be used as the starting point, hoping to help you solve the puzzles. This has a very high attendance rate in the daily use of javascript or in the front-end interview process. This undoubtedly illustrates the importance of this. However, this is very flexible, making it hard for many people to understand this behavior. This article summarizes the six rules of this from why this should be used as the starting point, hoping to help you solve the puzzles.

Introduction

This is actually equivalent to a parameter, which may be manually input during development, JS, or a third party.
This parameter usually points to the "owner" of the function execution ". This mechanism makes the function design more concise and reusable.

This is bound during function execution. There are six binding rules:

● New binding: when the new keyword is used to create an object, this will be bound to the created object.

● Explicit binding: when the call, apply, or bind method is used for explicit binding, this is the first parameter.

● Implicit binding: When a function is executed on an object, the system implicitly binds this to the object.

● Default binding: When the function is executed independently, the default binding value of this in strict mode is undefined, otherwise it is a global object.

● Arrow function binding: When an arrow function is used, the binding value of this is equal to this of the common function (or global object itself) with the outer layer.

● System or third-party binding: When a function is used as a parameter to input an interface provided by the system or a third party, this in the input function is bound by the system or a third party.

The role of this

This mechanism provides an elegant way to implicitly pass an object, which makes the function design more concise and reusable.

Consider the following example: there are two buttons, and the background is changed to red after you click them.

function changeBackgroundColor(ele) {  ele.style.backgroundColor = 'red';}btn1.addEventListener('click',function () {  changeBackgroundColor(btn1);});btn2.addEventListener('click',function () {  changeBackgroundColor(btn2);});

Here, we explicitly pass the clicked element to the changeBackgroundColor function. But in fact, this can be used to implicitly pass context features and obtain the currently clicked element directly in the function. As follows:

function changeBackgroundColor() {    this.style.backgroundColor = 'red';}btn1.addEventListener('click',changeBackgroundColor);btn2.addEventListener('click',changeBackgroundColor);

In the first example, the clicked element is replaced by ele, a formal parameter. In the second example, this keyword is used instead. This is similar to a formal parameter. In essence, it is an object reference. Its special feature is that you do not need to manually transmit values, so it is easier to use.

Six rules

In actual use, the object to which this points is the most confusing. This article classifies the six scenarios and summarizes the six binding rules for this.

1. new binding

When using new to create an object, what does this in the class mean?

Class Person {constructor (name) {this. name = name;} getThis () {return this} const xiaoMing = new Person ("James"); console. log (xiaoMing. getThis () === xiaoMing); // trueconsole. log (xiaoMing. getThis () = Person); // falseconsole. log (xiaoMing. name = "James"); // true

In the preceding example, the Person class is created using ES6 syntax. When the new keyword is used to create an object, this is automatically bound to the created object, that is, xiaoMing.

Rule 1: when the new keyword is used to create an object, this will be bound to the created object.

2. Explicit binding


Scenario 2: Use the call, apply, and bind methods to explicitly bind the this parameter.

Taking call as an example, the first input parameter of the call method is the object referenced by this.

function foo() {  console.log( this === obj ); // true  console.log( this.a === 2 ); // true}const obj = {  a: 2};foo.call( obj );

When explicitly passed, this points to an object that is the first parameter of the call, apply, or bind method.

Rule 2: when the call, apply, or bind method is used for explicit binding, this is the first parameter.

3. Implicit binding


The difference between implicit binding and explicit binding is that explicit binding is specified by developers. In implicit binding, a function or method has an "owner ", this "owner" refers to the function or method object directly called.

Example 1

Let's take a look at the simplest example.

function bar() {  console.log( this === obj );}const obj = {  foo: function () {    console.log( this === obj );  },  bar: bar};obj.foo(); // trueobj.bar(); // true


The function foo is directly attached to the object obj. The function bar is defined outside and then mounted to the object obj. The "owner" of a function is obj no matter where it is defined. Therefore, this points to the "owner" obj of the function call.

Example 2

For a deeper understanding, let's take a look at the following example when the function is assigned to a new object.

function bar() {  console.log( this === obj1 ); // false  console.log( this === obj2 ); // true}const obj1 = {  foo: function () {    console.log( this === obj1 ); // false    console.log( this === obj2 ); // true  },  bar: bar};const obj2 = {  foo: obj1.foo,  bar: obj1.bar};obj2.foo();obj2.bar();

In this example, the foo and bar methods in obj1 are assigned to obj2. When calling a function, the "owner" is obj2, not obj1. So this points to obj2.

Example 3

Objects can be nested in multiple layers. In this case, who is the "owner" of a function when executing a function?

const obj1 = {  obj2: {    foo: function foo() {      console.log( this === obj1 );      // false      console.log( this === obj1.obj2 ); // true    }  }};obj1.obj2.foo()

The direct caller in the foo method/function is obj2 rather than obj1, so the "owner" of the function points to the direct caller closest to it.

Example 4

If a method/function calls and executes the call Method on its direct object, does it belong to implicit binding or explicit binding?

const obj1 = {  a: 1,  foo: function () {    console.log(this === obj1); // false    console.log(this === obj2); // true    console.log(this.a === 2);  // true  }};const obj2 = {  a: 2};obj1.foo.call(obj2); // true

From the above, we can see that if the explicit binding exists, it cannot be an implicit binding.

Rule 3: If a function is executed on an object, the system implicitly binds this to the "owner" of the function execution ".

4. default binding

The previous section discussed how functions are executed as objects. In this section, we will discuss the independent execution of functions.

When a function is called directly, this binding is called the default binding.

Example 1

For the sake of simplicity, we should first discuss binding behavior in non-strict browser mode.

function foo() {  console.log( this === window); // true}foo();

In the above example, the system binds the window to the function this by default.

Example 2

Here, we will first introduce a way to explicitly bind null that we may see in the code.

function foo() {  console.log( this == window ); // true}foo.apply(null);

Change the default binding case to explicitly binding null.

In actual development, we may use the apply method, and pass in the null value in the first parameter, and the second parameter to pass in the array type parameters. This is a traditional way of writing. Of course, ES6 can be used now, but this is not within the scope of this article.

In this example, the most important thing to note is that this actually points to the window instead of null. In my personal test, when the function is called independently or explicitly, if the input values are null and undefined, the window is bound to this by default.

When a function is called multiple times to form a call stack, the default binding rule is also valid.

Example 3

Next, we will discuss the default bound value of this in strict mode.

"use strict";function foo() {  console.log( this === undefined );}foo();               // truefoo.call(undefined); // truefoo.call(null);      // false

In strict mode, the default value of this is undefined.

Rule 4: When the function is executed independently, the default binding value of this in strict mode is undefined. Otherwise, the default binding value is window.

5. Arrow function binding

The arrow function is actually a syntactic sugar. In fact, this in the arrow function is actually this in its outer function (or window/global itself.

// ES6function foo() {  setTimeout(() => {    console.log(this === obj); // true  }, 100);}const obj = {  a : 1}foo.call(obj);// ES5function foo() {  var _this = this;  setTimeout(function () {    console.log(_this === obj); // true  }, 100);}var obj = {  a : 1}foo.call(obj);

Rule 5: When the arrow function is used, the binding value of this is the same as that of the common function (or window/global itself) on the outer layer of this function.

6. system or third-party binding

In JavaScript, a function is the first citizen. It can pass a function into any system or function provided by a third party as a value. Now we will discuss the last case. How to bind a function as a value to a system function or a third-party function.

As we mentioned at the beginning of this article, the system automatically binds this as the clicked button in two button examples.

function changeBackgroundColor() {    console.log(this === btn1); // true}btn1.addEventListener('click',changeBackgroundColor);

Then, test the binding behavior of the setTimeout interface provided by the system in the browser and node.

// Browser setTimeout (function () {console. log (this = window); // true}, 0) // nodesetTimeout (function () {console. log (this = global); // false console. log (this); // Timeout}, 0)

It is amazing that the binding behavior of setTimeout in node and browser is inconsistent. If we print this in node, we will find that it is bound to a Timeout object.

If it is the third-party interface, the situation will be more complicated. In this case, you do not know the value to bind to this of the input function unless you check the document or source code.

The system or a third party may use one or more of the preceding five rules to bind this of the incoming function. Therefore, rule 6 is actually a rule derived from the first five rules.

Rule 6: when calling an interface provided by a system or a third party, this in the input function is bound by the system or a third party.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.