Fork me on GitHub

JS-科里化

科里化
科里化的简单应用

科里化是将一个函数所需要的多个参数分开传入函数中,每次调用会返回一个新函数,用于处理剩余参数。
所以将一个函数科里化的过程就是收集函数参数的过程,递归搜集参数,收集完成后,在最深层计算结果并返回。

科里化通用式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function curry(fn, args) {
let length = fn.length;
let subArgs = args || [];
return function () {
let subArgs = [...arguments].slice(0);
subArgs = [...subArgs, ...args]
if (subArgs.length >= length) {
return fn.apply(this, subArgs)
} else {
return curry.call(this, fn, subArgs)
}
}
}

// es6 实现
function curry(fn, ...args) {
return fn.length <= args.length ? fn(...args) : curry.bind(null, fn, ...args);
}

应用

验证手机号码

1
2
3
function checkPhone(phoneNumber){
return /^1[34578]\d{9}$/.test(phoneNumber)
}

运用科里化

1
2
3
4
5
6
7
8
function check(reg,targetString){
return reg.test(targetString)
}

var _check = createCurry(check);

var checkPhone = _check(/^1[34578]\d{9}$/);
var checkEmail = _check(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/);

调用

1
2
checkPhone('183888888');
checkEmail('xxxxx@test.com');

扩展

  1. 函数不定参数,解决方法

    1
    2
    3
    let args=[1,2,3,4]
    add.apply(null,args)
    add(...args)
  2. 函数隐式转换
    当函数参与运算时,会默认调用 toString 方法,获取返回值,参与运算。
    默认

    1
    2
    function a(){}
    a+1 //"function a(){}1"

    重写 toString 方法

    1
    2
    3
    4
    function a(){}
    a.toString=function(){return 10}
    a+1 //11
    a+'1' //'11'
  3. 实现add函数
    实现一个 add 方法,使计算结果能够满足如下预期

    1
    2
    3
    add(1)(2)(3) = 6;
    add(1, 2, 3)(4) = 10;
    add(1)(2)(3)(4)(5) = 15;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function add(){
    let _args=[].slice.call(arguments);
    const adder=function(){
    const _adder=function(){
    _args.push(...arguments)
    }
    _adder.toString=function(){
    return _args.reduce((a,b)=>{
    return a+b
    })
    }
    return _adder
    }
    return adder(..._args)
    }

参考:
科里化

-------------本文结束感谢阅读-------------