Master JS in the "This" (ii)

Source: Internet
Author: User
Tags babeljs

In the previous article Mastering JS " this (a) inside, we learned how to correctly use the keyword in JavaScript this and its basic principles. We also know this that the key factor in deciding which object to point to is to find out the current execution context (execution context). But if the execution context is not set up in the normal way, the problem can become tricky. In this article, I'll focus on where this happens and how it can be remedied.

Troubleshoot common issues

In this section, we'll explore some of the most common issues with the This keyword and learn how to handle it.

1. Use in the method of disassembly (extracted) this

The most common mistake is to assign the method of the object to a variable and assume that the function still points to the this original object. We can see from the following example 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

It seems to be getCarBrand quoted car.getBrand() , but in fact he points to only getBrand() himself. We already know that the most important thing in determining the context is the call point (Call-site), in the above code, the call point is getCarBrand() , this is just a normal function call.

getCarBrandthe method that proves pointing to a normal function (baseless function, which is not bound to any particular object) is used alert(getCarBrand); to view the corresponding content, and the output of alert is as follows:

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

getCarBrandJust a normal function, it is no longer the car object's method. So, in this case, it this.brand will actually be converted to window.brand . The result of the output is of course undefined .

If we remove a method from an object (extract), then this method becomes a normal function. His connection to the original object was cut off (severed), so no longer works as it was. In other words, a detached function is no longer bound to the original object.

How do we deal with this situation? OK, if you want to point to the original object, you need to getCarBrand explicitly getBrand() bind the function (BIND) to the object when assigning it, and car of course we can use the bind () method.

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

Now we have the expected correct output as we successfully redefine the desired context.

2. Use in callback functions this

The second type of problem is the use of a (used this ) method as a callback function. For example:

<button id="btn" type="button">查看汽车品牌</button>

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

Although it is used car.getBrand , it is actually just getBrand() associating the function to the button object.

Passing parameters to a function is an implicit assignment, so this is basically the same as the previous example. The difference is that car.getBrand no value is explicitly assigned at this time. The result is the same, get just a normal function, the bound object is button .

In other words, when we execute a method on an object, although the method may be defined within another object, the this keyword no longer points to the original object, but instead points to the object that called the method.

In the example above: we use (that is, the el button) to execute car.getBrand , but not the car object, although it was originally defined in the car object. So, the this point is el , instead of car .

If you do need to keep a reference to the original object, you need to explicitly getBrand() bind the function to the car object, and you can use the methods that each function has bind() .

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

Now, you can run it the way you want.

3. Use in closures (Closure) this

Use in closures can this also cause errors. Look at 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 we get is undefined because the closure function (that is, the intrinsic function) cannot access the variables of the external function this . So the end result is this.brand equivalent window.brand , because the inner function this is bound to a global object.

For this problem, we can this bind to the getBrand() function.

var car = {  brand: "Nissan",  getBrand: function(){    var closure = function(){      console.log(this.brand);    }.bind(this);// 注意这里    return closure();  }};car.getBrand();   // output: Nissan

The bindings here are equivalent car.getBrand.bind(car) .

Another common way to deal with closures is to assign a this value 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,,,,, and so _this that on, self me my context or other variable names that have this kind of meaning. The key is to preserve the lower outer object reference.

High-Tech in ECMAScript 6

In the example above, we see the use of "syntactic formality this ," which means that we can assign a this value to another variable. In ECMAScript 6 We can use the more elegant new technique, arrow function, to achieve a similar effect.

Arrow-functions is not function created by the keyword, but by the so-called "fat Arrow" operator (fat Arrow => ). Unlike the general function, the arrow function takes a value from its enclosing range (enclosing scope) this . The syntax bindings for the arrow functions are not overwritten, even if the new operator is used.

Let's take a look at how the arrow functions replace var self = this; this statement:

var car = {  brand: "Nissan",  getBrand: function(){    // 箭头函数保留了语法上的 "this" 作用域.    var closure = () => {         console.log(this.brand);    };    return closure();  }};car.getBrand();   // output: Nissan
About thisThe Knowledge point

As with other mechanisms, this keywords follow a few simple rules, and if you know the rules, you can use them more smoothly. The following is a quick review of the knowledge points learned in these two sections:

    • The global object is pointed to in the following cases this :
      • In the outermost code, not in any function.
      • Functions that are not object methods (method)
      • is not a constructor (constructor) function inside
    • When a function is called as a property of the parent object, this the parent object is pointed to.
    • When a function passes call() , apply() or bind() is called, this it points to the first argument passed to these methods. If the first parameter is anull
    • Or is not an object, then this the global object is pointed to.
    • newwhen you use an operator to invoke a function, this it points to the newly created object.
    • When you use the arrow function in ECMAScript 6, you this point to the Ancestor object (parent object) According to the scope of the syntax you are at.

With these simple and straightforward rules in hand, we can easily see this which object is pointing, and if it does, it can be done with the black technology we've learned.

Summarize

Mastering JavaScript this is not easy, but if you use it enough, you will naturally understand it. Hopefully this series of blogs will help you lay the groundwork and deepen your understanding, and then you'll have a good idea of the next time you have a problem.

Recommended Reading

Nanyi Teacher: ECMAScript 6 Getting Started

Some learning summaries of cnblog:javascript context and scope

Infoq: ES6 (1~10) series

babeljs-es6:https://babeljs.io/repl/

Master JS in the " this " (a)

Master js " this " (ii)

RELATED LINKS

GitHub version: https://github.com/cncounter/translation/blob/master/tiemao_2015/20_JavaScript_Mastering_this/ Javascript_mastering_this.md

Original link: http://www.sitepoint.com/mastering-javascripts-this-keyword/

Author: Anchor Http://blog.csdn.net/renfufei

Date: September 22, 2015

Master JS in the "This" (ii)

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.