简体   繁体   中英

About Arrow Functions in JavaScript

Confused about how arrow functions work...In this particular example:

class VillageState {
  constructor(place, parcels) {
    this.place = place;
    this.parcels = parcels;
  }

  move(destination) {
    if (!roadGraph[this.place].includes(destination)) {
      return this;
    } else {
      let parcels = this.parcels.map(p => {
        if (p.place != this.place) return p;
        return {place: destination, address: p.address};
      }).filter(p => p.place != p.address);
      return new VillageState(destination, parcels);
    }
  }
}

Particulary in,

let parcels = this.parcels.map(p => {
        if (p.place != this.place) return p;
        return {place: destination, address: p.address};})

What I can tell is that p is the argument of this arrow function but it is going to be replaced for what variable in this example? The only argument in the move method is destination but that's not going to replace p...I can't understand it.

Answer

Arrow functions don't have internal context (this) so they're super useful when you need to access the context from outside the function.

In this case you're using the arrow func inside a map and accessing the context from the class (because move is a method on VillageState it will also have access to this.place

Why is this cool? Well if you used a regular function and you tried accessing this.place you would get a ReferenceError because there is no place variable defined on the local this.

// dont do this at home
function mapFn(p) {
   /* This here is inside the mapFn and since this.place is not defined 
      we get a ReferenceError */
   if (p.place != this.place) return p;
   return {place: destination, address: p.address};
}

let parcels = this.parcels.map(mapFn)
/* Hopefully the syntax above isn't confussing: 
   * mapFn will be called by default with all the map() parameters
   * inside mapFn we only need p so that's the only name param used
*/

Resources

To learn more about arrow functions I'd check out Impatient JS, it's a really in depth explanation so it should answer most of your questions. The whole 'callable values' chapter is super useful. Also MDN.

https://exploringjs.com/impatient-js/ch_callables.html#arrow-functions

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

What I can tell is that p is the argument of this arrow function but it is going to be replaced for what variable in this example?

It won't be replaced by any variable. The map function calls its callback once for each entry in the array. Each time it calls the callback (the arrow function), it passes in the entry's value. That's what the arrow function receives in its p parameter.

So for instance, suppose this.parcels looked like this:

this.parcels = [
    {
        place: "a",
        description: "parcel a"
    },
    {
        place: "b",
        description: "parcel b"
    },
    {
        place: "c",
        description: "parcel c"
    }
];

With those parcels , map would call the arrow function three times. p in the first call would refer to the { place: "a", description: "parcel a" } object. p in the second call would refer to the { place: "b", description: "parcel b" } object, and p in the third call would refer to the { place: "c", description: "parcel c" } object.

The only thing different about the arrow function vs. a traditional function in that example is that it closes over this (and arguments and super ) — something that you want in that code, because it uses this to refer to the object holding parcels .

This code that you pointed to:

let parcels = this.parcels.map(p => {
    if (p.place != this.place) return p;
    return {place: destination, address: p.address};
})

...does the same thing this code using a traditional function does:

let _tmp = this; // *** Remember the value `this` has outside the function
let parcels = this.parcels.map(function(p) => {
    if (p.place != _tmp.place) return p;
//                 ^^^^−−−−−−−−−−−−−−−−−−−−−−−−−− use that value here
    return {place: destination, address: p.address};
})

It seems like you're trying to make sense of the higher-order functions in JS with fairly complex example.

First, what does the map method do? It iterates over an array and calls the provided callback function right?!

 [1, 2, 3].map(n => n + 1); // [2, 3, 4] // Which is equalent to this: [1, 2, 3].map(function(n) { return n + 1 }) // or this... function increment(n) { return n + 1 }; [1, 2, 3].map(n => increment(n));

Or for a better explanation, I would just suggest watching this video to get a clearer understanding of array methods and higher-order functions in JS: JavaScript Higher Order Functions & Arrays !

And after it would be much easier for you to reason about your concrete example :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM