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. jvm运行数据分布

    本人看的深入理解jvm(该版本的java se7) java运行时数据区域 Java虚拟机在执行java程序时,把内存划分为几个不同的阶段,存在不同的存在时间.不同的用途 先上图 程序计数器:是jvm ...

  2. 应用服务器和Web服务器

    如上图所示,绝大部分的公司会采用Apache+tomcat集群(或jetty集群)来部署公司的Web服务, Web服务器和应用服务器关系,先介绍一下我们常说的服务器: Tomcat服务器,是运行ser ...

  3. Struts 2.3.24源码解析+Struts2拦截参数,处理请求,返回到前台过程详析

    Struts2官网:http://struts.apache.org/ 目前最新版本:Struts 2.3.24 Struts1已经完全被淘汰了,而Struts2是借鉴了webwork的设计理念而设计 ...

  4. windows下命令行打jar包方法

     注意:系统必须装了java并且配置好了java环境变量. 事先必须编译好需要打jar的class.(eclipse一般在bin,maven构建的在target/classes) 进入cmd,输入ja ...

  5. Java基础学习总结--对象容器

    目录: ArrayList 顺序泛型容器 HashSet 集合容器 HashMap<Key,Value>容器 要用Java实现记事本的功能.首先列出记事本所需功能: 可以添加记录(字符串) ...

  6. jQuery Layer 弹层组件

    layer是一款近年来口碑非常不错的web弹层组件,她具备全方位的解决方案,致力于服务各个水平段的开发人员,您的页面会轻松地拥有丰富友好的操作体验. 在与同类组件的比较中,layer总是能轻易获胜.她 ...

  7. float 和 inline-block的心得

    float 优点: 横向排列时比较方便,不存在浏览器兼容问题. 缺点: 1)多行横向排行时,换行后经常不能顶行显示. 2)浮动后会跳出当前流,造成父元素高度塌陷,解决办法比较成熟统一 ,不存在浏览器兼 ...

  8. TI的DSP、ST的ARM、Intel的X86浮点性能对比

    估计没什么价值,单纯地记录下时间,以便以后查看.   TMS320F28335 STM32f030 i3 4170 i3 4170 主频 150MHz 48MHz 3.7GHZ 3.7GHZ IDE ...

  9. vncserver安装

    我的环境是centos6.5,如果没有安装桌面,先执行: # yum groupinstall "X Window System" "Desktop" # yu ...

  10. Android添加快捷方式(Shortcut)到手机桌面

    Android添加快捷方式(Short)到手机桌面 权限 要在手机桌面上添加快捷方式,首先需要在manifest中添加权限. <!-- 添加快捷方式 --> <uses-permis ...