[Effective JavaScript 笔记]第26条:使用bind方法实现函数的柯里化

Posted 脚后跟着猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Effective JavaScript 笔记]第26条:使用bind方法实现函数的柯里化相关的知识,希望对你有一定的参考价值。

bind方法的作用,除了有绑定函数到对象外,我们来看看bind方法的一些其它应用。

简单示例

例子:假设有一个装配URL字符串的简单函数。代码如下

function simpleURL(protocol,domain,path){
   return protocol+\'://\'+domain+\'/\'+path;
}

要将特定站点的路径字符串构建为绝对路径URL。可以使用ES5中数组的map方法来实现。如下

var paths=[\'wengxuesong/\',\'wengxuesong/p/5560484.html\',\'wengxuesong/p/5555714.html\'];
var urls=paths.map(function(path){
   return simpleURL(\'http\',\'www.cnblogs.com\',path);
});
urls;//["http://www.cnblogs.com/wengxuesong/", "http://www.cnblogs.com/wengxuesong/p/5560484.html", "http://www.cnblogs.com/wengxuesong/p/5555714.html"]

这里功能的实现完成正确。
但有没有可以改进的地方呢?里面每一次的迭代都使用相同的协议字符串和网站域名字符串。传给simpleURL函数的前两个参数对于迭代都是固定的,仅第三个参数是变化的。可以通过bind方法来生成一个已经包含两个参数的匿名函数。代码如下:

var urls=paths.map(simpleURL.bind(null,\'http\',\'www.cnblogs.com\'));

对于simpleURL.bind的调用产生了一个委托到simpleURL的新函数。bind方法的第一个参数提供了接收者的值。这里因为不需要,所以使用null或undefined都可以。simpleURL.bind的其余参数和提供给新函数的所有参数共同组成了传递给simpleURL的参数。
以上代码可以拆分得更细些,代码如下:

var newSimpleURL=simpleURL.bind(null,\'http\',\'www.cnblogs.com\');
var urls=paths.map(newSimpleURL);

不使用bind方法也是可以实现函数的,下面的一个版本是使用简单的函数实现,代码如下

var noBindSimpleURL=function(path){
    return simpleURL(\'http\',\'www.cnblogs.com\',path);
}
var urls=paths.map(noBindSimpleURL);

这里对比一下,bind方法提供了一种更简单的实现,结构更简单,但对于不了解bind方法的人理解起来可能有一点难度。

函数柯里化

将函数与其参数的一个子集绑定的技术称为函数柯里化(curring),以逻辑学家Haskell curry的名字命名。
比起显式的封闭函数,函数柯里化是一种简洁的、使用更少引用来实现函数委托的技术。

个人理解

函数柯里化,只是对参数的处理,也就是简化参数。简图如下
1465181669874

提示

  • 使用bind方法实现函数柯里化,即创建一个固定需求参数子集的委托函数

  • 传入null或undefined作为接收者的参数来实现函数柯里化,从而忽略其接收者

以上是关于[Effective JavaScript 笔记]第26条:使用bind方法实现函数的柯里化的主要内容,如果未能解决你的问题,请参考以下文章

[Effective JavaScript 笔记] 第12条:理解变量声明提升

[Effective JavaScript 笔记]第15条:当心局部块函数声明笨拙的作用域

[Effective JavaScript 笔记]第48条:避免在枚举期间修改对象

[Effective JavaScript 笔记] 第14条:当心命名函数表达式笨拙的作用域

[Effective JavaScript 笔记]第23条:永远不要修改arguments对象

[Effective JavaScript 笔记]第17条:间接调用eval函数优于直接调用