最近看到这么一个题目
请写一个乘法函数multiply,满足multiply(x)(y)(z);的调用方式,并输出运算结果,如下面实例所示(注:最后一个无参数输入时代表结束);
console.log(multiply(2)(3)(4)()); // output: 24
console.log(multiply(4)(3)()); // output: 12
这一个感觉思路简单,但是实现起来会有很多细节的题目。
可以用闭包存储每一步的参数,然后参数为空的时候,返回这些参数的乘机。
也可以把每次的乘机计算出来,然后在参数为空的时候返回值。
其实直觉上我开始认为可以构造一个复合函数,类似 (x) => nfn(x), 但是这种符合函数经过两次执行后就会变得不可以再执行。根本原因应该是每次返回的fn都应该是一个function, 而 nfn(x)这种的值不可能再是一个function。
答案1:
function multiply(n) {
const nums = []
function _multiply(n) {
if (n === undefined) {
return nums.reduce((pre, value) => {
return pre * value
})
} else {
nums.push(n)
}
return _multiply
}
return _multiply(n)
}
复制代码
答案2:
function multiply(n) {
return (function _multiply(...args) {
return function(...args2) {
if (args2.length === 0) {
return args.reduce((prev, value) => {
return prev * value
})
}
return _multiply(...args, ...args2)
}
})(n)
}
复制代码
引申一下,这个题目是想做什么呢,原来这是function curry,但是因为是题目所以有点小区别。
lodash 实现的 curry
var abc = function(a, b, c) {
return [a, b, c];
};
var curried = _.curry(abc);
curried(1)(2)(3);
复制代码
有时间看看lodash源码会对各种概念有更深入的理解。
另一篇介绍function curry的文章是:
zh.javascript.info/currying-pa…
给出的答案是:
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
return func.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
}
}
};
}
function sum(a, b, c) {
return a + b + c;
}
let curriedSum = curry(sum);
alert( curriedSum(1, 2, 3) ); // 6,仍然可以被正常调用
alert( curriedSum(1)(2,3) ); // 6,对第一个参数的柯里化
alert( curriedSum(1)(2)(3) ); // 6,全柯里化
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END