对Javascript柯里化currying的理解
2015-03-15 12:32
435 查看
1. 学习currying
对于currying,在《Javascript高级程序设计(第3版)》的604页第22.1.5节有一句言简意赅的解释:“它用于创建已经设置好了一个或多个参数的函数”。要更好的学习和理解currying,建议阅读以下几篇博文:JS中的柯里化(currying) —— 张鑫旭
javascript的currying函数 —— 司徒正美
Javascript中currying的实现 —— Aaron
如果要我自己写,最多也就是对以上几篇的重复,所以理论部分不再赘述,下面讲讲我的理解。
2. 使用currying
市面上有很多currying的实现,实际上达成的效果都一致:我们有一个函数fn,通过currying(fn[, arg1][, arg2][, ...][, argn]),将fn包装为前n个参数固定的新函数,这里的n为currying中的arg数。在看currying的时候,大家最爱用add函数的例子(参见1中建议阅读的几篇博文):
function add(x, y) { return x + y; }
通过以下方式可以固定add的第一个参数,产生从addZero到addNine的函数(先忽略掉currying及其注释说明,看currying对add产生的效果,这里主要看for(var key in dict)循环里的注释):
function gener() {
var currying = function(fn) {
// fn 要进行柯里化的函数
// args 固定下来的参数,可以多个
var args = [].slice.call(arguments, 1);
// 包装fn,里面的arguments是向包装后的fn传入的未固定参数,args已固定参数
return function() {
// 已经固化的参数args和新传入的参数arguments连接成新参数数组newArgs
var newArgs = args.concat([].slice.call(arguments));
// 包装原fn并返回,参数为newArgs,apply(null, [...])方便直接用数组参数newArgs调fn
return fn.apply(null, newArgs);
};
};
function add(a, b) {
return a + b;
}
var dict = {
addNine: 9, addEight: 8, addSeven: 7, addSix: 6, addFive: 5,
addFour: 4, addThree: 3, addTwo: 2, addOne: 1, addZero: 0
};
for(var key in dict) {
// 相当于执行(this是window):
// this.addNine = cuurying(add, 9)
// this.addEight = cuurying(add, 8)
// ...
// this.addZero = cuurying(add, 0)
// 其中,addNine是固化add的第一个参数为9的函数,其他同理
this[key] = currying(add, dict[key]);
}
}
gener();
console.log(['addZero(1): ' , addZero(1)].join('') );
console.log(['addOne(1): ' , addOne(1)].join('') );
console.log(['addTwo(1): ' , addTwo(1)].join('') );
console.log(['addThree(1): ', addThree(1)].join(''));
console.log(['addFour(1): ' , addFour(1)].join('') );
console.log(['addFive(1): ' , addFive(1)].join('') );
console.log(['addSix(1): ' , addSix(1)].join('') );
console.log(['addSeven(1): ', addSeven(1)].join(''));
console.log(['addEight(1): ', addEight(1)].join(''));
console.log(['addNine(1): ' , addNine(1)].join('') );
控制台输出:
上面代码中使用的currying函数如下(注释写得不好,希望能帮助理解,这里将上面的currying函数提出来放这里,它是实现柯里化的关键):
var currying = function(fn) {
// fn 要进行柯里化的函数
// args 固定下来的参数,可以多个
var args = [].slice.call(arguments, 1);
// 包装fn,里面的arguments是向包装后的fn传入的未固定参数,args已固定参数
return function() {
// 已经固化的参数args和新传入的参数arguments连接成新参数数组newArgs
var newArgs = args
4000
.concat([].slice.call(arguments));
// 包装原fn并返回,参数为newArgs<span style="font-family: Arial, Helvetica, sans-serif;">,apply(null, [...])方便直接用数组参数newArgs调fn</span>
return fn.apply(null, newArgs);
};
};
说明都写在注释中了,如果理解困难,可以参考第1部分中的几篇博文。大家可能还不知道柯里化的作用,可以查看张鑫旭的《JS中的柯里化(currying)》中的第二部分“柯里化有什么作用?”。
相关文章推荐
- 浅析 JavaScript 中的 函数 currying 柯里化
- 函数-JavaScript 中的 函数 currying 柯里化
- 浅析 JavaScript 中的 函数 currying 柯里化
- javascript中的函数currying(柯里化) 的理解
- 全面理解Javascript里的类 --转载
- 理解JavaScript中的事件
- AJAX入门之深入理解JavaScript中的函数
- AJAX入门之深入理解JavaScript中的函数
- 理解JavaScript中的事件
- AJAX入门之深入理解JavaScript中的函数
- AJAX入门之深入理解JavaScript中的函数
- 全面理解javascript的caller,callee,call,apply概念[摘]
- AJAX入门之深入理解JavaScript中的函数
- 理解Javascript的caller,callee,call,apply区别
- javascript中事件的理解
- 深入理解JavaScript中的函数
- 理解JavaScript中的事件(收藏)
- 理解JavaScript中的事件
- Javascript - 全面理解 caller,callee,call,apply
- 全面理解javascript的caller,callee,call,apply概念