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 ...
随机推荐
- Support for multiple result sets
https://blueprints.launchpad.net/myconnpy/+spec/sp-multi-resultsets Calling a stored procedure can p ...
- Firemonkey TEdit 切换不同 KeyboardType 样式
用代码切换 Edit 不同的键盘样式: procedure TForm1.Button1Click(Sender: TObject); begin Edit1.KeyboardType := TVir ...
- 制作Java视频播放器
一.工程准备 首先需要下载并安装VLC播放器,然后下载vlcj外部库. 下载slf4j中的slf4j-api-1.7.13.jar. slf4j- nop-1.7.13.jar 将vlc安装目录下的l ...
- php中的常用数组函数(七) 数组合并 array_merge()和array_merge_recursive()
$arr1 = array(1, 2, 3, 4, 'color'=>'red'); $arr2 = array('a', 'b', 'c', 'color'=>'blue'); prin ...
- CI框架源码阅读笔记3 全局函数Common.php
从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...
- MYSQL数据库如何赋予远程某个IP访问权限
1. 授权用户root使用密码jb51从任意主机连接到mysql服务器:代码如下:GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'jb ...
- [转载]协程-cooperative multitasking
[转载]协程三讲 http://ravenw.com/blog/2011/08/24/coroutine-part-1-defination-and-classification-of-corouti ...
- WebSocket 学习笔记--IE,IOS,Android等设备的兼容性问题与代码实现
一.背景 公司最近准备将一套产品放到Andriod和IOS上面去,为了统一应用的开发方式,决定用各平台APP嵌套一个HTML5浏览器来实现,其中数据通信,准备使用WebSocket的方式.于是,我开始 ...
- ENVI数据显示操作【Tools菜单操作1】
---恢复内容开始--- 一.Tools菜单命令及其功能 主图像窗口中Tool菜单多对应的下拉菜单共17项命令. 二.窗口链接/覆盖显示 窗口链接和叠加显示(Link和Overlay)是对多幅图像某一 ...
- Matter.js – 你不能错过的 2D 物理引擎
Matter.js 是一个 JavaScript 2D 刚体物理引擎的网页.Matter.Engine 模块包含用于创建和操作引擎的方法.这个引擎是一个管理更新和渲染世界的模拟控制器. Matter. ...