我看函数式编程的时候看到这样一个题:
如何实现一个函数add使得:add(1)(4,5,6)(7,8)(10) 输出 41 ?
我看通常的解法是这样
function add(...args) {
function inner(...otherArgs) {
args = [...args, ...otherArgs];
return inner;
}
inner.toString = () => {
return args.reduce((acc, cur) => acc + cur, 0);
};
return inner;
}
let res = add(1)(4, 5, 6)(7, 8)(10);
alert(res)
但是事实上, 这是有问题的
alert实际上默认调用了toString方法, 而实际开发中更常用的console.log则不会调用toString, 使用console.log(res)打印出来的结果会有问题
请问有没有什么方法能够完美解决这个问题呢?
控制台 API 不是在任何规范中定义的标准 API,而是取决于具体浏览器的实现。
换而言之,你用
console.log
的结果就已经是不可预知的了。对应到 C/C++ 里的话,这就属于一个未定义行为。任何依赖未定义行为的解法反倒是不对的。本题是为了考察函数柯里化的基本知识,已经如何覆写
toString
而已,跟你用什么浏览器并无关系。甚至于说,如果你的运行环境压根也不在浏览器里、压根就没有console.log
方法、也不影响你作答。P.S. 事实上,早期版本的 Chrome 即便你用
console.log
,也确实是能输出 toString() 结果的;某个版本之后才开始原样打印 function 内部定义了 ———— 本来这也不是标准 API,Chrome 想怎么改就怎么改,说不定它们哪天又改回输出 toString() 了。