簡體   English   中英

關於 JavaScript 中的箭頭函數

[英]About Arrow Functions in JavaScript

對箭頭函數的工作方式感到困惑……在這個特定的例子中:

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);
    }
  }
}

特別是在,

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

我能說的是 p 是這個箭頭函數的參數,但是在這個例子中它將被什么變量替換? move 方法中唯一的參數是目的地,但這不會取代 p...我無法理解。

回答

箭頭函數沒有內部上下文 (this),因此當您需要從函數外部訪問上下文時,它們非常有用。

在這種情況下,您在地圖中使用箭頭 func 並從類訪問上下文(因為 move 是 VillageState 上的一個方法,它也可以訪問this.place

為什么這很酷? 好吧,如果您使用常規函數並嘗試訪問this.place您會得到一個 ReferenceError,因為在本地 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
*/

資源

要了解有關箭頭函數的更多信息,我會查看 Impatient JS,這是一個非常深入的解釋,因此它應該可以回答您的大部分問題。 整個“可調用值”一章都非常有用。 還有MDN。

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

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

我能說的是 p 是這個箭頭函數的參數,但是在這個例子中它將被什么變量替換?

它不會被任何變量替換。 map函數為數組中的每個條目調用一次回調。 每次調用回調(箭頭函數)時,它都會傳入條目的值。 這就是箭頭函數在其p參數中接收的內容。

例如,假設this.parcels看起來像這樣:

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

對於這些parcelsmap將調用箭頭函數三次。 p一次調用中的p將引用{ place: "a", description: "parcel a" }對象。 第二次調用中的p指的是{ place: "b", description: "parcel b" }對象,第三次調用中的p指的是{ place: "c", description: "parcel c" }對象.

arrow函數與該示例中的傳統函數的唯一不同之處在於它關閉了this (以及argumentssuper )——您在該代碼中想要的東西,因為它使用this來引用持有parcels的對象。

您指向的這段代碼:

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

...使用傳統函數執行此代碼所做的相同操作:

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};
})

似乎您正試圖通過相當復雜的示例來理解 JS 中的高階函數。

首先,map方法是做什么的? 它遍歷一個數組並調用提供的回調函數,對嗎?!

 [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));

或者為了更好的解釋,我建議觀看此視頻以更清晰地了解 JS 中的數組方法和高階函數: JavaScript 高階函數和數組

之后你會更容易推理你的具體例子:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM