簡體   English   中英

在函數數組上執行Javascript'reduce'如何實現函數組合?

[英]How Javascript `reduce` performed on function array achieves function composition?

我在redux compose功能中遇到了這種模式。 我仍然不明白如何在下面的示例中從最后開始而不是從第一個開始評估函數:

function f2(a) {
  return a + a;
}
function f3(a) {
  return a + a + a;
}
function f4(a) {
  return a + a + a + a;
}
function f5(a) {
  return a + a + a + a + a;
}

function compose(...funcs) {
  return funcs.reduce(function x(a, b) {
    return function y(...args) {
      const temp = a(b(...args));
      return temp;
    };
  });
}

const composedFunction = compose(f2, f3, f4, f5);
const result = composedFunction(2);

在第一個reduce迭代中,累加器為f2因此我們得到f2(f3(2))=12 在下一次迭代中,我們將調用f4(12)=48 在上一次迭代中,我們將調用f5(48)=240 因此,評估順序為f5(f4(f2(f3(2)))) 但是使用console.log我看到評估順序是f2(f3(f4(f5(2)))) ,巧合的也是240。

據我了解,函數y是為所有數組元素調用的,那么為什么只有最后一個函數將2作為參數?

讓我們通過一個非常簡單的示例逐步完成代碼:

 compose(f2, f3, f4)

由於沒有傳遞任何初始值來減少值,因此它將以數組的第一個(f2)和第二個(f3)值開頭,並以該值調用回調, x的調用為af2bf3 現在x不執行任何操作,只返回可以通過閉包訪問a和b的函數y

Reduce現在將繼續到第三個元素,第一個參數是上一個回調(閉包y )的結果,第二個參數是f4 現在再次調用x ,並在y上創建另一個閉包, y從整個函數中最終返回。

如果我們嘗試可視化這樣的閉包函數,它將是:

 y { // closure of y
  a -> y { // a references another closure of y
    a -> f3,
    b -> f2
  },
  b -> f4
}

現在,您調用該閉包y並將2傳遞給它,這將調用bf4 )並將結果傳遞給該調用到a (閉包y)。

 a         (  b(...args))   
 y { ... } (  f4(2) )

現在,封閉的y將執行相同的操作:

 a (  b ( ...args))
 f2( f3( f4( 2 ) ) )

提示:有時很難跟蹤閉包的值,因此控制台為您提供了強大的實用程序來跟蹤它們:在控制台的“ debugger”選項卡中打開代碼,單擊函數調用所在的行號。附加斷點,然后再次運行代碼,只要到達斷點,執行就會產生,您可以看到所有變量(包括封閉變量)的值。

reduce不會調用函數f2,f3,f3,f5,而是從這些函數創建函數。 這是每次迭代中累加器的值。 請注意,該值是一個function而不是function執行的結果。

1:a = f2; b = f3;返回值(不是溫度,但函數y)= f2(f3(... args))

2:a(上一個返回值)= f2(f3(... args)); b = f4;返回值= f2(f3(f4(... args))))

等等....

撰寫功能可以重寫為:

function compose(...funcs) {
  return funcs.reduce(function (a, b) {
    return function (arg) {
      const temp = a(b(arg));
      return temp;
    };
  });
}

第一次迭代后,作為下一個累加器傳遞的返回函數為:

function (arg) {       // R1
  return f2(f3(arg));

}

在第二次迭代之后,作為下一個累加器傳遞的返回函數為:

function (arg) {       // R2
  return R1(f4(arg));

}

最后,分配給compositionFunction的返回函數為:

function (arg) {       // composedFunction
  return R2(f5(arg));

}

因此,運行composedFunction(2)並返回上鏈:

f5(2) returns 10

R2(10) returns R1(f4(10))
which is       R1(40)

R1(40) returns f2(f3(40))
which is   f2(120)
which is   240

希望這足夠了。

可以將其寫為以下單個調用:

function composedFunction(arg) {
  return f2(f3(f4(f5(arg))));
}

暫無
暫無

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

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