JavaScript函数柯里化及简单题目

本文详细介绍了JavaScript函数柯里化的概念与原理,并通过实例展示了如何使用柯里化简化DOM回调和创建add函数的柯里版本。通过柯里化,我们可以创建动态函数,方便多次传参。最后提供了一个实现题目,教你如何利用柯里化创建满足特定条件的加法操作。
摘要由CSDN通过智能技术生成

JavaScript函数柯里化及简单题目


1. 函数柯里化

柯里化是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回一个新函数,这个新函数能够接受原函数的参数。下面可以通过例子来帮助理解。

// 简单的柯里化
function adder(num) {
	return function(x) {
		return num + x;
	}
}
var add5 = adder(5);
var add6 = adder(6);
console.log(add5(1)); // 6
console.log(add6(1)); // 7

柯里化在DOM的回调中非常有用。因为柯里化可以将分别多次传入的参数储存起来最后做同一处理。

通俗点说柯里化就是利用已有的函数, 再创建一个动态的函数,该动态函数内部还是通过已有的函数来发生作用,只是传入更多的参数来简化函数的参数方面的调用。

function curry(fn) {
	var args = [].slice.call(arguments, 1);
	return function() {
		return fn.apply(null, args.concat([].slice.call(arguments, 0)));
	}
}
function add(numl, num2} {
	return numl + num2;
}

var newAdd = curry(add, 5);
alert (newAdd (6)); / /11

在curry 函数的内部,私有变量args 相当千一个存储器,用来暂时存储在调用curry 函数时所传递的参数值,这样再跟后面动态创建函数调用时的参数合并并执行,就会得到一样的效果。

函数柯里化的基本方法和函数绑定是一样的:使用一个闭包返回一个函数。两者的区别在于,当函数被调用时,返回函数还需要设置一些传入的参数。

// 返回一个新函数,参数已提前内定
function bind(fn, context) {
	var args = Array.prototype.slice.call(arguments, 2);
	return function() {
		var innerArgs = Array.prototype.slice.call(arguments);
		var finalArgs = args.concat(innerArgs);
		return fn.apply(context, finalArgs);
	}
}
// 在Function.prototype就操存在有bind方法,函数可以直接调用,
// 语法:function.bind(thisArg[, arg1[, arg2[, ...]]]),与上述bind方法作用类似

创建柯里化函数的通用方式是:

function curry(fn) {
	var args = Array.prototype.slice.call(argurnents, 1);
	return function() {
		var innerArgs = Array.prototype.slice.call(argurnents);
		var finalArgs = args.concat(innerArgs);
		retrun fn.apply(null, finalArgs);
	}
}

curry 函数的主要功能就是将被返回的函数的参数进行排序。为了获取第一个参数后的所有参数,在arguments 对象上调用slice()方法,并传入参数1 表示被返回的数组的第一个元素应该是第二个参数。

2. 利用函数柯里化的简单题目

  • 实现一个函数add,使得add(3)(4)(5)() = 12,add(3)(4, 5)(6)() = 18

  • 代码实现:

    add.args = null // 静态变量args
    
    function add() {
    	// 第一次都没有传参数,直接结束
      if(arguments.length === 0) return null
    	// 将第一次传入的参数保存起来
      add.args = Array.from(arguments)
      
      	// 返回一个函数
      return function() {
        if (arguments.length === 0) {
        	// 调用时没有再传参数了,将之前收集的参数统一处理,返回结果
          const result = add.args.reduce((a, b) => {
            return a + b
          })
          return result
        } else {
        	// 调用时继续传入参数,将参数保存到静态变量中,返回本身函数准备接受下一次调用
          add.args = [...add.args, ...Array.from(arguments)]
          return arguments.callee
        }
      }
    }
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值