Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the correct way to handle the this pointing of JS?

2025-01-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

Today, I will talk to you about how to correctly handle the this direction of JS. Many people may not know much about it. In order to make you understand better, the editor summed up the following content for you. I hope you can get something from this article.

I like to change the direction of the function execution context in JS, also known as this pointing.

For example, we can use array methods on class array objects:

Const reduce = Array.prototype.reduce;function sumArgs () {return reduce.call (arguments, (sum, value) = > {return sum + = value;});} sumArgs (1,2,3); / / = > 6

This, on the other hand, is hard to grasp.

We often find that the this we use points incorrectly. The following shows you how to simply bind this to the desired value.

Before I begin, I need a helper function, execute (func), which executes only the functions provided as arguments.

Function execute (func) {return func ();} execute (function () {return 10}); / / = > 10

Now, continue to understand the nature of errors around this: method separation.

1. Method separation problem

Suppose you have a class Person that contains fields firstName and lastName. In addition, it has a method getFullName (), which returns the person's full name. As follows:

Function Person (firstName, lastName) {this.firstName = firstName; this.lastName = lastName; this.getFullName = function () {this = agent; / / = > true return `$ {this.firstName} ${this.lastName} `;}} const agent = new Person ('front end', 'this.lastName'); agent.getFullName (); / / = > 'front end'

You can see that the Person function is called as a constructor: new Person ('front end', 'Xiao Zhi'). The this inside the function represents the newly created instance.

Getfullname () returns the person's full name: "Front end Xiaozhi". As expected, the this in the getFullName () method equals agent.

What happens if the helper function executes the agent.getFullName method:

Execute (agent.getFullName); / / = > 'undefined undefined'

The execution result is incorrect: 'undefined undefined', this is a problem caused by incorrect this pointing.

Now in the getFullName () method, the value of this is the global object (window in the browser environment). This equals window,$ {window.firstName} ${window.lastName} the result of execution is' undefined undefined'.

This occurs because the method is detached from the object when execute (agent.getFullName) is called. Basically what happens is a regular function call (not a method call):

Execute (agent.getFullName); / / = > 'undefined undefined'// is equivalent to: const getFullNameSeparated = agent.getFullName;execute (getFullNameSeparated); / / >' undefined undefined'

This is the so-called method separated from its object, and when the method is detached and then executed, the this is not connected to the original object.

1. To ensure that the this inside the method points to the correct object, you must do this

2. Execute the method in the form of a property accessor: agent.getFullName () or statically bind this to the included object (using arrow functions, .bind () methods, etc.)

The problem of method separation, which leads to incorrect this direction, generally occurs in the following situations:

Callback

The `this` in / / `this` is the global object setTimeout (object.handlerMethod, 1000).

When setting up an event handler

/ / React: `this` in `this` is the global object Click me

Then I introduce some useful methods, that is, how to make this point to the desired object if the method is separated from the object.

two。 Close the context

The easiest way to keep this pointing to an instance of a class is to use an extra variable self:

Function Person (firstName, lastName) {this.firstName = firstName; this.lastName = lastName; const self = this; this.getFullName = function () {self = agent; / / = > true return `$ {self.firstName} ${self.lastName} `;} const agent = new Person ('front-end', 'self.lastName'); agent.getFullName (); / / = > 'front-end' execute (agent.getFullName); / / > 'front-end'

GetFullName () turns off the self variable statically, effectively binding this manually.

Now, when execute (agent.getFullName) is called, everything works fine, because the this in the getFullName () method always points to the correct value.

3. Use the arrow function

Is there a way to bind this statically without attaching variables? Yes, that's what the arrow function does.

Use the arrow function to ReFactor Person:

Function Person (firstName, lastName) {this.firstName = firstName; this.lastName = lastName; this.getFullName = () = > `$ {this.firstName} ${this.lastName} `;} const agent = new Person ('front-end', 'execute'); agent.getFullName (); / / = > 'front-end execute' (agent.getFullName); / / > 'front-end intelligence'

The arrow function binds this lexically. Simply put, it uses the value from the external function this that it defines.

It is recommended that you use the arrow function in all cases where you need to use an external function context.

4. Binding context

Now let's go a step further and ReFactor Person using the classes in ES6.

Class Person {constructor (firstName, lastName) {this.firstName = firstName; this.lastName = lastName;} getFullName () {return `${this.firstName} ${this.lastName}`;}} const agent = new Person ('front end', 'const agent'); agent.getFullName (); / / = > 'front end' execute (agent.getFullName); / / > 'undefined undefined''

Unfortunately, execute (agent.getFullName) still returns "undefined undefined" even with the new class syntax.

In the case of classes, it is not feasible to use additional variables self or arrow functions to fix the pointing of this.

But there is a trick that involves the bind () method, which binds the context of the method to the constructor:

Class Person {constructor (firstName, lastName) {this.firstName = firstName; this.lastName = lastName; this.getFullName = this.getFullName.bind (this);} getFullName () {return `${this.firstName} ${this.lastName}`;} const agent = new Person ('front-end', 'this.lastName'); agent.getFullName (); / / = > 'front-end' execute (agent.getFullName); / / > 'front-end'

The this.getFullName = this.getFullName.bind (this) in the constructor binds the method getFullName () to the class instance.

Execute (agent.getFullName) works as expected and returns' front-end intelligence'.

5. Fat arrow method

The bind way is a little too verbose, we can use the fat arrow way:

Class Person {constructor (firstName, lastName) {this.firstName = firstName; this.lastName = lastName;} getFullName = () = > {return `$ {this.firstName} ${this.lastName} `;}} const agent = new Person ('front end', 'const agent'); agent.getFullName (); / / = > 'front end' execute (agent.getFullName); / / > 'front end'

Fat Arrow method getFullName = () = > {… Bind to a class instance, even if the method is detached from its object.

This method is the most efficient and concise way to bind this in a class.

Methods that are detached from objects can cause incorrect this pointing problems. To bind this statically, you can manually use an additional variable self to save the correct context object. A better alternative, however, is to use the arrow function, which is essentially intended to bind this lexically.

In a class, you can manually bind class methods in the constructor using the bind () method. Of course, if you don't have to use the verbose method of bind, you can also use a simple and convenient fat arrow representation.

After reading the above, do you have any further understanding of how to correctly handle the this pointing of JS? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report