Open MrErHu opened 7 years ago
// 这样呢
function plus() {
var _args = [].slice.call(arguments);
var _adder = function () {
[].push.apply(_args, [].slice.call(arguments));
return _adder;
};
_adder.toString = function () {
return _args.reduce(function (a, b) {
return a + b;
});
}
return _adder;
}
console.log(plus(1)(2)(3).toString())
@zdddrszj 当然可以啊,答案不唯一,尽情发挥
function plus(num) {
return (() => {
let args = [] // 存储参数
let addArg = function() {
args.push(arguments[0] || 0)
return addArg
}
addArg.toString = ()=>args.reduce((a,b)=>a+b)
return addArg
})()(num)
}
这里直接使用argument[0]应该没问题吧,不过这里可能需要判断参数为空的情况。
@MrErHu 虽然过了测试,但感觉有问题的
var p1 = plus(1);
console.log(p1(1).toString()); //2
console.log(p1(1).toString()); //3
欢迎大家再一次来到我的文章专栏:从面试题中我们能学到什么,各位同行小伙伴是否已经开始了悠闲的春节假期呢?在这里提前祝大家鸡年大吉吧~哈哈,之前有人说,学面试题不会有什么长进,其实我觉得这个就像是我们英语考试中的阅读理解,带着问题去看文章反而更有利于自己的学习。 之前的两篇文章:
都在稀土掘金和Segmentfault都获得了非常多的点击量,没有看的小伙伴们可以点击了解一下,今天为大家带来一道关于闭包和函数的柯里化方面的编程题目,各位小伙伴有没有开始跃跃欲试呢? 编程题目的要求如下,完成
plus
函数,通过全部的测试用例。测试用例如下
实话说刚开始拿到这道题的时候我并没有完全的做出来,但是具体的思路是有的,肯定是关于函数的柯里化(Currying)方面的,应该是想考察一下面试者的闭包理解能力. 那么首先介绍一下什么是函数的柯里化(Currying)。《JavaScript忍者秘籍》一书中,对于柯里化的定义如下:
维基百科中关于其定义如下:
首先我们举个例子来具体的解释一下以上的概念。 例如一个最简单的加法函数:
如果采用柯里化是怎样将接受两个参数的函数变成接受单一参数的函数呢,其实很简单如下:
这样理解起来其实是不是就很简单了,其实实质利用的就是闭包的概念(大家可以在我的另一篇文章浅谈JavaScript闭包看一下)。本质上讲柯里化(Currying)只是一个理论模型,柯里化所要表达是:如果你固定某些参数,你将得到接受余下参数的一个函数,所以对于有两个变量的函数
y^x
,如果固定了y=2
,则得到有一个变量的函数2^x
。这就是求值策略中的部分求值策略。 柯里化(Currying)具有:延迟计算、参数复用、动态生成函数的作用。例如如果我们需要创建一个通用的DOM事件绑定函数,不使用柯里化的写法如下(该示例来自于博客园Tong Zeng):但是在使用了柯里化(Currying)的情况下,不再需要每次添加事件处理都要执行一遍
if...else...
判断,只需要在浏览器中判定一次就可以了,把根据一次判定之后的结果动态生成新的函数,以后就不必重新计算。其实在实际使用中使用最多的一个柯里化的例子就是Function.prototype.bind()
函数,我们也一并给出一个较为简单的Function.prototype.bind()
函数的实现方式。回到我们的题目本身,其实根据测试用例我们可以发现,
plus
函数的要求就是接受单一函数,例如:但是与柯里化不同之处在于,柯里化返回的一个新函数。我们观察其实最后的求值是通过
toString
函数得到的,那么我们就很容易想到,我们可以给返回的函数增加一个toString
属性就可以了。我自己写出的答案如下:运行一下,通过全部的测试用例,需要注意的是由于题目的要求运行在严格模式下,所以我们在
_adder
函数内部是不能引用arguments.callee
,这时我们采用的方法是给函数表达式中函数本身起名_adder
,这样就解决的这个问题。 再次感谢大家阅读本篇文章,希望大家能从中或多或少学到一些东西,入行资历甚浅,不足之处请多指教