柯理化函数思想 add(1) =>> 1 add(1) (2,3) =>> 6 add(1) (2,3)(4,5,6) =>> 21

941 阅读1分钟

柯理化函数思想

实现:

add(1) =>> 1

add(1) (2,3) =>> 6

add(1) (2,3)(4,5,6) =>> 21

方法一:

function currying(add) {
	return function(...args) {
		if (args.length == 0) {
			return add(...args)
		}
		return currying(add.bind(null, ...args))
	}
}

function add(...args) {
	return args.reduce((total, num) => {
		return total + num
	})
}

add = currying(add)
console.log( add(1)() ) //1
console.log( add(1)(2,3)() ) //6
console.log( add(1)(2, 2, 2, 9, 0, 78, 89)(7, 8, 5)(110, 88)(99)() )  //500

方法二:

重写toString()方法

function add(...args) {
	function fn(...fn_args) {
		return add.bind(null, ...[...args, ...fn_args])() //或
		// return add.call(null, ...[...args, ...fn_args]) //或
		// return add.apply(null, [...args, ...fn_args]) //或
	}
	fn.toString = function() {
		return args.reduce((total, num) => total + num)
	}
	return fn
}

console.log( add(1)  ) //1
console.log( add(1)(2,3)  ) //6
console.log( add(1)(2,3)(4,5,6)  ) //21

结果:

我觉得这道题核心要知道 bind 有累加参数的作用 且 bind 是返回一个函数不执行,不像 call 和 apply 会直接执行 reduce 只是实现求一个数组的和,这里求数组的和 我刚发现一个新方法也还是有点意思的,之前也没想到

let arr = [1, 2, 3, 4, 5]
let res = eval( arr.join("+") )
console.log(res) //15

是不是感觉豁然开朗,之前竟然没想到这么用