若 Function 有 n 個 Argument,但實際 Data 卻為 n 個 Element 的 Array,當然可將 Array 一一拆解傳進 Function,但有更精簡寫法。
Version
macOS Mojave 10.14.5
VS Code 1.35.1
Quokka 1.0.232
ECMAScript 2015
Ramda 0.26.1
Function
let data = [1, 2, 3];
let fn = (x, y, z) => x + y + z;
fn(data[0], data[1], data[2]); // ?
fn()
為 3 個 argument 的 function,但 data
卻是 3 個 element 的 array。
當然可用 index 寫法將 element 取出傳進 function。
Function.prototype.apply()
let data = [1, 2, 3];
let fn = (x, y, z) => x + y + z;
fn.apply(null, data); // ?
ES5 提供了 Function.prototype.apply()
,因此每個 function 都可使用自帶的 apply()
傳入 array。
apply()
的第一個 argument 為傳入 object 取代 this
,因為 fn()
沒使用到 this
,因此傳入 null
即可。
Spread Operator
let data = [1, 2, 3];
let fn = (x, y, z) => x + y + z;
fn(...data); // ?
ES6 迎來了 ...
spread operator,可將 array element 展開之後,再傳入 fn()
。
Ramda
import { apply } from 'ramda';
let data = [1, 2, 3];
let fn = (x, y, z) => x + y + z;
apply(fn, data); // ?
Ramda 也提供了 apply()
,為 Array.prototype.apply()
的 FP 版本。
apply()
(*… → a) → [*] → a
將 argument function 變成以 array 為輸入的單一 argument function
(*… → a)
:原本多 argument function
[*] -> a
:回傳以 array 為單一 argument function
Conclusion
- 若以原生寫法,
...
spread operator 最精簡,且可讀性最高 - Ramda 的
apply()
適合 function composition 與 point-free
Reference
MDN, Function.prototype.apply()
MDN, Spread syntax
Ramda, apply()