The difference between ES6 ordinary functions and arrow functions

The difference between arrow function and ordinary function

As the newly added arrow function syntax in ES6, it is deeply loved by developers, and it is also a typical question that is often asked during front-end interviews. It not only simplifies our code, but also allows developers to get rid of the "erratic" this point. This article analyzes the difference between arrow functions and ordinary functions.

In my opinion, what the interviewer is most concerned about and the most critical difference between the two is the difference of this pointing. This in a normal function points to the object that the function is called, so for different callers, the value of this is different. The arrow function does not have its own this (at the same time, there are no other local variables in the arrow function, such as this, argument, super, etc.), so the this in the arrow function is fixed, and it points to the object where the function is defined .

Ordinary functions
I believe that everyone is already very familiar with the usage of ordinary functions. Let's give a simple example below.

var a  = 3;
var obj = {
    
    
    a : 1,
    foo : function(){
    
    
        console.log(this.a);
    }
}
obj.foo(); //1
var bar = obj;
bar.a = 2;
bar.foo(); //2
var baz = obj.foo;
baz(); //3

In the above code, there are three situations:

Call the method foo directly through obj. At this time, this will point to the object that calls the foo function, that is, obj;
assign the obj object to a new object bar. At this time, call the foo function through bar, and the value of this will be Point to the caller bar;
assign obj.foo to a new object baz, call the foo function through baz(), at this time this points to window;
from this we can draw a conclusion:

The this of a normal function always refers to its direct caller.
In strict mode, if no direct caller is found, this in the function is undefined.
In the default mode (non-strict mode), if no direct caller is found, this in the function points to window.
Consider the following situation again:

var obj = {
    
    
    a : 1,
    foo : function(){
    
    
        setTimeout(
            function(){
    
    console.log(this.a),3000})
    }
}
obj.foo(); //undefined

You might think that the output should be 1 at this point, but the result is undefined. Because at this time this points to the global window object.
Through the above examples, the following conclusions can be drawn:

For a method (that is, the function is called through an object), this in an ordinary function always points to its caller.
For general functions, this points to global variables (in non-strict mode) or undefined (in strict mode). In the above example, the function in setTimeout is not called by any object, so its this point is still the window object. Therefore, this can also be summarized as follows: javascript's this can be simply considered as late binding. When there is no place to bind, it will be bound to window or undefined by default.
What if we want to be able to use this in the setTimeout function in the above example? Before arrow functions appeared, we tended to use the following two methods:

Outside the setTimeout function, that is, inside the upper-level function foo, this is achieved by assigning the value of this to a temporary variable.

var obj = {
    
    
    a : 1,
    foo : function(){
    
    
        var that  = this;
        setTimeout(
            function(){
    
    console.log(that.a),3000})
    }
}
obj.foo(); //1

Bind this through bind().

var obj = {
    
    
    a : 1,
    foo : function(){
    
    
        setTimeout(
            function(){
    
    console.log(this.a),3000}.bind(this))
    }
}
obj.foo(); //1

This phenomenon has been improved after the introduction of arrow functions in ES6.

Arrow function
Arrow function is a new feature introduced in ES6, the method of use is:

()=>{
    
    console.log(this)}

The () is the parameter to be brought in, and the {} is the statement to be executed. Arrow function is a manifestation of functional programming. Functional programming focuses more on the relationship between input and output, omitting some factors of the process. Therefore, arrow functions do not have their own this, arguments, new target ( ES6) and super(ES6). Arrow functions are equivalent to anonymous functions, so new cannot be used as a constructor.
This in an arrow function always refers to this in its parent scope. In other words, the arrow function captures the this value of its context as its own this value. Any method can't change its point, such as call(), bind(), apply(). When this is called in an arrow function, it simply searches up the scope chain and finds the nearest this to use, which has nothing to do with the context of the call. Let's explain it with code.

var obj = {
    
    
    a: 10,
    b: () => {
    
    
      console.log(this.a); // undefined
      console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
    },
    c: function() {
    
    
      console.log(this.a); // 10
      console.log(this); // {a: 10, b: ƒ, c: ƒ}
    },
    d:function(){
    
    
        return ()=>{
    
    
            console.log(this.a); // 10
        }
    },
    e:function(){
    
    
      setTime
    }
  }
  obj.b(); 
  obj.c();
  obj.d()();

Simply analyze the code, this in obj.b() will inherit the this value in the parent context, that is, it has the same this point as obj, and it is the global variable window. The this point of obj.c() is the caller obj, and the this in obj.d().() also inherits from the this in the parent context, that is, the this point of d, which is obj.

Through this example, we can roughly understand the difference between this in ordinary functions and this in anonymous functions, so that we can use these two functions correctly and reasonably according to our needs in our work.

Guess you like

Origin blog.csdn.net/m1009113872/article/details/110004615