库里: ???
首先上链接,Web前端面试题,求解答?;
问题描述
4.写一个mul函数调用时将生成以下输出: console.log(mul(2)(3)(4)); // output : 24 console.log(mul(4)(3)(4)); // output : 48 */
|
里面真是群神乱舞,排名第一答案使用的valueOf
&const
当初真是把我看哭了,我几乎是跪着看完他的答案。
但是今天转头回去再一看,wait wait wait, what’s this.. hold on big brother.. r u sure? r u kidding me?,总之我很凌乱,直觉告诉我:不!考官绝对不是特么让你写什么const
! 摆明就是要考你柯里化(curry)好么!?
我的解法
题主应该没有把要求说完整,预定义函数很有可能是固定参数的:
function curryIt(fn) { var len = fn.length, args = []; return function () { args.push([].shift.call(arguments)); if (args.length < len) { return arguments.callee; } else { return fn.apply(null, args); } } } var fn = (x,y,z) => x*y*z; var mul = curryIt(fn); console.log( mul(1)(2)(3) );
|
但是…这不够装bi…这也不够震慑面试官,万一面试官反怼: 如果我要支持无限次传入参数而且可以分批传入呢?
稳住!我们能赢!
所以….还是必须得借助toString或者valueOf进行隐式转化!看个小sample:
var fn = function (){ console.log('fn被调用了'); return fn; } fn.valueOf = function(){ return 'valueOf:我被调用了'; } fn.toString = function(){ return 'toString:我被调用了'; } console.log( fn() ) ;
|
- 也就是说,在函数返回值时,如果返回的是一个函数,使用console.log进行输出时会默认调用函数原型身上的toString(Object)
- 调用valueOf还是toString取决于函数将倾向被转化成哪种形式,比如使用+号来进行计算,左侧如果是字符串,那么+号后跟函数,则会尝试将函数转化为数字,此时自然调用valueOf方法。 如果+号前是字符串,那么函数将会转化为字符串,自然便调用toString方法了。
我们来看下这道题的解法:
function mul() { var allArgs = [].slice.call(arguments); var runner = function () { var _argsCollector = function () { allArgs = [].concat.call(allArgs, [].slice.call(arguments)); return _argsCollector; }; _argsCollector.valueOf = function () { return allArgs.reduce(function (a, b) { return a * b; },1) }; return _argsCollector; } return runner.apply(null, allArgs); } console.log(mul(1)); console.log(mul(1)(2)); console.log(mul(1)(2)(3)(4)); console.log(mul(1,2,3,4)); console.log(mul(1,2,3)(4)); console.log(mul(1)(2)(3,4));
|
优化一下,我们可以把需要的求值函数传入其中,也就是valueOf里的reduce方法,可以改成各种你想要的效果,可见reduce和curry结合后的强大。(本身两者就挺强大的了…)
恩…现在回想一下,当初必然是盲目崇拜了… 看到如此惊天地泣鬼神的答案,要是面试当场写出这解法,面试官也得虎躯一震问问预期薪水如何了吧23333.
这两天在看书,马上会继续整理基础知识,基础最重要!