Moment For Technology

ES6 series arrow functions

Posted on Sept. 21, 2022, 1:31 p.m. by 何婉婷
Category: The front end Tag: javascript react.js The front end Immutable.js

review

Let's start by reviewing the basic syntax of arrow functions.

ES6 added arrow functions:

let func = value=  value;
Copy the code

Is equivalent to:

let func = function (value) {
    return value;
};
Copy the code

If you need to pass more than one argument to a function:

let func = (value, num) =  value * num;
Copy the code

If a function block requires more than one statement:

let func = (value, num) =  {
    return value * num
};
Copy the code

If you need to return an object directly:

let func = (value, num) =  ({total: value * num});
Copy the code

Combined with variable deconstruction:

let func = ({value, num}) =  ({total: value * num})

/ / use
var result = func({
    value: 10.num: 10
})

console.log(result); // {total: 100}
Copy the code

Most of the time, you probably won't think of using it this way, so for example, in the React versus Immutable technique selection, we do this for an event:

handleEvent = (a)=  {
  this.setState({
    data: this.state.data.set("key"."value")})};Copy the code

In fact, it can be simplified as:

handleEvent = (a)=  {
  this.setState(({data}) =  ({
    data: data.set("key"."value")}}));Copy the code

To compare

This article focuses on comparing arrow functions with ordinary functions.

The main differences include:

1. Without this

The arrow function doesn't have this, so you need to find its value by looking in the scope chain.

This means that if an arrow function is contained by a non-arrow function, this is bound to the nearest non-arrow function's this.

Simulate an example in real development:

Our requirement is to click a button and change the background color of the button.

For ease of development, we extract a Button component and, when needed, use it directly:

// Passing the element ID will bind the event that changes the background color when the element is clicked
new Button("button")
Copy the code

The HTML code is as follows:

button id="button"Click on the color/button
Copy the code

The JavaScript code is as follows:

function Button(id) {
    this.element = document.querySelector("#" + id);
    this.bindEvent();
}

Button.prototype.bindEvent = function() {
    this.element.addEventListener("click".this.setBgColor, false);
};

Button.prototype.setBgColor = function() {
    this.element.style.backgroundColor = '#1abc9c'
};

var button = new Button("button");
Copy the code

TypeError: Cannot read property 'style' of undefined TypeError: Cannot read property 'style' of undefined

This is because when an element is registered for an event using addEventListener(), the this value in the event function is a reference to that element.

So if we have console.log(this) in setBgColor, and this points to the button element, then this.element is undefined, and an error is expected.

You might ask, since this refers to the button element, let's just change the setBgColor function to:

Button.prototype.setBgColor = function() {
    this.style.backgroundColor = '#1abc9c'
};
Copy the code

Wouldn't that solve the problem?

It is possible to do this, but in real development we might call other functions in setBgColor as well, such as this:

Button.prototype.setBgColor = function() {
    this.setElementColor();
    this.setOtherElementColor();
};
Copy the code

So we still want this in setBgColor to refer to the instance object so that we can call other functions.

With ES5, we typically do this:

Button.prototype.bindEvent = function() {
    this.element.addEventListener("click".this.setBgColor.bind(this), false);
};
Copy the code

To avoid the effects of addEventListener, use bind to force this of setBgColor() to be an instance object

With ES6, we can better solve this problem:

Button.prototype.bindEvent = function() {
    this.element.addEventListener("click", event = this.setBgColor(event), false);
};
Copy the code

Since the arrow function doesn't have this, it looks for the value of this in the outer layer, which in bindEvent refers to the instance object, so it correctly calls this.setBgColor. This in this.setBgColor also points correctly to the instance object.

As an additional note, note that bindEvent and setBgColor are used as normal functions, not arrow functions. If we changed to arrow functions, this would point to the window object (in non-strict mode).

Finally, since the arrow function does not have this, it cannot use call(), apply(), or bind() to change the pointer to this. Here's an example:

var value = 1;
var result = (() =  this.value).bind({value: 2}) ();console.log(result); / / 1
Copy the code

2. 没有 arguments

The arrow function does not have its own arguments object, which is not necessarily a bad thing, since the arrow function can access the arguments object of the peripheral function:

function constant() {
    return (a)=  arguments[0]}var result = constant(1);
console.log(result()); / / 1
Copy the code

What if we just want to access the arguments to the arrow function?

You can access parameters either as named parameters or as REST parameters:

let nums = (. nums) =  nums;
Copy the code

3. The new keyword cannot be used

JavaScript functions have two internal methods: [[Call]] and [[Construct]].

When a function is called from new, the [[Construct]] method is executed to create an instance object, and then the function body is executed to bind this to the instance.

When called directly, the [[Call]] method executes the function body directly.

The arrow function does not have a [[Construct]] method and cannot be used as a constructor. If called from new, an error will be reported.

var Foo = (a)=  {};
var foo = new Foo(); // TypeError: Foo is not a constructor
Copy the code

4. There is no new target

Because you can't use the new call, there is no new. Target value.

For new.target, see es6.ruanyifeng.com/#docs/class...

5. There are no prototypes

Since you can't call the arrow function with new, there's no need to build a prototype, so the arrow function doesn't have the prototype property.

var Foo = (a)=  {};
console.log(Foo.prototype); // undefined
Copy the code

6. There is no super

There is no super for arrow functions, but just like this, arguments, and new.target, these values are determined by the nearest non-arrow function.

conclusion

Finally, an introduction to the arrow function, citing MDN, is:

An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. These function expressions are best suited for non-method functions, and they cannot be used as constructors.

Translation:

Arrow function expressions have a shorter syntax than function expressions and do not bind their own this, arguments, super, or new.target. These function expressions are best used for non-method functions, and they cannot be used as constructors.

What are non-method functions?

Let's look at the definition of method:

A method is a function which is a property of an object.

A function in an object property is called a method, so non-mehtod means that it is not used as a function in an object property. Why are arrow functions more suitable for non-methods?

Let's take a look at an example:

var obj = {
  i: 10.b: (a)=  console.log(this.i, this),
  c: function() {
    console.log( this.i, this)
  }
}
obj.b();
// undefined Window
obj.c();
// 10, Object {... }
Copy the code

Self-executing function

The form of the self-executing function is:

(function(){
    console.log(1)
})()
Copy the code

or

(function(){
    console.log(1)
}())
Copy the code

Use arrows to simplify writing self-executing functions:

((a)=  {
    console.log(1)
})()
Copy the code

Note, however, that an error will be reported using the following syntax:

((a)=  {
    console.log(1)
}())
Copy the code

Why do I get an error? Hey hey, if you know, can tell me ~

ES6 series

ES6 directory address: github.com/mqyqingfeng...

ES6 series is expected to write about 20 chapters, aiming to deepen the understanding of ES6 knowledge points, focusing on the block-level scope, tag template, arrow function, Symbol, Set, Map and Promise simulation implementation, module loading scheme, asynchronous processing and other contents.

If there is any mistake or not precise place, please be sure to give correction, thank you very much. If you like or are inspired by it, welcome star and encourage the author.

Search
About
mo4tech.com (Moment For Technology) is a global community with thousands techies from across the global hang out!Passionate technologists, be it gadget freaks, tech enthusiasts, coders, technopreneurs, or CIOs, you would find them all here.