解法:
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转换成数组。