search
HomeWeb Front-endJS TutorialEverything you want to know about this is here

Everything you want to know about this is here

Jan 23, 2017 pm 04:12 PM
javascriptfront end

Whether in the daily use of javascript or in the front-end interview process, this has a very high appearance rate. This undoubtedly illustrates the importance of this. But this is very flexible, which makes many people find the behavior of this difficult to understand. This article starts with why this is necessary and summarizes the six rules of this. I hope it can help you answer your confusion.

Introduction

This is actually equivalent to a parameter. This parameter may be passed in manually during development, or it may be JS or the third Incoming from three parties.
This parameter usually points to the "owner" when the function is executed. The this mechanism can make function design more concise and more reusable.

this is bound when the function is executed. There are six binding rules in total, which are:

●new binding: When using the new keyword to create an object, this will be bound to on the created object.

●Explicit binding: When explicitly bound using the call, apply or bind method, this is its first parameter.

●Implicit binding: When a function is executed on an object, the system will implicitly bind 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 the global object.

●Arrow function binding: When using arrow functions, the binding value of this is equal to the this of its outer ordinary function (or the global object itself).

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

The role of this

This mechanism provides an elegant way to implicitly pass an object, which allows function design More concise and better reusable.

Consider the following example, there are two buttons that change their background to red when clicked.

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, you can take advantage of this feature of implicitly passing context to get 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, this formal parameter. In the second example, it is replaced by a special keyword this. This has a similar function to formal parameters. It is essentially a reference to an object. Its special feature is that it does not require manual value transfer, so it is simpler and more convenient to use.

Six Rules

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

1.new binding

When using new to create an object, this in the class refers to What is?

class Person {
  constructor(name){
    this.name = name;
  }
  getThis(){
    return this
  }
}
const xiaoMing = new Person("小明");
console.log(xiaoMing.getThis() === xiaoMing); // true
console.log(xiaoMing.getThis() === Person); // false
console.log(xiaoMing.name === "小明"); // true

In the above example, the Person class was created using ES6 syntax. In the process of creating an object using the new keyword, this will be automatically bound to the created object by the system, that is, xiaoMing.

Rule 1: When using the new keyword to create an object, this will be bound to the created object.

2. Explicit binding


Scenario 2, use call, apply and bind methods to explicitly bind this parameter .

Take call as an example. The first parameter passed in to 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 );

In the case of explicit passing, the object pointed to by this is obvious, which is the first parameter of the call, apply or bind method.

Rule 2: When explicitly bound using the call, apply or bind method, this is its first parameter.

3. Implicit binding


The difference between implicit binding and explicit binding is that explicit binding It is up to the developer to specify this; when implicitly bound, the function or method will have an "owner", and this "owner" refers to the function or method object that is directly called.

Example 1

Let’s look at the simplest example first.

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 hung in the object obj, and the function bar is defined outside and then hung on the object obj. No matter where the function is defined, when the function is finally called, its "owner" is obj. So this points to the "owner" obj when the function is called.

Example 2

In order to have a deeper understanding and consider the situation of reassigning a function to a new object, let’s take a look at the following example.

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 the function is called, the "owner" is obj2, not obj1. So this points to obj2.

Example 3

Objects can be nested at multiple levels. In this case, when a function is executed, who is the "owner" of the function?

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

obj1.obj2.foo()

foo The direct caller in the method/function is obj2, not obj1, so the "owner" of the function points to the nearest direct caller.

Example 4

如果一个方法/函数,在它的直接对象上调用执行,又同时执行了 call 方法,那么它是属于隐式绑定还是显式绑定呢?

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

由上,可以看出,如果显式绑定存在,它就不可能属于隐式绑定。

规则三:如果函数是挂在对象上执行的,这个时候系统会隐式的将 this 绑定为函数执行时的“拥有者”。

4.默认绑定

前一小段,讨论了函数作为对象的方法执行时的情况。本小段,要讨论的是,函数独立执行的情况。

在函数直接调用的情况下,this 绑定的行为,称之为默认绑定。

例一

为了简单起见,先讨论在浏览器的非严格模式的下绑定行为。

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

在上面的例子中,系统将 window 默认地绑定到函数的 this 上。

例二

