知乎秀我一脸,这必须是考察柯里化

作者 Kylewh 日期 2017-03-14
知乎秀我一脸,这必须是考察柯里化

库里: ???

首先上链接,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) ); //6

但是…这不够装bi…这也不够震慑面试官,万一面试官反怼: 如果我要支持无限次传入参数而且可以分批传入呢?

稳住!我们能赢!

所以….还是必须得借助toString或者valueOf进行隐式转化!看个小sample:

var fn = function (){
console.log('fn被调用了');
return fn; //如果没有这行,默认返回undefined
}
//如果没有这个方法,则返回自己身上的toString的调用结果,如果连toString都没有,只能调用原型身上的了...
fn.valueOf = function(){
return 'valueOf:我被调用了';
}
fn.toString = function(){
return 'toString:我被调用了';
}
console.log( fn() ) ; //valueOf:我被调用了
  • 也就是说,在函数返回值时,如果返回的是一个函数,使用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.

这两天在看书,马上会继续整理基础知识,基础最重要!