JavaScript 中的偏函数应用(Partial Application)实现原理
本文介绍 JavaScript 中偏函数应用(Partial Application)的概念与实现。通过对比数学函数定义,解析如何将多参数函数转换为接收部分参数并返回新函数的形式。文章提供了基于 arguments 对象处理的 m 函数实现代码,演示了如何固定部分参数以简化调用,并提及 Dojo 框架中 hitch 的相关应用。
偏函数应用的概念引入
本文旨在深入探讨 Partial Application(偏函数应用)技术。首先回顾函数的基本定义,参考维基百科的相关介绍:
在数学语境下,函数描述了输入值与唯一输出值之间的对应关系,记作 f(x)。例如,表达式 f(x)=x^2 定义了一个函数 f,它将每个输入值 x 映射到唯一的输出值 x^2。
若输入值为 3,则对应的输出值为 9。对于包含两个参数 x 和 y 的函数 g(x,y) = xy,其值为两者的乘积。上述描述假设 x 和 y 均为整数(int)。换一种视角,f(x) 可表示为映射 x -> y(x^2),类型签名写作 int -> int。
从数学函数到 JavaScript 实现
该函数接受一个整数并返回一个整数。再看 g(x,y),可表示为 x -> y -> z(xy),即 x 和 y 经过 g 映射到 z,类型签名写作 int -> int -> int。下面使用 JavaScript 实现 g(x,y) 函数:
代码如下:
function g(x,y){
return x*y;
} 实现简洁且符合数学定义。该函数依次接收两个参数 x 和 y,并返回它们的乘积。然而,当 x 为常数(例如自然数 n)时,g(n,y) = ny 变为常数与变量的乘积。此时函数仅接受一个参数 y 并返回 ny,即映射 y -> z(ny),类型签名写作 int -> int。据此理解,g(x,y) 实际上接收一个整数参数,并返回一个只接受整数并返回整数的新函数。使用 JavaScript 表示如下:
代码如下:
var h = g(2); 此处 h 表示函数 h(y) = 2y。因此,h(5) 结果为 10,h(13) 结果为 26。
代码如下:
h(5);
h(13); JavaScript 中偏函数的具体实现
该技术将多参数函数转换为接收单个参数的函数链,通常称为柯里化(Currying),以纪念 Haskell Curry。尽管他并非首位提出者,但 JavaScript 原生并不直接支持此特性。因此,我们需要通过代码实现这一功能。主要思路是存储参数,当调用函数链上的下一个函数时,取出之前存储的参数继续传递给后续函数,直至获得最终返回值。参考以下代码:
代码如下:
function atarr(a,index){
var index=index||0,args = new Array(a.length - index);
for(var i in a){
if(i>=index) args[i-index]=a[i];
}
return args;
}
function m(scope,fn){
if(arguments.length<3) return fn.call(scope);
var p = atarr(arguments,2);
return function(){
var args = atarr(arguments);
return fn.apply(scope,p.concat(args));
}
} 测试代码:
代码如下:
var plus = function(a,b){
return a+b;
};
var plus2 = m(null,plus,2);
console.log(plus2(10));
console.log(plus2(0));
//结果
12
2 总结与框架应用
至此目标已达成。上述 atarr 函数用于从 arguments 对象中提取指定位置开始的参数并保存至数组。m 函数是核心,它完成了存储函数链参数并返回接收剩余参数函数的任务。测试代码中的 plus 函数原本接收 a、b 两个参数并返回二者之和(类型签名 int -> int -> int),而 plus2 则变为接收一个参数 b 并与 2 相加,返回二者之和(类型签名 int -> int)。
借助前述步骤,我们完成了JavaScript中的偏函数应用。在Dojo框架里,hitch2实现了作用域绑定与偏函数功能。如有兴趣,可查阅其源码,实现简洁清晰。
D3.js 比例尺与坐标轴的配置详解
2026-11-05 16:54:46
JavaScript怎么遍历对象的Symbol键和不可枚举属性
2026-11-05 13:13:39
封装一个健壮的JS字符串判空工具函数
2026-11-05 12:16:14
JavaScript合并数组的三种常用方法:concat、扩展运算符与push
2026-11-05 11:22:29
JavaScript立即执行函数(IIFE)是什么及基本语法
2026-11-05 10:51:19
