Master "this" in JS (2)

Source: Internet
Author: User

Master "this" in JS (2)

In the previous article, master the"this(1) We learned how to correctly usethisKeyword and its basic principle. We also know the decisionthisThe key factor pointing to an object is to find the current execution context ). However, if the execution context is not set in the normal way, the problem may become very difficult. In this article, I will focus on the areas where this happens and how it can be done.

Solve common problems

In this section, we will explore some of the most common problems when using the this keyword and learn how to handle this situation.

1. Use the Extracted method this

The most common error is to assign an object method to a variable and considerthisStill pointing to the original object. We can see from the example below that this is not the case at all.

var car = {  brand: Nissan,  getBrand: function(){    console.log(this.brand);  }};var getCarBrand = car.getBrand;getCarBrand();   // output: undefined

Looks likegetCarBrandIt seems that the reference iscar.getBrand()But what he actually points to isgetBrand()Itself. We already know that the most important thing to determine the context is the call-site. In the above Code, the call point isgetCarBrand()This is just a common function call.

ProofgetCarBrandTo point to a common function (baseless function, which is not bound to any function of a specific object ),alert(getCarBrand);To view the corresponding content. The alert output is as follows:

function(){  console.log(this.brand);}

getCarBrandIt is just a common function, and it is no longercarObject method. Therefore, in this case,this.brandWill be convertedwindow.brand. Of course, the output result isundefined.

If we remove (extract) A method from an object, this method will become a common function ). He and the original object are disconnected (severed), so they no longer run in the original way. In other words, a split function is no longer bound to the original object.

How can this problem be solved? OK. If you want to point to the original object, you must assign a valuegetCarBrandExplicitlygetBrand()Function binding (bind)carObject. Of course, we can use the bind () method.

var getCarBrand = car.getBrand.bind(car);getCarBrand();   // output: Nissan

Now we get the expected correct output because we have successfully redefined the desired context.

2. Use in the callback function this

The second type of problem isthis) Method as the callback function. For example:

View car brands

var car = {  brand: Nissan,  getBrand: function(){    console.log(this.brand);  }};var el = document.getElementById(btn);el.addEventListener(click, car.getBrand);

Althoughcar.getBrand, But in fact, onlygetBrand()Function associatedbuttonObject.

Passing a parameter to a function is an implicit value assignment, so this is basically the same as the previous example. The difference is thatcar.getBrandNo explicit value assignment. The result is the same. The result is only a common function, and the bound object isbutton.

In other words, when we execute a method on an object, although this method may be defined in other objectsthisThe keyword no longer points to the original object, but to the object that calls this method.

For example, in the preceding example, we useel(That is, button) to executecar.getBrandIs useless.carObject, although initially defined incarObject. Therefore,thisPointelInsteadcar.

If you do need to retain reference to the original object, you need to explicitlygetBrand()Function bindingcarObject, which can be used by each functionbind()Method.

el.addEventListener(click, car.getBrand.bind(car));

Now, you can run it as needed.

3. Use in Closure this

Use in closuresthisIt may also cause errors. See the following example:

var car = {  brand: Nissan,  getBrand: function(){    var closure = function(){      console.log(this.brand);    };    return closure();  }};car.getBrand();   // output: undefined

Here, the output isundefinedBecause the closure function (internal function) cannot access the external FunctionthisVariable. So the final result isthis.brandEquivalentwindow.brandBecausethisThe bound global object.

To solve this problem, we canthisBindgetBrand()Function.

Var car = {brand: Nissan, getBrand: function () {var closure = function () {console. log (this. brand );}. bind (this); // pay attention to return closure () ;}}; car. getBrand (); // output: Nissan

The binding here is equivalentcar.getBrand.bind(car).

Another common method for processing closures is to firstthisAssign values to another variable to avoid unnecessary changes.

var car = {  brand: Nissan,  getBrand: function(){    var self = this;    var closure = function(){      console.log(self.brand);    };    return closure();  }};car.getBrand();   // output: Nissan

Here, we can assign the _ this value_this,that,self,me,my,contextOr other variable names with such meanings. The key is to keep the object reference of the lower outer layer.

High technology in ECMAScript 6

In the preceding example, we can see thatthis"Usage, that is, we canthisAssign a value to another variable. In ECMAScript 6, we can use the more elegant new technology, the arrow function to achieve similar results.

Arrow-functions does not passfunctionThe keyword is created through the so-called "fat arrow" Operator (fat arrow,=>. Unlike general functions, the arrow function obtainsthisValue. The syntax binding of Arrow functions is not overwritten, even if the new operator is used.

Next let's take a look at how arrow functions are replaced.var self = this;For this statement:

Var car = {brand: Nissan, getBrand: function () {// The Arrow function retains the syntax of this scope. var closure = () => {console. log (this. brand) ;}; return closure () ;}}; car. getBrand (); // output: Nissan
About thisKnowledge Point

Like other mechanisms,thisKeywords also follow some simple rules. If you understand these rules, you can use them more smoothly. The following is a quick review of the knowledge points learned in these two sections:

In the following cases thisIt points to a global object:
In the code at the outermost layer, not in any function, it is not a constructor in the method function of the object method) when the function is called as the property of the parent object, thisIt points to the parent object ). When the function passes call(), apply()Or bind()When calling, thisIt points to the first parameter passed to these methods. If the first parameter is nullOr is not an object thisIt points to a global object. In use newWhen an operator calls a function, thisPoint to the newly created object. When the arrow function is used in ECMAScript 6, thisPoints to the parent object (parent object) according to the syntax scope ).

After understanding these simple and direct rules, we can easily seethisWhich object is pointed to? If the point is incorrect, you can use the learned black technologies.

Summary

MasterthisIt is not easy, but if you use enough, you will naturally understand. I hope that this series of blog posts will help you lay a solid foundation and deepen your understanding. Then, you will be able to understand the relevant issues next time.

 

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.