Points needing attention in arrow function

Time:2021-4-30

1、 Introduction

I believe you are familiar with ES6 arrow function, and we will often use it in the process of daily development, but what are the points of arrow function that we should pay attention to?

2、 Some points for attention in using arrow function

1. This object in the function body is the object when it is defined, not the object when it is used

We all know that,This in a normal function points to the scope of the runtimeBut the arrow function is not,This in the arrow function is the scope of the binding definition

  • Ordinary function
function foo() {
  setTimeout(function() {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });            //id: 21
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });            //id: 42

As can be seen from the above two examples, the callback function in setTimeout runs in the scope of window, but this is defined in the scope of foo. Therefore, if it is a normal function, this should point to the global object window during execution, which should output 21. But,The arrow function causes this to always point to the object in which the function definition takes effectSo the output is 42

Using this characteristic of arrow function, we canYou can use the arrow function to make this point fixedThis feature is very importantIt is helpful to encapsulate the callback function. Here is an example. The callback function of DOM event is encapsulated in an object.

var handler = {
  id: '123456',

  init: function() {
    document.addEventListener('click',
      event => this.doSomething(event.type), false);
  },

  doSomething: function(type) {
    console.log('Handling ' + type  + ' for ' + this.id);
  }
};

In the init method of the above code, the arrow function is used, which causes this in the arrow function to always point to the handler object. Otherwise, when the callback function runs, the line this.dosomething will report an error, because this points to the document object.

A lot of kids will be surprised,Why doesn’t this of the arrow function change because the scope of the function changes at run time

In fact, the actual reason is thatThe arrow function does not have its own this at all, so the internal this is the outer code block’s this.

Therefore, the code for converting the arrow function to Es5 is as follows:

// ES6
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);        // In fact, this is the one that uses the outer scope
  }, 100);
}

// ES5
function foo() {
  var _ this = this;            // Copy this of the outer scope to a variable

  setTimeout(function () {
    console.log('id:', _this.id);
  }, 100);
}

2. It can’t be used as a constructor, that is, you can’t use the new command, otherwise an error will be thrown

The first point above says:Arrow function does not have its own this, so of course arrow function can not be used as a constructor

Let’s try to use the arrow function as the constructor:

var fun = (id, name) => {
    this.id = id;
    this.name = name;
    this.showName = () => {
        console.log(this.name);
    }
};

let obj = new fun(1, "hdl");     //TypeError: fun is not a constructor
obj.showName();

Sure enough, an error was reported, saying that fun is not a constructor, which in turn confirms the first point: the arrow function does not have this.

3. Arguments object cannot be used, it does not exist in function body. If you want to use, you can use the rest parameter instead.

function func1(a, b) {
    console.log(arguments);
}

let func2 = (a, b) => {
    console.log(arguments);     //arguments is not defined
}

func1(1, 2);
func2(1, 2);

If you have to print function parameters, you canUse rest parameter instead of arguments object in arrow function

function func1(a, b) {
    console.log(arguments);
}

let func2 = (...rest) => {
    console.log(rest);     //[1, 2]
}

func1(1, 2);
func2(1, 2);

4. No new.target

New. Target is a new property introduced in ES6. If a common function is called through new,New. Target returns a reference to the function

function Cat() {
    console.log(new.target); 
}
let cat = new Cat(); // ƒ Cat() { console.log(new.target); }

This property is mainlyUsed to determine whether the constructor is a new call

Using new. Target in the arrow function will report an error.

//Ordinary function
let a = function() {
    console.log(new.target);
}
a(); // undefined

//Arrow function
let b = () => {
    console.log(new.target); //  Error: uncaught syntax error: new.target expression is not allowed here
};
b();

5. No prototype and super

Because it cannot be called through the new keyword, it cannot be used as a constructorThe arrow function does not have the attribute prototype

let func = () => {};
console.log(func.prototype) // undefined

The arrow function has no prototype,Therefore, you cannot access the properties of the prototype through superSo the arrow function has no super. Like this, arguments, and new. Target, these values are determined by the nearest non arrow function.

6. The call / apply / bind method cannot change the direction of this in the arrow function

It’s easy to understand,The common feature of call (), apply (), and bind () methods is that they can change the direction of this, which is used to dynamically modify the direction of this when the function is executed. But becauseThis definition of the arrow function has been determined and will not change. So these three methods can never change the direction of the arrow function this.

var name = 'global name';
var obj = {
    name: 'huangdonglu'
}
//The arrow function is defined in the global scope
let func = () => {
    console.log(this.name);
};

func();     // global name
//The direction of this will not change. It will always point to the window object and the global variable under the window
func.call(obj);     // global name
func.apply(obj);    // global name
func.bind(obj)();   // global name

7. The analytic order of arrow function is relative to that before examination

Although the arrow in the arrow function is not an operator, the arrow function has a special operator priority resolution rule different from the regular function.

let a = false || function() {}; // ok
let b = false || () => {}; // SyntaxError: Malformed arrow function parameter list
let c = false || (() => {}); // ok

8. Arrow function does not support duplicate name parameters

function foo(a, a) {
    console.log(a, arguments); // 2 Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}

Var boo = (a, a) = > {// direct error: uncaught syntax error: duplicate parameter name not allowed in this context
    console.log(a);
};
foo(1, 2);
boo(1, 2);

9. The yield command cannot be used, so the arrow function cannot be used as the generator function.

3、 Arrow functions are not applicable to scenarios

As we all know, arrow function is much simpler than ordinary function, but arrow function is not suitable for any scene.

1. The first occasion is to define the method of the object, and the method includes this.

  • The function in the object uses the arrow function
const cat = {
    lives: 9,
    jumps : () => {
        this.lives--;
    }
};

cat.jumps();
console.log(cat.lives);     //9
  • The methods in the object use common methods
const cat = {
    lives: 9,
    jumps() {
        this.lives--;
    }
};

cat.jumps();
console.log(cat.lives);     //8

In the above code, the cat. Jumps () method is an arrow function, which is an error. When calling cat. Jumps(), if it is an ordinary function, this in the method points to cat; IfWrite an arrow function like the one above to make this point to the global objectTherefore, the expected results will not be obtained. that is becauseObject does not form a separate scope, so the scope of the jumps arrow function is the global scope

2. Dynamic functions should not be used when dynamic this is needed.

var btn = document.getElementById('btn');
btn.addEventListener('click', () => {
  console.log(this);
});

Because BTN’s listening function is an arrow function,This is the global objectIt doesn’t meet the needs of the button itself that we want to operate.If it is changed to a normal function, this will dynamically point to the button object to be clicked.

In addition to the above two points, it also summarizes the following points:

  • Should not be used on methods that define objects
  • Callback functions with dynamic context should also not use arrow functions
  • Cannot be applied in a constructor
  • Avoid using on Prototype
  • Avoid using on arguments

4、 Summary

Let’s summarize the above. Thank you for your articlePoints for attention in using arrow functionRecently, I’m also reading “in depth understanding ES6” by Nicholas. I hope I can be more familiar with ES6. I also hope you can supplement and correct this article.

Recommended Today

External part – Visual Studio code and vue.js

Fan waipian Seaconch is so tired that he can’t help writing this article I can’t help but recommend new editors. I can’t help but use them everywherevs codeThis editor To whom? I don’t know, when the same person is like meFrom vsThen maybe you will feel the same as me~ Start learning in Mayvue.jsUp to […]