JavaScript作为一门灵活多变的编程语言,其函数的高级特性为开发者提供了强大的功能和表达力。本文将聚焦于柯里化(Currying),探索它们如何在实际编程中发挥重要作用,并通过实例演示它们的妙用。
闭包:函数内部的持久记忆闭包是JavaScript中最令人着迷的概念之一。简单来说,闭包是指有权访问另一个函数作用域中的变量的函数,即使在其父函数已经关闭(执行完毕)的情况下依然可以访问。这得益于JavaScript的垃圾回收机制不会立即回收那些被内部函数引用的外部变量。柯里化的过程中也有闭包的产生。
详细可查看:深入解析JavaScript闭包:功能、机制与实践中的权衡艺术
柯里化:函数的优雅变形柯里化(Currying),又称为部分求值(Partial Evaluation),是一种在计算机科学中将多参数函数转换为一系列单参数函数的技术。具体来说,柯里化的过程是将一个原本接受多个参数的函数转换成接受第一个参数的函数,该函数返回一个新的函数,新函数接受剩余参数中的第一个,然后可能再返回下一个函数以接受更多的参数,依此类推,直到所有参数都被提供为止,最后的函数则返回最终结果。
以JavaScript为例,原始函数可能像这样:
function add(a, b, c) { return a + b + c;}经过柯里化后,它可能被改写为:
function Add(a) { return function(b) { return function(c) { return a + b + c; }; };}使用柯里化版本的函数时,你可以这样调用:
const addFive = Add(5);const addThreeToFive = addFive(3);const result = addThreeToFive(2); // 输出10在这个过程中,curriedAdd(5)返回一个接受第二个参数的函数,然后addFive(3)再次返回一个接受第三个参数的函数,最后addThreeToFive(2)计算并返回最终结果10。
柯里化的主要优点包括增强函数的可复用性、便于函数组合、以及在某些情况下实现更灵活的控制流。
拓展类数组在JavaScript中,"类数组"(Array-like)对象是指那些拥有长度(length属性)和索引元素,但并不一定是真正的Array实例的对象。类数组对象通常缺少Array.prototype上的方法,如push、pop、slice等,它们可能也无法直接使用数组的其它一些特性,比如迭代方法(forEach、map等)。尽管如此,由于它们在结构上类似于数组,我们有时可以通过一些技巧来像操作数组一样操作它们。
根据上面实例,如果需要对参数数量进行管理,或者以另一种方式实现三个数相加都可以使用到类数组arguments。
function add(a, b, c) { let sum=0 if(arguments.length<3){ console.log('参数数量不足'); return } for(var i=0; i<arguments.length; i++){ sum+=arguments[i] } return sum}这里我们对类数组的使用就如同使用数组一样,但通过类型判断Object.prototype.toString.call(arguments),返回结果为[object Arguments]。
Array.prototype.reduce()Array.prototype.reduce()是JavaScript数组的一个方法,用于对数组中的每个元素执行一个由您提供的reducer函数(累计器),结果是将数组中的值累积成一个单一的返回值。这个方法特别适用于数组的值需要被汇总成一个总结值的情况,比如求和、求积、计算平均值等。
从MDN官方文档中我们可以了解到它的基本语法和语法。
const array1 = [1, 2, 3, 4];// 0 + 1 + 2 + 3 + 4const initialValue = 0;const sumWithInitial = array1.reduce( (accumulator, currentValue) => accumulator + currentValue, initialValue,);console.log(sumWithInitial);简单来说,就是initialValue为accumulator的初始值,该案例中,初始值为0,表示从0开始累加,每一次相加后会返回一个结果给accumulator然后继续相加,直至相加结束。
展开运算符、reduce()与箭头函数结合如下面案例,通过使用ES6的展开运算符...,会得到一个数组,再结合刚刚我们学会的 Array.prototype.reduce(),进而简化了对arguments对象的依赖,展现了现代JavaScript语法糖的魅力。
console.log(Object.prototype.toString.call(args))//'[object Array]'const add=(...args)=>args.reduce((prev,cur)=>prev+cur,0)console.log(add(1,2,3));//输出6箭头函数自身不携带arguments对象,也不绑定自己的this,在展开运算符和 Array.prototype.reduce()的共同作用下,使得没必要去使用arguments和this,那么使用箭头函数就更方便简洁了。
结语通过理解和掌握这些高级技巧,开发者能够编写出更加简洁、可读性更强、易于维护的代码。随着JavaScript的不断进化,诸如箭头函数、展开运算符等新特性为我们提供了更多实现思路,让函数的运用更加灵活高效。如果还有不同的求和方法,欢迎在评论区留言我们一起学习。
作者:Delighted链接:https://juejin.cn/post/7385098943941771318