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.
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
*/
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.