浅谈柯里化传参以及类数组转数组的三种方法

Hokori 3月20日

何为柯里化传参

简单地说就是参数可以分次传入,等效于一次传入
比如:

console.log(sum(1)(2)())   //3
console.log(sum(1,2))      //3

明白了柯里化传参
我们来看看它的实现,
这里拿最简单的加法举例子

直接上完整代码:

let sum = function() {
    //以下三种方式都是把arguments对象转换成数组

    //在这里储存传进来的参数
    //let args = Array.prototype.slice.call(arguments)
    //let args = [].slice.call(arguments);
    let args = [...arguments];

    return (function f() {
        if (arguments.length !== 0) {
            //如果闭包函数存在参数,则把参数添加到参数组args
            args.push(...arguments);
            //递归调用
            return f
        } else {
            //如果参数为空,说明参数累加完毕,对最终args进行计算
            return args.reduce((a, b) => a + b);
        }
    })
}

至此,对柯里化传参的实现就结束了
这里的sum返回了一个闭包函数,
这个闭包函数在自身参数非空的时候会递归调用自身,并且对args添加本次递归前传入闭包的参数,
当递归到闭包参数为空时,把最终集大成的args拿去做真正的计算。

这里对args实现了三种方法的类数组转数组方法
先讲讲最简单的

  1. let args = [...arguments];

    • 这里用了ES6的扩展运算符直接展开类数组然后声明成数组
  2. let args = [].slice.call(arguments);

    • 这个涉及到slice()call()方法。
    • 可以注意的是,slice()如果参数为空,它将返回一个与原数组相同的数组,也就是copy了一遍。
    • 而这里call()传入了arguments作为this指向。
    • 最终结果就是copy了一个跟arguments相同的数组出来
  3. let args = Array.prototype.slice.call(arguments)

    • 其实是跟上面的一样的,只不过是从原型上调用的slice()方法,减少了对原型链的查找,性能更高了
icon_biggrin.pngicon_neutral.pngicon_twisted.pngicon_arrow.pngicon_eek.pngicon_smile.pngicon_sad.pngicon_cool.pngicon_evil.pngicon_mrgreen.pngicon_exclaim.pngicon_surprised.pngicon_razz.pngicon_rolleyes.pngicon_wink.pngicon_cry.pngicon_confused.pngicon_lol.pngicon_mad.pngicon_question.pngicon_idea.pngicon_redface.png
expand_less