JavaScript Patterns 4.10 Curry
Function Application
apply() takes two parameters: the first one is an object to bind to this inside of the function, the second is an array or arguments, which then becomes the array-like arguments object available inside the function. If the first parameter is null, then this points to the global object, which is exactly what happens when you call a function that is not a method of a specific object.
// define a function
var sayHi = function(who) {
return "Hello" + ( who ? ", " + who : "") + "!";
};
// invoke a function
sayHi();
// "Hello"
sayHi('world');
// "Hello, world!"
// apply a function
sayHi.apply(null, ["hello"]);
// "Hello, hello!"
//-----------------------------------------------------------------------
var alien = {
sayHi : function(who) {
return "Hello" + ( who ? ", " + who : "") + "!";
}
};
alien.sayHi('world');
// "Hello, world!"
sayHi.apply(alien, ["humans"]);
// "Hello, humans!"
In the preceding snippet, this inside of sayHi() points to alien. In the previous example this points to the global object.
When you have a function that takes only one parameter, you can save the work of creating arrays with just one element:
// the second is more efficient, saves an array sayHi.apply(alien, ["humans"]); // "Hello, humans!" sayHi.call(alien, "humans"); // "Hello, humans!"
Partial Application
var add = function(x, y) {
return x + y;
};
// full application
add.apply(null, [5, 4]);
//
// partial application
var newadd = add.partialApply(null, [5]);
// applying an argument to the new function
newadd.apply(null, [4]);
//
Here’s no partialApply() method and functions in JavaScript don’t behave like this by default. But you can make them, because JavaScript is dynamic enough to allow this. The process of making a function understand and handle partial application is called currying.
// a curried add()
// accepts partial list of arguments
function add(x, y) {
var oldx = x, oldy = y;
if ( typeof oldy === "undefined") {// partial
return function(newy) {
return oldx + newy;
};
}
// full application
return x + y;
}
// test
typeof add(5);
// "function"
add(3)(4);
//
// create and store a new function
var add2000 = add(2000);
add2000(10);
//
General-purpose currying function
function schonfinkelize(fn) {
var slice = Array.prototype.slice, stored_args = slice.call(arguments, 1);
return function() {
var new_args = slice.call(arguments), args = stored_args.concat(new_args);
return fn.apply(null, args);
};
}
// a normal function
function add(x, y) {
return x + y;
}
// curry a function to get a new function
var newadd = schonfinkelize(add, 5);
newadd(4);
//
// another option -- call the new function directly
schonfinkelize(add, 6)(7);
//
// a normal function
function add(a, b, c, d, e) {
return a + b + c + d + e;
}
// works with any number of arguments
schonfinkelize(add, 1, 2, 3)(5, 5);
//
// two-step currying
var addOne = schonfinkelize(add, 1);
addOne(10, 10, 10, 10);
//
var addSix = schonfinkelize(addOne, 2, 3);
addSix(5, 5);
//
When to Use Currying
When you find yourself calling the same function and passing mostly the same parameters, then the function is probably a good candidate for currying. You can create a new function dynamically by partially applying a set of arguments to your function. The new function will keep the repeated parameters stored (so you don’t have to pass them every time) and will use them to pre-fill the full list of arguments that the original function expects.
References:
JavaScript Patterns - by Stoyan Stefanov (O`Reilly)
JavaScript Patterns 4.10 Curry的更多相关文章
- JavaScript Patterns 2.10 Naming Conventions
1. Capitalizing Constructors var adam = new Person(); 2. Separating Words camel case - type the word ...
- JavaScript Patterns 7.1 Singleton
7.1 Singleton The idea of the singleton pattern is to have only one instance of a specific class. Th ...
- JavaScript Patterns 6.7 Borrowing Methods
Scenario You want to use just the methods you like, without inheriting all the other methods that yo ...
- JavaScript Patterns 6.6 Mix-ins
Loop through arguments and copy every property of every object passed to the function. And the resul ...
- JavaScript Patterns 6.5 Inheritance by Copying Properties
Shallow copy pattern function extend(parent, child) { var i; child = child || {}; for (i in parent) ...
- JavaScript Patterns 6.4 Prototypal Inheritance
No classes involved; Objects inherit from other objects. Use an empty temporary constructor function ...
- JavaScript Patterns 6.3 Klass
Commonalities • There’s a convention on how to name a method, which is to be considered the construc ...
- JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance
// the parent constructor function Parent(name) { this.name = name || 'Adam'; } // adding functional ...
- JavaScript Patterns 6.1 Classical Versus Modern Inheritance Patterns
In Java you could do something like: Person adam = new Person(); In JavaScript you would do: var ada ...
随机推荐
- jvm运行数据分布
本人看的深入理解jvm(该版本的java se7) java运行时数据区域 Java虚拟机在执行java程序时,把内存划分为几个不同的阶段,存在不同的存在时间.不同的用途 先上图 程序计数器:是jvm ...
- 应用服务器和Web服务器
如上图所示,绝大部分的公司会采用Apache+tomcat集群(或jetty集群)来部署公司的Web服务, Web服务器和应用服务器关系,先介绍一下我们常说的服务器: Tomcat服务器,是运行ser ...
- Struts 2.3.24源码解析+Struts2拦截参数,处理请求,返回到前台过程详析
Struts2官网:http://struts.apache.org/ 目前最新版本:Struts 2.3.24 Struts1已经完全被淘汰了,而Struts2是借鉴了webwork的设计理念而设计 ...
- windows下命令行打jar包方法
注意:系统必须装了java并且配置好了java环境变量. 事先必须编译好需要打jar的class.(eclipse一般在bin,maven构建的在target/classes) 进入cmd,输入ja ...
- Java基础学习总结--对象容器
目录: ArrayList 顺序泛型容器 HashSet 集合容器 HashMap<Key,Value>容器 要用Java实现记事本的功能.首先列出记事本所需功能: 可以添加记录(字符串) ...
- jQuery Layer 弹层组件
layer是一款近年来口碑非常不错的web弹层组件,她具备全方位的解决方案,致力于服务各个水平段的开发人员,您的页面会轻松地拥有丰富友好的操作体验. 在与同类组件的比较中,layer总是能轻易获胜.她 ...
- float 和 inline-block的心得
float 优点: 横向排列时比较方便,不存在浏览器兼容问题. 缺点: 1)多行横向排行时,换行后经常不能顶行显示. 2)浮动后会跳出当前流,造成父元素高度塌陷,解决办法比较成熟统一 ,不存在浏览器兼 ...
- TI的DSP、ST的ARM、Intel的X86浮点性能对比
估计没什么价值,单纯地记录下时间,以便以后查看. TMS320F28335 STM32f030 i3 4170 i3 4170 主频 150MHz 48MHz 3.7GHZ 3.7GHZ IDE ...
- vncserver安装
我的环境是centos6.5,如果没有安装桌面,先执行: # yum groupinstall "X Window System" "Desktop" # yu ...
- Android添加快捷方式(Shortcut)到手机桌面
Android添加快捷方式(Short)到手机桌面 权限 要在手机桌面上添加快捷方式,首先需要在manifest中添加权限. <!-- 添加快捷方式 --> <uses-permis ...