1. Introduction

In ES6, if you can use ()=>, you should use the arrow function as much as possible. In other languages, the arrow function has a fancy name Lambda expression.

There are no window objects in the nodeJS environment

2. This point

This refers to the object on which it was last called without the use of apply, call and arrow functions. If it was last called by a function, it refers to undefined in strict mode and to the global variable window in non-strict mode.

The following examples are all non-strict modes.

var a = 1;
var obj = {
  a: 2.b: function() {
    return this.a; }};console.log(obj.b()); / / 2
Copy the code

The above example should be clear, because the last time b was called was obj, and the value of a in obj was 2, so this example prints 2.

So let’s make it harder and look at the following example.

var a = 1;
var obj = {
  a: 2.b: function() {
    return this.a; }};var t = obj.b;
console.log(t());
console.log(obj.b());
console.log(t() === obj.b()); 
console.log(t === obj.b); 
Copy the code

So let’s add a new variable t, and let’s assign the method B to t, and let’s think about what the function t is going to output.

Something amazing happened!

console.log(t()); / / 1
console.log(obj.b()); / / 2
console.log(t() === obj.b()); //false
console.log(t === obj.b); //true
Copy the code

The output of t is 1.

Because t is called this time and its object is window, and because the value of a on the object window is 1, t’s final output is 1.

The same goes for the following example.

var a = 1;
var obj = {
  a: 2.b: function() {
    function fun() {
      return this.a;
    }
    console.log(fun()); }}; obj.b();/ / 1
Copy the code

Since fun is called by b, the last call to fun is not an object, so this refers to the global variable window.

3. Arrow function

  • The arrow function captures its contextthisValue, as its ownthisValue.
  • Arrow functions have no this binding and must determine its value by looking up the scope chain. If the arrow function is contained by a non-arrow function, this is bound to the nearest non-arrow function’s this; otherwise, this isundefined.

3.1 Pain points solved

Using this in ES5 syntax can sometimes make it difficult to predict what this is pointing at and cause bugs, a problem that is especially evident in the framework era when classes are encapsulated. If you’ve learned React, this is always a headache when passing functions from parent components to child components.

Although the use of Call,apply, and bind can solve this pain point, additional code is required, which not only increases the workload, but also increases the maintenance cost.

3.2 Simple Questions

var a = 1;
var obj = {
  a: 2.b: () = >{
    return this.a; }};console.log(obj.b()); / / 1
Copy the code

Since B is declared by the arrow function, its this refers to obj’s this, which is the global variable window.

3.3 Medium Topics

var a = 1;
var obj = {
  a: 2.b: function () {
    var fun = () = > {
      return this.a;
    };
    console.log(fun()); }}; obj.b();/ / 2
Copy the code

Since the arrow function looks for the context’s this, the object found above is method B’s this, which is obj.

var a = 1;
var obj = {
  a: 2.b: () = > {
    var fun = () = > {
      return this.a;
    };
    console.log(fun()); }}; obj.b();/ / 1
Copy the code

The arrow function doesn’t have this, so fun looks for this layer by layer and finally finds the object obj’s this.

4. call,apply,bind

The apply() method calls a function with a specified this value and arguments supplied as an array (or array-like object)

The bind() method creates a new function that, when called, sets its this keyword to the supplied value and, when called, provides a given sequence of arguments before any supply.

  1. Apply: Calls a method on an object that replaces the current object with another. B. ply(A, arguments); The method that object A applies to object B.

  2. Call: Calls a method on an object that replaces the current object with another. For example, b. call(A, args1,args2); That is, the method that object A calls object B.

  3. Bind: Takes the same arguments as call, except that it returns a function.

4.1 Arrow Function

This cannot be changed, so calling call,apply, and bind to arrow functions has no effect

var a = 1;
var obj = {
  a: 2.b: function () {
    var fun = () = > {
      return this.a;
    };
    console.log(fun.call(a)); }}; obj.b();/ / 2
Copy the code

4.2 Special Circumstances

var a = 1;
var obj = {
  a: 2.b: function () {
    var fun = () = > {
      return this.a;
    };
    console.log(fun()); }};var obj1 = {
  a: 3}; obj.b.call(obj1);/ / 3
Copy the code

The arrow function’s this cannot be changed, but its context’s this can be changed.

5. Lots of questions

With all that said, let’s take a look at the following questions:

var age = 10;
var person = {
  age: 20.getAge() {
    var age = 30;
    return this.age; / / 20}};console.log(age, age * 2); / / 10 20
console.log(person.getAge()); / / 20
var b = person.getAge;
console.log(b()); / / 10
console.log(person.getAge()); / / 20
console.log((1, person.getAge)()); / / 10
console.log((1, person.getAge.bind(person))()); / / 20
console.log((person.getAge, person.getAge)()); / / 10
console.log((person.getAge = person.getAge)()); / / 10
console.log(person.getAge.call()); / / 10
console.log(person.getAge.call(person)); / / 20
function getAge2() {
  this.age = 40;
  console.log(person.getAge());
}
getAge2(); / / 20
console.log(age); // The Node environment is different from the browser environment because the browser environment has the Window object
function getAge3() {
  this.age = 50;
  this.getAge4 = () = > {
    console.log(person.getAge.call(this)); / / 50
  };
}
console.log(new getAge3().getAge4());
console.log(age); / / 10
function getAge4() {
  this.age = 60;
  this.getAge5 = () = > {
    console.log(person.getAge.call(this)); / / 60
  };
}
console.log(new getAge4().getAge5()); //undefined
console.log(age); / / 10
var age2 = 10;
var person2 = {
  age2: 20.getAge2: () = > {
    var age2 = 30;
    return this.age2; }};console.log(person2.getAge2.call()); / / 10
console.log(person2.getAge2.call(person2)); / / 10
Copy the code

6. Stop using self=this and that=this

This should be the end of the article, but! It’s a new era now! We can use the arrow function to avoid using const self = this as much as possible. I wasn’t sure why React and Vue were in the era of functional programming until I read a code that had const self = this. Let’s take a look at the following code:

<template> <div> < button@click ="click"> </button> <div>{{center}}</div> </template> <script> export default { Const self = this const self = this; return { self: 100, center: 50, test: { click: () => { console.log(self.self); // What does this mean? this.center = 10; console.log(this.center); ,}}}; }, methods: { click() { this.test.click(); ,}}}; </script> <style scoped></style>Copy the code

You can see that this code, self and this, is just a simplified version of the code THAT I took from the project. The original code is more complex. Let’s take a look at the test position in the original project:

amapEvents: {
  // The arrow function is used
  click: (e) = > {
    let { lng, lat } = e.lnglat;
    // self is this
    console.log(self.plugin);
    self.plugin[1];
    let address;
    // There is no arrow function here
    self.plugin[1].getAddress([lng, lat], function (status, result) {
      if (status === "complete" && result.info === "OK") {
        if (result && result.regeocode) {
          // Self is not this because there is no arrow function
          self.address = result.regeocode.formattedAddress;
          address = self.address;
          console.log("Address:"+ self.address); self.$nextTick(); }}});this.center = [lng, lat];
    this.address = address; }},Copy the code

No? Dizziness? This project is both this and self, and it uses arrow functions and does not use arrow functions. The most important thing is that it also places functions in data! This is a violation of the basic code, so it is best to use arrow functions in projects, because arrow functions this will look up layer by layer. After I use the arrow function, I don’t have to worry about this anymore!