实现一个函数add(1)(2)(3),add(1,2,3),add(1,2)(3)

517 阅读1分钟

解法:

    function curryingCheck() {
      // 第一次执行时,定义一个数组专门用来存储所有的参数
      let _args = Array.prototype.slice.call(arguments);
      // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
      let _adder = function () {
        _args.push(...arguments);
        return _adder;
      };

      _adder.toString = function () {
        return _args.reduce(function (a, b) {
          return a + b;
        });
      }

      return _adder;
    }

    console.log(curryingCheck(1, 2)(3, 4)(5));

难点:

这里单对以下代码进行一些解释

   _adder.toString = function () {
        return _args.reduce(function (a, b) {
          return a + b;
        });
      }

1、正常情况下我们执行一个函数的toString,例如_adder.toString,其实都是调用的Function.prototype.toString,函数自身没有toString。

2、当我们直接打印_adder时,是无法读取函数的源码的,都是通过Function.prototype.toString来读取的。

3、当我们在_adder上挂载toString后,就不会去查找Function.prototype.toString,而是直接执行_adder.toString函数。具体可以查看js的原型链。


Array.prototype.slice.call(arguments))能将具有length属性的对象(key值为数字)转成数组。
[]是Array的示例,所以可以直接使用[].slice()方法
[].slice.call(arguments);

arguments类似数组,存在length属性,但是没有slice属性,所以通过call改变slice的执行对象,
从而将arguments转换成数组。