add(1)(2)(3)(4)


可以实现任意数量数字相加,但是需要用+号隐式转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function fn() {
let result = [];
function add(...args) {
    // ...args剩余参数,可以获取到传进来的参数
    result = [...result, ...args]
    return add;
  };
  // 创建一个取代 valueOf 方法的函数,覆盖自定义对象的 valueOf 方法
  add.toString = () => result.reduce((sum, k) => sum + k, 0);
  return add;
};
let add = fn()
  console.log(+add(1)(2)(3)(4)) // --->10
   // let add2 = fn();
   console.log(+add2(1, 2, 3)(4)) // --->10

参数固定的情况下,不需要用+号,可以根据参数长度来判断返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
   function currying(fn, length) {
     length = length || fn.length; // 第一次调用,给length赋值fn的长度,后面每次重复调用,length的长度都会减去参数的长度
     return function (...args) {
       return args.length >= length // 当前传递进来的参数的长度与length长度进行比较
         ? fn.apply(this, args) // 把最后一组实参传给为赋值的形参,此时所有形参都已赋值,并调用fn函数
        : currying(fn.bind(this, ...args), length - args.length)
       // 每一次调用fn.bind,都会把当前的args里的实参依次传给fn的形参,length的长度减去参数的长度
       // 相当于fn.bind(this, 1).bind(this, 2, 3),bind的连续调用,来填充fn的参数
       // 直到某一次调用,fn的形参即将全部都被赋值时,条件成立,会执行fn.apply,把最后的参数传递过去,并且调用fn
    }
  }
   function fn(a, b, c, d) {
     return a + b + c + d
  }
   const add = currying(fn)
   add(4)(3)(1)(2) //10
   add(1, 3)(4)(2) //10
   add(1)(3, 4, 2) //10