js里方法和属性值为函数,就像一个东西两种称呼一个样,比如土豆,也叫马铃薯,一个样。既然一样,那就可以对对象的方法提取出来为函数,然后把提取出来的函数作为回调函数直接传递给高阶函数。

高阶函数是什么

玩过套娃娃游戏没,没玩过,没事,我也没玩过。
大致就是下面这个样子

呃,好吧,这才是真正的。

就是多层函数,以函数为参数或返回值的函数。有点绕,没事看看上面的图就明白了。想了解怎么实现个简单的请点这里
好了,函数拿出来了,给高阶函数做参数传进去了。
这里面很容易会忘记把传进去的函数绑定到当前对象上,自由惯了,没办法,自由很重要,但没有绑定的对象,你什么都做不了。比如没有女朋友,你就得靠双手了,伤身呀。

一个示例

来看看下面这段代码提提神。

var you={
gF:[],
add:function(s){
this.gF.push(s);
},
all:function(){
return this.gF.join("-");
}
}

比如你不希望一次只交一个女朋友,想同时交往多个。ES5的forEach方法,在每个源数组(多个女朋友)元素上重复地调用add方法(交往),就可以把多个女孩子加到你的后宫了。

var girls=["西施","王昭君","貂蝉","杨贵妃"];//按人物历史出场顺序,呵呵
girls.forEach(you.add);

想想看着四大美人,来出来一见。

you.all();//error:Cannot read property 'push' of undefined

什么都有人呢,都哪去了。
因为you.add的接收者并不是你(you对象)。函数的接收者取决于它是如何被调用的,上面并没有调用它,只是把它传给了高阶函数forEach。但forEach的实现使用全局对象,这个时候你加女朋友变成了,在全世界(window对象)里找gF属性,因为这个gF没有为undefined,所以也就没有push方法,这就报错了。
问题找到了,美女们还往哪里跑~

var girls=["西施","王昭君","貂蝉","杨贵妃"];//按人物历史出场顺序,呵呵
girls.forEach(you.add,you);
you.all();//"西施,王昭君,貂蝉,杨贵妃"

完美运行,是不是想想都美了。

匿名函数

但不是每个高阶函数都像forEach这样善解人意,提供一个其回调函数的接收者。如果遇到个不解风情的函数怎么办?我们可以创建一个调用对象方法的函数来运行。法子如下

var girls=["西施","王昭君","貂蝉","杨贵妃"];//按人物历史出场顺序,呵呵
girls.forEach(function(s){
you.add(s);
});
you.all();//"西施,王昭君,貂蝉,杨贵妃"

好了,事情就这样解决了。

bind方法

NO,还有东西要讲,现在请bind方法全场,它是在ES5标准库才有的函数方法。主要作用就是为函数指定一个对象为其接收者,你也可以理解为,就是指定函数里的this指向哪个对象的。现在就看看上面的情况,bind方法如何解决:

var girls=["西施","王昭君","貂蝉","杨贵妃"];//按人物历史出场顺序,呵呵
girls.forEach(you.add.bind(you));
you.all();//"西施,王昭君,貂蝉,杨贵妃"

怎么样,是不是很牛掰。那bind都弄了啥呢?这里you.add.bind(you)生成了一个全新的函数,这个函数行为和you.add是一致的,但它里把this定死了,死心踏地地就是you了,原来的函数you.add的接收者保持不变。

you.add===you.add.bind(you);//false

这样就可以在很多的场合共享函数了。特别是里面有this关键词的原型方法。只要使用bind就再也不用担心this的指向问题了。不用在外层作用域用变量存储this了。

var obj={
txt:'hello',
sayHello:function(){
console.log(this.txt);
}
}
document.body.onclick=obj.syaHello.bind(obj);//"hello"

事件绑定再也不用担心了。
bind方法在ES5之前需要兼容写法,详细请点击查看
下面就又到了书上的提示内容了,记住一小点受用很多噢。

提示

  • 注意,提取一个方法不会将方法的接收者绑定到该方法的对象上

  • 当给高阶函数传递对象方法时,使用匿名函数在适当的接收者上调用该方法

  • 使用bind方法创建绑定到适当接收者的函数

