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的更多相关文章

  1. JavaScript Patterns 2.10 Naming Conventions

    1. Capitalizing Constructors var adam = new Person(); 2. Separating Words camel case - type the word ...

  2. 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 ...

  3. JavaScript Patterns 6.7 Borrowing Methods

    Scenario You want to use just the methods you like, without inheriting all the other methods that yo ...

  4. JavaScript Patterns 6.6 Mix-ins

    Loop through arguments and copy every property of every object passed to the function. And the resul ...

  5. JavaScript Patterns 6.5 Inheritance by Copying Properties

    Shallow copy pattern function extend(parent, child) { var i; child = child || {}; for (i in parent) ...

  6. JavaScript Patterns 6.4 Prototypal Inheritance

    No classes involved; Objects inherit from other objects. Use an empty temporary constructor function ...

  7. JavaScript Patterns 6.3 Klass

    Commonalities • There’s a convention on how to name a method, which is to be considered the construc ...

  8. JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance

    // the parent constructor function Parent(name) { this.name = name || 'Adam'; } // adding functional ...

  9. 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 ...

随机推荐

  1. Support for multiple result sets

    https://blueprints.launchpad.net/myconnpy/+spec/sp-multi-resultsets Calling a stored procedure can p ...

  2. Firemonkey TEdit 切换不同 KeyboardType 样式

    用代码切换 Edit 不同的键盘样式: procedure TForm1.Button1Click(Sender: TObject); begin Edit1.KeyboardType := TVir ...

  3. 制作Java视频播放器

    一.工程准备 首先需要下载并安装VLC播放器,然后下载vlcj外部库. 下载slf4j中的slf4j-api-1.7.13.jar. slf4j- nop-1.7.13.jar 将vlc安装目录下的l ...

  4. php中的常用数组函数(七) 数组合并 array_merge()和array_merge_recursive()

    $arr1 = array(1, 2, 3, 4, 'color'=>'red'); $arr2 = array('a', 'b', 'c', 'color'=>'blue'); prin ...

  5. CI框架源码阅读笔记3 全局函数Common.php

    从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...

  6. MYSQL数据库如何赋予远程某个IP访问权限

    1. 授权用户root使用密码jb51从任意主机连接到mysql服务器:代码如下:GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'jb ...

  7. [转载]协程-cooperative multitasking

    [转载]协程三讲 http://ravenw.com/blog/2011/08/24/coroutine-part-1-defination-and-classification-of-corouti ...

  8. WebSocket 学习笔记--IE,IOS,Android等设备的兼容性问题与代码实现

    一.背景 公司最近准备将一套产品放到Andriod和IOS上面去,为了统一应用的开发方式,决定用各平台APP嵌套一个HTML5浏览器来实现,其中数据通信,准备使用WebSocket的方式.于是,我开始 ...

  9. ENVI数据显示操作【Tools菜单操作1】

    ---恢复内容开始--- 一.Tools菜单命令及其功能 主图像窗口中Tool菜单多对应的下拉菜单共17项命令. 二.窗口链接/覆盖显示 窗口链接和叠加显示(Link和Overlay)是对多幅图像某一 ...

  10. Matter.js – 你不能错过的 2D 物理引擎

    Matter.js 是一个 JavaScript 2D 刚体物理引擎的网页.Matter.Engine 模块包含用于创建和操作引擎的方法.这个引擎是一个管理更新和渲染世界的模拟控制器. Matter. ...