返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript函数柯里化是什么
  • 576
分享到

JavaScript函数柯里化是什么

2024-04-02 19:04:59 576人浏览 安东尼
摘要

这篇文章将为大家详细讲解有关javascript函数柯里化是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、简单了解apply和callcall 和 apply 都

这篇文章将为大家详细讲解有关javascript函数柯里化是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

一、简单了解apply和call

  • call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向。

  • call 和 apply二者的作用完全一样,只是接受参数的方式不太一样。call其实是apply的一种语法糖。

  • 格式:apply(context,[arguments]),call(context,param1,param2,...)

二、什么是函数柯里化?

柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。

在这里举个例子,有一个add()函数,它是用来处理我们传给它的参数(param1,params2,…)相加求和的一个函数。

// 在这里第一个具有两个参数`x`、`y`的`add(x , y)`函数
function add(x , y){
	return x + y;
}

// 调用`add()`函数,并给定两个参数`4`和`6`
add(4,6);

// 模拟计算机操作,第一步 传入第一个参数 4
function add(4 , y){
	return 4 + y;
}

// 模拟计算机操作,第二步 传入第一个参数 6
function add(4 , 6){
	return 4 + 6;
}

如果我们将add()函数柯里化,是什么样子呢?在这里简单的实现一下:

// 柯里化过的add()函数,可以接受部分参数
function add(x ,y){
	if (typeof y === 'undefined') {
		return function (newy){
			return x + newy;
		}
	}
	// 完整应用
	return x + y;
}

// 测试调用
console.log(typeof add(4)); // [Function]
console.log(add(4)(6)); // 10

// 可以创建保存函数
let saveAdd = add(4);
console.log(saveAdd(6)); // 10

从以上简单柯里化的add()函数可以看出,函数可以接受部分函数,然后返回一个新的函数,使其继续处理剩下的函数。

三、写一个公共的柯里化函数

在这里我们创建一个公共的柯里化函数,那样我们就不必每次写一个函数都要在其内部实现复杂的柯里化过程。

// 定义一个createCurry的函数function createCurry(fn){
	var slice = Array.prototype.slice,
	stored_args = slice.call(arguments,1);
	
	return function () {
		let new_args = slice.call(arguments),
		args = stored_args.concat(new_args);
		return fn.apply(null,args);
	}}

在以上公共的柯里化函数中:

  • arguments,并不是一个真的数组,只是一个具有length属性的对象,所以我们从Array.prototype中借用slice方法帮我们把arguments转为一个真正的数组,方便我们更好的操作。

  • 当我们第一次调用函数createCurry的时候,其中变量stored_args 是保持了除去第一个参数以外的参数,因为第一个参数是我们需要柯里化的函数。

  • 当我们执行createCurry函数中返回的函数时,变量new_args获取参数并转为数组。

  • 内部返回的函数通过闭包访问变量stored_args中存储的值和变量new_args的值合并为一个新的数组,并赋值给变量args

  • 最后调用fn.apply(null,args)方法,执行被柯里化的函数。

现在我们来测试公共的柯里化函数

// 普通函数add()
function add(x , y){
	return x + y;
}

// 柯里化得到一个新的函数
var newAdd = createCurry(add,4);
console.log(newAdd(6)); // 10


//另一种简便方式
console.log(createCurry(add,4)(6));// 10

当然这里并不局限于两个参数的柯里化,也可以多个参数:

// 多个参数的普通函数
function add(a,b,c,d){
	return a + b + c + d;
}

// 柯里化函数得到新函数,多个参数可以随意分割
console.log(createCurry(add,4,5)(5,6)); // 20

// 两步柯里化
let add_one = createCurry(add,5);
console.log(add_one(5,5,5));// 20
let add_two = createCurry(add_one,4,6);
console.log(add_two(6)); // 21

通过以上的例子,我们可以发现一个局限,那就是不管是两个参数还是多个参数,它只能分两步执行,如以下公式:

  • fn(x,y) ==> fn(x)(y);

  • fn(x,y,z,w) ==> fn(x)(y,z,w) || fn(x,y)(z,w)||…

如果我们想更灵活一点:

  • fn(x,y) ==> fn(x)(y);

  • fn(x,y,z) ==> fn(x,y)(z) || fn(x)(y)(z);

  • fn(x,y,z,w) ==> fn(x,y)(z)(w) || fn(x)(y)(z)(w) || …;

我们该怎么实现呢?

四、创建一个灵活的柯里化函数

经过以上练习,我们发现我们创建的柯里化函数存在一定局限性,我们希望函数可以分为多步执行:

// 创建一个可以多步执行的柯里化函数,当参数满足数量时就去执行它:
// 函数公式:fn(x,y,z,w) ==> fn(x)(y)(z)(w);
let createCurry = (fn,...params)=> {
	let args = parsms || [];
	let fnLen = fn.length; // 指定柯里化函数的参数长度
	
	return (...res)=> {
		// 通过作用域链获取上一次的所有参数
		let allArgs = args.slice(0);
		// 深度拷贝闭包共用的args参数,避免后续操作影响(引用类型)
		allArgs.push(...res);
		if(allArgs.length < fnLen){
		   // 当参数数量小于原函数的参数长度时,递归调用createCurry函数
		   return createCurry.call(this,fn,...allArgs);
		}else{
		  // 当参数数量满足时,触发函数执行
		  return fn.apply(this,allArgs);
		}
	}
}


// 多个参数的普通函数
function add(a,b,c,d){
	return a + b + c + d;
}

// 测试柯里化函数

let curryAdd = createCurry(add,1);
console.log(curryAdd(2)(3)(4)); // 10

以上我们已经实现了灵活的柯里化函数,但是这里我们又发现了一个问题:

  • 如果我第一次就把参数全部传入,但是它并没有返回结果,而是一个函数(function)。

  • 只有我们再次将返回的函数调用一次才能返回结果:curryAdd(add,1,2,3,4)();

  • 可能有人说如果是全部传参,就调用原来的add()函数就行了,这也是一种办法;但是我们在这里既然是满足参数数量,对于这种情况我们还是处理一下。

在这里我们只需要在返回函数前做一下判断就行了:

let createCurry = (fn,...params)=> {
	let args = parsms || [];
	let fnLen = fn.length; // 指定柯里化函数的参数长度
	
	if(length === _args.length){
	   // 加入判断,如果第一次参数数量以经足够时就直接调用函数获取结果
           return fn.apply(this,args);
        }
	return (...res)=> {
		let allArgs = args.slice(0);
		allArgs.push(...res);
		if(allArgs.length < fnLen){
		   return createCurry.call(this,fn,...allArgs);
		}else{
		  return fn.apply(this,allArgs);
		}
	}}

以上可以算是完成了一个灵活的柯里化的函数了,但是这里还不算很灵活,因为我们不能控制它什么时候执行,只要参数数量足够它就自动执行。我们希望实现一个可以控制它执行的时机该怎么办呢?

五、写一个可控制的执行时间的柯里化函数

我们这里直接说明一下函数公式:

  • fn(a,b,c) ==> fn(a)(b)(c )();

  • fn(a,b,c) ==> fn(a);fn(b);fn(c );fn();

  • 当我们参数足够时它并不会执行,只有我们再次调用一次函数它才会执行并返回结果。在这里我们在以上例子中加一个小小的条件就可以实现。

// 当参数满足,再次执行时调用函数
let createCurry = (fn,...params)=> {
	let args = parsms || [];
	let fnLen = fn.length; // 指定柯里化函数的参数长度
	
	//当然这里的判断需要注释掉,不然当它第一次参数数量足够时就直接执行结果了
	//if(length === _args.length){
	   // 加入判断,如果第一次参数数量以经足够时就直接调用函数获取结果
           //return fn.apply(this,args);
        //}
	return (...res)=> {
		let allArgs = args.slice(0);
		allArgs.push(...res);
		// 在这里判断输入的参数是否大于0,如果大于0在判断参数数量是否足够,
		// 这里不能用 && ,如果用&& 也是参数数量足够时就执行结果了。
		if(res.length > 0 || allArgs.length < fnLen){
		   return createCurry.call(this,fn,...allArgs);
		}else{
		  return fn.apply(this,allArgs);
		}
	}
}


// 多个参数的普通函数
function add(a,b,c,d){
	return a + b + c + d;
}

// 测试可控制的柯里化函数

let curryAdd = createCurry(add,1);
console.log(curryAdd(2)(3)(4)); // function
console.log(curryAdd(2)(3)(4)()); // 10
console.log(curryAdd(2)(3)()); // 当参数不足够时返回 NaN

关于“JavaScript函数柯里化是什么”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: JavaScript函数柯里化是什么

本文链接: https://lsjlt.com/news/91439.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaScript函数柯里化是什么
    这篇文章将为大家详细讲解有关JavaScript函数柯里化是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、简单了解apply和callcall 和 apply 都...
    99+
    2024-04-02
  • 什么是函数柯里化
    本篇内容介绍了“什么是函数柯里化”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!柯里化(Currying)柯...
    99+
    2024-04-02
  • JavaScript函数柯里化
    目录1 什么是函数柯里化2 柯里化的作用和特点2.1 参数复用2.2 提前返回2.3 延迟执行3 封装通用柯里化工具函数#4 总结和补充1 什么是函数柯里化 在计算机科学中,柯里化(...
    99+
    2024-04-02
  • JavaScript柯里化是什么
    这篇“JavaScript柯里化是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Jav...
    99+
    2024-04-02
  • JavaScript中函数柯里化的原理是什么
    今天就跟大家聊聊有关JavaScript中函数柯里化的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。柯里化是这样的一个转换过程,把接受多个...
    99+
    2024-04-02
  • JavaScript函数柯里化详解
    目录一、简单了解apply和call二、什么是函数柯里化?三、写一个公共的柯里化函数四、创建一个灵活的柯里化函数五、写一个可控制的执行时间的柯里化函数总结一、简单了解apply和ca...
    99+
    2024-04-02
  • 怎样用Javascript实现函数柯里化与反柯里化
    函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感;下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一...
    99+
    2024-04-02
  • js柯里化函数的好处是什么
    本篇内容介绍了“js柯里化函数的好处是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!好处说明可以把函数式编程变得简洁,没有冗余。尽管有多...
    99+
    2023-06-20
  • 如何使用Javascript实现函数柯里化与反柯里化
    这篇文章将为大家详细讲解有关如何使用Javascript实现函数柯里化与反柯里化,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。javascript是一种什么语言javascript是一种动态类型、弱类型的...
    99+
    2023-06-14
  • JavaScript 中怎么实现柯里化函数
    本篇文章为大家展示了JavaScript 中怎么实现柯里化函数,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。阶段1现在有一个加法函数:function a...
    99+
    2024-04-02
  • JavaScript函数柯里化该怎么理解
    本篇文章给大家分享的是有关JavaScript函数柯里化该怎么理解,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、简单了解apply和callcall 和 apply 都是为...
    99+
    2023-06-26
  • JavaScript如何实现函数柯里化
    这篇文章给大家分享的是有关JavaScript如何实现函数柯里化的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。函数柯里化的实现// 函数柯里化指的是一种将使用多个参数的...
    99+
    2024-04-02
  • JavaScript中的函数柯里化怎么使用
    这篇“JavaScript中的函数柯里化怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JavaScript中的函数柯...
    99+
    2023-07-06
  • Scala柯里化是什么
    这篇文章主要讲解了“Scala柯里化是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Scala柯里化是什么”吧!柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)...
    99+
    2023-06-02
  • JavaScript函数柯里化的示例分析
    这篇文章将为大家详细讲解有关JavaScript函数柯里化的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。函数柯里化使用方法:柯里化是函数式编程的一个重要技巧,将使用多个参数的一个函数转换成一系列...
    99+
    2023-06-27
  • 深入了解JavaScript中的函数柯里化
    目录一、参数复用二、延迟执行三、部分应用四、函数组合JavaScript函数柯里化是一种将接受多个参数的函数转换为一系列接受单个参数的函数的技术。这种技术可以让我们更方便地创建可复用...
    99+
    2023-05-16
    JavaScript函数柯里化 JavaScript 柯里化
  • 一文带你了解JavaScript函数柯里化
    目录一、定义二、柯里化函数的作用1、参数复用2、提前确认3、延迟执行三、柯里化函数的实现四、柯里化总结性能方面:应用场景:一、定义 柯里化(Currying)是把接受多个参数的函数变...
    99+
    2023-02-01
    JavaScript函数柯里化 JavaScript 柯里化
  • 前端JavaScript彻底弄懂函数柯里化curry
    目录一、什么是柯里化( curry)二、柯里化的用途三、如何封装柯里化工具函数 一、什么是柯里化( curry) 在数学和计算机科学中,柯里化是一种将使用多个参数的一个函数转换成一系...
    99+
    2024-04-02
  • JavaScript函数柯里化如何使用占位符
    小编给大家分享一下JavaScript函数柯里化如何使用占位符,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!函数柯里化(支持占位符)使用方法:通过占位符能让柯里化...
    99+
    2023-06-27
  • react柯里化指的是什么
    这篇文章主要介绍了react柯里化指的是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇react柯里化指的是什么文章都会有所收获,下面我们一起来看看吧。 ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作