在这里,先介绍一种我们可能会在代码中见到的显式绑定 null 的写法。

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

foo.apply(null);

将例一默认绑定的情况,改为了显式绑定 null 的情况。

在实际开发中,我们可能会用到 apply 方法,并在第一个参数传入 null 值,第二个参数传入数组的方式来传递数组类型的参数。这是一种传统的写法,当然现在可以用 ES6 的写法来代替,但是这不在本文的讨论范围内。

在本例最需要关注的是,this 竟然指向的 window 而不是 null。个人测试的结果是,在函数独立调用时,或者显式调用,传入的值为 null 和 undefined 的情况下,会将 window 默认绑定到 this 上。

在函数多次调用,形成了一个调用栈的情况下,默认绑定的规则也是成立的。

例三

接着,探讨下严格模式下,this 的默认绑定的值。

"use strict";

function foo() {
  console.log( this === undefined );
}

foo();               // true
foo.call(undefined); // true
foo.call(null);      // false

在严格模式下,this 的默认绑定的值为 undefined。

规则四:在函数独立执行的情况下,严格模式 this 的默认绑定值为 undefined,否则默认绑定的值为 window。

5.箭头函数绑定

箭头函数实际上,只是一个语法糖,实际上箭头函数中的 this 实际上是其外层函数(或者 window/global 本身)中的 this。

// ES6
function foo() {
  setTimeout(() => {
    console.log(this === obj); // true
  }, 100);
}

const obj = {
  a : 1
}

foo.call(obj);

// ES5
function foo() {
  var _this = this;

  setTimeout(function () {
    console.log(_this === obj); // true
  }, 100);
}

var obj = {
  a : 1
}

foo.call(obj);

规则五:使用箭头函数时,this 的绑定值和其外层的普通函数(或者 window/global 本身) this 绑定值相同。

6.系统或第三方绑定

在 JavaScript 中,函数是第一公民,可以将函数以值的方式,传入任何系统或者第三方提供的函数中。现在讨论,最后一种情况。当将函数作为值,传入系统函数或者第三方函数中时,this 究竟是如何绑定的。

我们在文章一开始提到的,两个按钮例子,系统自动将 this 绑定为点击的按钮。

function changeBackgroundColor() {    console.log(this === btn1); // true}

btn1.addEventListener('click',changeBackgroundColor);

接着测试系统提供的 setTimeout 接口在浏览器和 node 中绑定行为。

// 浏览器
setTimeout(function () {
  console.log(this === window); // true
},0)

// node
setTimeout(function () {
  console.log(this === global); // false
  console.log(this); // Timeout
},0)

很神奇的是,setTimeout 在 node 和浏览器中的绑定行为不一致。如果我们将 node 的中的 this 打印出来,会发现它绑定是一个 Timeout 对象。

如果是第三发提供的接口,情况会更加复杂。因为在其内部,会将什么值绑定到传入的函数的 this 上,事先是不知道的,除非查看文档或者源码。

系统或者第三方,在其内部,可能会使用前面的五种规则一种或多种规则,对传入函数的 this 进行绑定。所以,规则六,实际上一条在由前五条规则上衍生出来的规则。

规则六:调用系统或者第三方提供的接口时,传入函数中的 this 是由系统或者第三方绑定的。

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Understanding the JavaScript Engine: Implementation DetailsUnderstanding the JavaScript Engine: Implementation DetailsApr 17, 2025 am 12:05 AM

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python vs. JavaScript: The Learning Curve and Ease of UsePython vs. JavaScript: The Learning Curve and Ease of UseApr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python vs. JavaScript: Community, Libraries, and ResourcesPython vs. JavaScript: Community, Libraries, and ResourcesApr 15, 2025 am 12:16 AM

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

From C/C   to JavaScript: How It All WorksFrom C/C to JavaScript: How It All WorksApr 14, 2025 am 12:05 AM

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

JavaScript Engines: Comparing ImplementationsJavaScript Engines: Comparing ImplementationsApr 13, 2025 am 12:05 AM

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

Beyond the Browser: JavaScript in the Real WorldBeyond the Browser: JavaScript in the Real WorldApr 12, 2025 am 12:06 AM

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)Apr 11, 2025 am 08:22 AM

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft