惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
有赞技术团队
有赞技术团队
量子位
N
Netflix TechBlog - Medium
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
Google DeepMind News
Google DeepMind News
aimingoo的专栏
aimingoo的专栏
GbyAI
GbyAI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Blog — PlanetScale
Blog — PlanetScale
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
Martin Fowler
Martin Fowler
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
博客园 - 司徒正美
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
V
V2EX
IT之家
IT之家
L
LangChain Blog
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 小郝(Kaibo Hao)

Big O Complexity Chart (From: bigocheatsheet.com) Machine Learning Note - Note 1 JavaScript Patterns 7.1 Singleton JavaScript Patterns 6.7 Borrowing Methods JavaScript Patterns 6.6 Mix-ins JavaScript Patterns 6.5 Inheritance by Copying Properties JavaScript Patterns 6.4 Prototypal Inheritance JavaScript Patterns 6.3 Klass JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance JavaScript Patterns 6.1 Classical Versus Modern Inheritance Patterns JavaScript Patterns 5.9 method() Method JavaScript Patterns 5.8 Chaining Pattern JavaScript Patterns 5.7 Object Constants JavaScript Patterns 5.6 Static Members JavaScript Patterns 5.5 Sandbox Pattern JavaScript Patterns 5.4 Module Pattern JavaScript Patterns 5.3 Private Properties and Methods JavaScript Patterns 5.2 Declaring Dependencies JavaScript Patterns 5.1 Namespace Pattern
JavaScript Patterns 4.10 Curry
小郝(Kaibo Hao) · 2014-06-18 · via 博客园 - 小郝(Kaibo Hao)

2014-06-18 23:01  小郝(Kaibo Hao)  阅读(300)  评论()    收藏  举报

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]);
// 9

// partial application

var newadd = add.partialApply(null, [5]);

// applying an argument to the new function

newadd.apply(null, [4]);
// 9

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);
// 7

// create and store a new function

var add2000 = add(2000);

add2000(10);
// 2010

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);
// 9

// another option -- call the new function directly

schonfinkelize(add, 6)(7);
// 13

// 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);
// 16

// two-step currying

var addOne = schonfinkelize(add, 1);

addOne(10, 10, 10, 10);
// 41

var addSix = schonfinkelize(addOne, 2, 3);

addSix(5, 5);
// 16

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)