1. 一道实现函数柯里化的面试题
题目
// 实现一个函数add, 满足以下两种调用方式,其结果都为6:
add(1, 2, 3)
add(1)(2)(3)
解法
function add() {
var args = [...arguments] // push第一次调用add函数的参数
var temp = function() {
// 将每一次调用时的参数都push进 args 变量中
args.push(...arguments)
// 返回temp函数自身,即第二次调用add函数以及之后的每一次调用都是在调用temp函数
return temp
}
temp.toString = function() {
// 由于调用无论调用add函数多少次最终都是返回temp函数本身,最终的temp函数并未执行,
当在console中打印该temp函数时,函数会隐式转换调用toString()方法,因此可以改写temp函数的toString()方法,将args数组累加返回
return args.reduce((acc, x) => acc += x, 0)
}
return temp // 第一次调用add函数时返回temp函数
}
2. 柯里化实现 Function.prototype.bind() 函数
函数柯里化是指传入部分参数给一个函数,并返回一个新函数的一个过程。Javascript 的 Function.prototype.bind() 函数的概念在MDN中的解释为:
bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。
bind()函数可以显示绑定函数的this值,并返回一个新的函数,可以借助柯里化和显示绑定函数this值的apply()函数来实现。
Function.prototype._bind = function () {
var fn = this // 原函数自身
var context = [].shift.call(arguments) // 需要绑定的this上下文,即为arguments里的第一个参数
var args = [].slice.call(arguments) // 剩余的参数转为数组
return function () {
// 绑定this值,并将调用_bind()函数是传入的参数和调用新函数时传入的参数合并
return fn.apply(context, args.concat([].slice.call(arguments)))
}
}
console 中验证该函数:
