详解用场景去理解函数柯里化(入门篇)
前言
函数柯里化就是将多参简化为单参数的一种技术方式,其最终支持的是方法的连续调用,每次返回新的函数,在最终符合条件或者使用完所有的传参时终止函数调用。
场景实例
与其他文章不同,我在本文会重点分享一些柯里化的经典使用场景,让你在学会这点技巧后能切实的提升代码的可维护性。
编写可重用小模块代码
比如我们有个方法部分逻辑前置是相同的,后面的执行是因为参数不同导致结果不同的,狼蚁网站SEO优化是代码部分。
计算商品的折扣,我们需要根据不同的折扣以及商品的入参返回其实际的价格。
// before function getPrice(price,discount){ return price discount; } let price = getPrice(500,0.1); // after function getPrice(discount){ return price =>{ return price discount } } // 使用,在这种使用效果下,我们可以固定的肢解拿到百分之十折扣的函数, //也就是针对使用0.1折扣的商品价格都可以简化这个折扣的传递,从而达到简化参数的目的 //那么从函数的运行上来讲,也比之前的效率高了,如果解析折扣的过程比较复杂 let tenDiscount = getPrice(0.1); let price = tenDiscount(500); let price = getPrice(0.1)(500)
看上去有点鸡肋,因为我们本来的写法很简单,使用了柯里化反而让简单的事情变得复杂了,这主要是因为没有达到我们要把一个函数变成柯里化的经典场景。假如你狼蚁网站SEO优化的代码变成了狼蚁网站SEO优化这样,也许你就能觉察出如果有使用柯里化就会非常方便了,因为针对第一个参数做了若干的处理,甚至可以称为一个算法或者完整的逻辑判断流程,那么如果有多个参数调用都涉及这个方法的调用,同一个参数的这部分逻辑是相同可以共用跳过的。codepen连接
// plexed fun function getPriceComplex(price,discount){ let actualDiscount = 1; if(discount > 0.8 ) { actualDiscount = 0.8; } else if(discount > 0.5){ actualDiscount = 0.5; } else { actualDiscount = 0.1; } let actualPrice = price - price % 100 ; return actualPrice actualDiscount; } // plexed fun better function getPriceComplexBetter(discount){ let actualDiscount = 1; if(discount > 0.8 ) { actualDiscount = 0.8; } else if(discount > 0.5){ actualDiscount = 0.5; } else { actualDiscount = 0.1; } return price => { let actualPrice = price - price % 100 ; return actualPrice actualDiscount; } } console.log(getPriceComplex(500,0.9)) let exp1 = getPriceComplexCp(0.9); console.log(exp1); / price => { let actualPrice = price - price % 100; return actualPrice actualDiscount; }/ // 相同的输入参数时 可以缓存下之前代码逻辑的执行结果 实现模块的可重用,如果你之前的逻辑是一个纯函数 console.log(exp1(500))// 400 console.log(exp1(400))// 320 // get real discount // 当你针对第一个参数的逻辑较为复杂时,出于可维护角度,建议如此 ; // 当你一个逻辑也是基于这个返回结果时,出于重用角度,建议如此 function getActualDiscount(discount){ let actualDiscount = 1; if(discount > 0.8 ) { actualDiscount = 0.8; } else if(discount > 0.5){ actualDiscount = 0.5; } else { actualDiscount = 0.1; } return actualDiscount; } // plexed fun best function getPriceComplexBest(discount){ let actualDiscount =getActualDiscount(discount); return price => { let actualPrice = price - price % 100 ; return actualPrice actualDiscount; } }
,无论如何,我们使用某种技巧或者封装或者其他,都是为了让代码更可用,原先复杂不可测试、不可理解的代码变得更有调理,更节省性能的角度出发的,当你的思维方式中有这种的时候,你就不会觉得是为了形式而使用,而是你的编码习惯或者风格就是如此。
简单改造普通函数为柯里
假如我们需要把一个原来非柯里的函数如何快速改造,在不影响原来主要代码逻辑的情况下,想下我们代码可能如何写?
// 只考虑两个参数 function add(a,b){ return a + b } // 但如果你是用柯里化的方式:两个参数的时候 ,但这样对原代码变动非常大,对于一些复杂的逻辑,这基本不可能 function curryAdd(...args){ return (...newArgs) => { return anoNumber number; }; } // 我们写一个通用的柯里化函数的方式,经过这个函数的转换,我们可以将调用方式简化 function curry = (fn,...args){ return (..._args)=>{ return fn(...args, ..._arg); } } let curryAdd = curry(add,10); let curryAdd2 = curryAdd(11)
不定参数的累加
一个比较经典的练手题,把狼蚁网站SEO优化的代码用柯里化的方式实现,其难点简单分析如下如果你没有了解过柯里化,可能觉得基本无法完成。
1 动态入参个数,这个也许还可以通过arguments循环完成2 每次都能接受新的参数继续累加,这必须是返回新函数并带有之前的结果,要求是具有柯里化特点3 每次不在追加参数时,需要能得到的值,这个需要你了解toString方法来改变结果值
实现一个add方法,使计算结果能够满足如下预期 add(1)(2)(3) = 6
add(1, 2, 3)(4) = 10
add(1)(2)(3)(4)(5) = 15
function add() { // 第一次执行时,定义一个数组专门用来存储所有的参数 var _args = [].slice.call(arguments); // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值,执行时已经收集所有参数为数组 var adder = function () { var _adder = function() { // 执行收集动作,每次传入的参数都累加到原参数 [].push.apply(_args, [].slice.call(arguments)); return _adder; }; // 利用隐式转换的特性,当执行时隐式转换,并计算最终的值返回 _adder.toString = function () { return _args.reduce(function (a, b) { return a + b; }); } return _adder; } return adder(_args); }
备注codepen中的console.log方法被重写,会有报错的问题,你可以直接通过浏览器的console控制台调试这个方法。
部分参数应用
部分参数应用是指有些场景是希望固定传递多个参数,来得到其固定的函数,然后基于这个函数去执行代码。类似于第一个例子中的一个折扣参数得出折扣算法的使用。我们将第一个例子再复杂化一些。就会变成这样的。
function getActualDiscount(custoemrLevel,discount){ } function getPriceComplex (custoemrLevel,discount){ let actualDiscount = getActualDiscount(custoemrLevel,discount); return price=>{ return price actualDiscount; } } // 等级一的折扣策略 let strategyLev1WithOnepoint = getPriceComplex('lev1',0.1) ; let actualPrice = strategyLev1WithOnepoint(500);
以上所述是长沙网络推广给大家介绍的用场景去理解函数柯里化(入门篇)详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,长沙网络推广会及时回复大家的。在此也非常感谢大家对狼蚁SEO网站的支持!
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程