Thunk 实现多参数函数转单参数函数

292 阅读1分钟

选自·阮一峰·大神书籍 ECMAScript 6 入门

1. Background背景

1.1 函数传参的求值策略 Params Transfer Strategies:

1.1.1 Call by value 传值调用

1.1.2 Call by name 传名调用

function capitalize(fullname) {
    let reg = /\b\w+\b/g;
    return fullname.replace(reg, word => word.substring(0,1).toUpperCase() + word.substring(1).toLowerCase());
}

let first = "mark",
    middle = "elliot",
    last = "zuckerberg";
    
capitalize(`${first} ${middle} ${last}`);
// "Mark Elliot Zuckerberg"

/* 传值调用 模式下 */
capitalize("mark elliot zuckerberg");

/* 传名调用 模式下 */
capitalize(`${first} ${middle} ${last}`);
// 只有运行时才会计算

二者比较:传值 ? or 传名 ?

传值调用比较简单,但是对参数求值的时候,实际上还没用到这个参数,有可能造成性能损失。(阮一峰 书籍)

let x = 10;
function f(a, b){
  return b;
}

f(3 * x * x - 2 * x - 1, x);
// 第一个参数在函数体内,并未被使用,在传值调用时,则计算时会消耗性能。

2. Thunk Explanation含义

2.1 编译器:thunk函数替代的是表达式

let first = "mark",
    middle = "elliot",
    last = "zuckerberg";
    
function thunk () {
    return `${first} ${middle} ${last}`;
}

function capitalize(thunk) {
    let reg = /\b\w+\b/g;
    return thunk().replace(reg, word => word.substring(0,1).toUpperCase() + word.substring(1).toLowerCase());
}
capitalize(thunk);
// "Mark Elliot Zuckerberg"

2.2 JavaScript语言:thunk替换多参数函数 => 单参数函数

几乎所有参数有callback的函数,都能转为thunk单参数函数

const Thunk = fn => (...args) => callback => fn.call(this, ...args, callback);

function fn(a, b, callback) {
  console.log(`Receive params: ${a} ${b}`);
  callback(a, b);
  return 'done';
}

function add(a, b) {
  console.log(a + b);
}

Thunk(fn)(1,2)(add);
// Receive params: 1 2
// 3
// done