附录:这次没有附录,本节里的内容,在之前都有,没有引进新的知识点。

[Effective JavaScript 笔记]第25条:使用bind方法提取具有确定接收者的方法的更多相关文章

  1. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  2. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  3. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  4. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  5. [Effective JavaScript 笔记]第62条:在异步序列中使用嵌套或命名的回调函数

    异步程序的操作顺序 61条讲述了异步API如何执行潜在的代价高昂的I/O操作,而不阻塞应用程序继续处理其他输入.理解异步程序的操作顺序刚开始有点混乱.例如,下面的代码会在打印"finishe ...

  6. [Effective JavaScript 笔记]第19条:熟练掌握高阶函数

    高阶函数介绍 高阶函数曾经是函数式编程的一个概念,感觉是很高深的术语.但开发简洁优雅的函数可以使代码更加简单明了.过去几年中脚本语言采用了这些个技术,揭开了函数式编程的最佳惯用法的神秘面纱.高阶函数就 ...

  7. [Effective JavaScript 笔记]第20条:使用call方法自定义接收者来调用方法

    不好的实践 函数或方法的接收者(即绑定到特殊关键字this的值)是由调用者的语法决定的.方法调用语法将方法被查找的对象绑定到this变量,(可参阅之前文章<理解函数调用.方法调用及构造函数调用之 ...

  8. [Effective JavaScript 笔记]第21条:使用apply方法通过不同数量的参数调用函数

    apply()方法定义 函数的apply()方法和call方法作用相同,区别在于接收的参数的方式不同.apply()方法接收两个参数,一个是对象,一个是参数数组. apply()作用 1.用于延长函数 ...

  9. [Effective JavaScript 笔记]第44条:使用null原型以防止原型污染

    第43条中讲到的就算是用了Object的直接实例,也无法完全避免,Object.prototype对象修改,造成的原型污染.防止原型污染最简单的方式之一就是不使用原型.在ES5之前,并没有标准的方式创 ...

随机推荐

  1. js验证身份证号

    /* * 身份证检测(格式.地区.生日.年龄范围) * code:检测字符串 rangeAge:年龄范围[格式为:25-55] * 返回值 0:为空 ,不为0则验证不通过 */ : : : : : : ...

  2. Ruby On Rails 常用的精品Gem汇总

    首先需要注明一点,本文是原创的并不是从其它地方转载.所有的数据是我从 GitHub 和 RubyGems 上码下来的,数据的截取时间就是本文的发布日期. RubyGems 的下载量可以看到在用这个 g ...

  3. Koala Framework是什么?我为什么要写这个框架?

    当时的监管组,技术力量累积的很少,还在直连DB,使用着DataTable.DataSet作为数据的承载,监管是公司最近几年主推的项目,所以领导们决定进行重要调整. 初来乍到 由于之前没有任何的技术积累 ...

  4. Linq之隐式类型、自动属性、初始化器、匿名类

    目录 写在前面 系列文章 隐式类型 自动属性 初始化器 匿名类 总结 写在前面 上篇文章是本系列的小插曲,也是在项目中遇到,觉得有必要总结一下,就顺手写在了博客中,也希望能帮到一些朋友.本文将继续介绍 ...

  5. linux用终端上传文件和文件家到远程的服务器

    文件上传:scp 本地文件地址 root@aifei8.net:/var/www/html/landrover 文件夹上传:1.先进入文件夹目录 2. 执行命令:scp -r . root@aifei ...

  6. struts2支持的结果类型

    在struts2-core.jar/struts-default.xml中,我们可以找到关于result-type的一些配置信息,从中可以看出struts2组件默认为我们提供了这 些result-ty ...

  7. hdu2222 字典树

    要注意二点 . 这组数据 1 6 she he he say shr her yasherhs出现重复的,也要算.所以这里答案为4: 这一组 1 6 she he he say shr her yas ...

  8. Java 关键字 native

    native 关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件中,而是在用其他语言实现的文件中.Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言 ...

  9. asp.net input怎么获取值

    前台: <input type="hidden" name="content" value="content"> 后台: Req ...

  10. jquery ajax 应用返回类型是html json

    jquery ajax 例子:    function JudgeUserName()        {            $.ajax({            type:"GET&q ...