This is the 11th day of my participation in the August More Text Challenge

The foreword 0.

Arrow functions in ES6 look like this :()=>{}

1. ES6The way we declared functions before

// Method 1: function declaration
function hello1 () {}
Method 2: function expression, also called function literal
let hello2 = function () {}
// Method 3: function construction method, parameters must be quoted
let hello3 = new Function(a)Copy the code

2. ES6Declare functions using arrow functions in

2.1 Declaration of arrow functions

// Declare a function called hello
let hello = () = > { // Note: the parentheses should not be omitted
  console.log('hello world')}// Call this function
hello() // hello world
Copy the code

The function declared above has no parameters. What if you want to pass parameters? It can be done like this:

// Declare a function called hello that takes a name argument
let hello = (name) = > {
  console.log('hello world', name)
}
hello('jjLin') // hello world jjLin
Copy the code

I passed one argument up here. What if I wanted to pass a second one? It can be written like this:

let hello = (name, city) = > {
  console.log('hello world', name, city)
}
hello('jjLin'.'shanghai') // hello world jjLin shanghai
Copy the code

And so on, want to pass 3, 4….. If there are multiple parameters, separate them by commas (,) and write them in subsequent order.

Note: without arguments, the parentheses before the arrow (=>) cannot be omitted.

2.2 Ellipsis and abbreviations of arrow function declaration

The pair of parentheses before the arrow (=>) can be omitted if and only if there is only one argument.

let hello = name= > {
  console.log('hello world', name)
}
hello('jjLin') // hello world jjLin
Copy the code

Since the curly braces can be omitted, can the following curly braces be omitted?

Yes, you can omit the return keyword and the curly braces in the method body when the body of an arrow function has only one return statement.

let sum = (x, y, z) = > x + y + z // x + y + z is an expression whose value is the return value of the function
console.log(sum(1.2.3)) / / 6
Copy the code

When returning object literals, remember that the simple syntax of params => {object: literal} won’t work.

var func = () = > { foo: 1 };               
// Calling func() returns undefined!

var func = () = > { foo: function() {}};// SyntaxError: function statement requires a name

let sum = (x, y, z) = > {
  x: x,
  y: y,
  z: z
} // Uncaught SyntaxError: Unexpected token ':'
Copy the code

This is because the code inside curly braces ({}) is parsed as a series of statements (that is, foo is treated as a tag, not part of an object literal).

So remember to enclose object literals in parentheses:

var func = () = > ({foo: 1});

let sum = (x, y, z) = > ({
  x: x,
  y: y,
  z: z
})
console.log(sum(1.2.3)) // {x: 1, y: 2, z: 3}
Copy the code

The curly braces behind the arrow in the above code are used as the curly braces of the literal object, not the body of the function.

Of course, if you don’t want to remember the shorthand in these cases, you can simply add the curly braces and return keyword of the function body.

let sum = (x, y, z) = > {
  return {
    x: x,
    y: y,
    z: z
  }
}
console.log(sum(1.2.3)) // {x: 1, y: 2, z: 3}
Copy the code

3. There is no separate arrow functionthis

Before the arrow function, each new function defined the function’s this value in terms of how it was called:

  • If the function is a constructor,thisPointer to a new object
  • In a function call in strict mode,thisPoint to theundefined
  • If the function is a method of an object, thenthisThe pointer points to this object
  • , etc.

This turns out to be a boring object-oriented style of programming.

function Person () {
  // The Person() constructor defines' this' as its own instance.
  this.age = 0

  setInterval(function growUp () {
    // In non-strict mode, growUp() defines' this' as a global object,
    // Not the same as' this' defined in the Person() constructor.
    this.age++
  }, 1000)}var p = new Person()
Copy the code

In ESMAScript 3/5, this is solved by assigning the value to a closed variable.

function Person () {
  var that = this
  that.age = 0

  setInterval(function growUp () {
    // The callback refers to the 'that' variable, whose value is the expected object.
    that.age++
  }, 1000)}Copy the code

Alternatively, you can create a binding function that passes the pre-allocated this value to the binding’s target function (the growUp() function in the above example).

The arrow function does not create its own this; it only inherits this from the upper level of its scope chain. Therefore, in the following code, the value of this in the function passed to setInterval is the same as that in the enclosing function:

function Person () {
  this.age = 0

  setInterval(() = > {
    this.age++ // This correctly points to instance p
  }, 1000)}var p = new Person()
Copy the code

Here’s an example of a common topic in a front-end interview:

let test = {
  name: 'test'.say: function () {
    console.log(this.name)
  }
}
test.say() // test
Copy the code

What is the result of asking test.say()?

That’s right, “test.” So why “test”?

When we learned about scope earlier, we concluded that when determining the direction of this, we can look at who is calling this function, so this refers to who.

In this case, say() is called by test, so this in say() is referred to as test, so this.name is test.name.

Ok, here’s the thing. Let’s change this function to the arrow function and see what happens.

let test = {
  name: 'test'.say: () = > {
    console.log(this.name, this)
  }
}
test.say() // undefined {}
Copy the code

Normal function and arrow function pairthisThe definition of pointing to is different,ES5, who is calling thisfunction, thenthisTo whom they point; whileES6Is defined in the arrow functionthisWhat does theta point to, when it’s executedthisTheta points to something.

As you can see, this in the arrow function above is an empty object. Why is this?

If we execute the above code block in the Chrome Console, we can see that this is actually the Window object.

Why is this empty?

This is because the previous code was built with WebPack, and eval (js eval, which executes strings as code) points to an empty object in the outermost scope of our code, so this points to an empty object.