函数柯里化: 提高函数的适用性, 同时降低函数的通用性; 其实现方式就是固定一些可以预期的参数, 然后返回一个特定的函数
其作用主要体现在以下三个方面:
提高函数的适用性:
把 map 改造为 tripleMap, 提高了函数的适用性, 不用每次都传递 triple 这个重复的参数; 但同时因为 tripleMap 只能用于 triple 操作, 所以降低了函数的适用性; 所以函数的柯里化要根据具体的场景使用, 不能说函数柯里化就一定好用.
- function curryAdapt(fn) {
- var outAgrs = Array.prototype.slice.call(arguments, 1)
- return function () {
- var inArgs = Array.prototype.slice.call(arguments, 0)
- return fn.apply(this, outAgrs.concat(inArgs))
- }
- }
- function triple(x) {
- return x * 3
- }
- function map(handler, arr) {
- return arr.map(handler)
- }
- map(triple, [1, 2, 3]) // [3, 6, 9]
- map(triple, [2, 4]) // [6, 12]
- var tripleMap = curryAdapt(map, triple)
- tripleMap([1, 2, 3]) // [3, 6, 9]
- tripleMap([2, 4]) // [6, 12]
让函数逻辑延迟执行:
将以下的 add 函数的逻辑, 延迟到无参数调用时再执行, 同时也起到了固定参数的作用
- function curryDelay(fn) {
- var args = []
- return function () {
- if (arguments.length === 0) {
- return fn.apply(this, args)
- } else {
- for (var i = 0; i < arguments.length; i++) {
- args.push(arguments[i])
- }
- return arguments.callee
- }
- }
- }
- function add() {
- return Array.prototype.reduce.call(arguments, function(sum, now) {
- return sum + now
- })
- }
- add(3, 4, 5) // 12
- var delayedAdd = curryDelay(add)
- delayedAdd(3)(4)(5)() // 12
固定易变的参数:
经典的应用场景就是 Function 类的 bind 函数, 下面是自己手写的一个 bind 函数, 其不仅起到了固定 this 指针指向的作用, 还可以用来提前传递一部分函数参数
- Function.prototype.myBind = function (obj) {
- var func = this
- var args = Array.prototype.slice.call(arguments, 1)
- var returnFunc = function() {
- args = args.concat(Array.prototype.slice.call(arguments))
- return func.apply(this instanceof returnFunc ? this : obj, args)
- }
- var Dump = function (){}
- Dump.prototype = func.prototype
- returnFunc.prototype = new Dump()
- return returnFunc
- }