今天看到公司大神的一段代码:

function ReplaceProcessor() {
this._dom = {
btnReplace: $('#ro_btnReplace'),
btnComplete: $('#ro_btnComplete')
};
// Bind events
this._dom.btnReplace.on('click', this._onReplace.bind(this));
this._dom.btnComplete.on('click', this._onComplete.bind(this));
} ReplaceProcessor.prototype._onReplace = function() {
// code
this._dom.btnComplete.html("OK");
}

这里面最后两行代码是向DOM节点上绑定事件,"this._onReplace.bind(this)"明显就是绑定的执行函数,在不知道具体作用的情况下猜测一下bind()的作用可能和call或者apply类似,用来改变function执行时的上下文环境,不知道理解的对不对所以找资料来印证一下。

先上官网的解释,不管我们个人的解释是多么的接地气,官方API到底还是比较靠谱的:
  bind方法会创建一个新函数,称为绑定函数.当调用这个绑定函数时,绑定函数会以创建它时传入bind方法的第一个参数作为this,传入bind方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数.

这个解释多读几次还是很靠谱的,不是很难懂。从功能描述上看和call以及apply还是有区别的,应用的场景不太一样,bind主要是为了改变函数内部的this指向,这个是在ECMA5以后加入的,所以IE8一下的浏览器不支持,当然有兼容的办法,不过坦白说首先对于IE8以下实在无爱,其次那种情况下估计你也没什么心情用bind了吧。。。

东西就是这么个东西,最主要的还是应用的场景,什么情况下使用。本文一开始代码中使用.bind(this)的效果就相当于将事件绑定的callback抽出来写,但是同时还维持了函数中的this指向。本来事件绑定的处理函数一般是一个匿名函数,这里相当于单独抽出来从而使结构更清晰的同时,this指向的是ReplaceProcessor的实例。

这里列举三部分的代码来说明bind能为我们做些什么,同时它的好处在哪里。

(一)事件处理函数
   所谓的事件处理函数其实就是绑定事件后的那个callback,这里如果用上bind你的代码应该会简洁优雅一些,我在开篇列出的那段代码里就是这样做的。

var logger = {
x: 0,
updateCount: function() {
this.x++;
console.log(this.x);
}
}
// 下面两段代码的实现是一样的
document.querySelector('button').addEventListener('click', function() {
logger.updateCount();
});
document.querySelector('button').addEventListener('click', logger.updateCount.bind(logger));

如何,这就是我之前说的,本来通常情况下处理函数都要用一层匿名函数包裹一下,才能维持处理函数本身的this.这里直接通过.bind(logger)人为的将其执行时的this指向logger对象。
bind()创建了一个函数,当这个函数在被调用的时候,它的this关键词会被设置成被传入的值(这里指调用bind()时传入的参数)。

(二)setTimeout 

function LateBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
// declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
window.setTimeout(this.declare.bind(this), 1000);
};
LateBloomer.prototype.declare = function() {
console.log('I am a beautiful flower with ' + this.petalCount + ' petals!');
};

看一下这里this.dclare.bind(this),相当于将LateBloomer的实例对象传递到declare中,是不是setTimeout简洁了很多,同时不会破坏其他执行函数的结构。

(三)请完整阅读下面的代码

//设立一个简单地对象作为“上下文”
var context = {
foo: "bar"
};
//一个在this上下文中指向foo变量的函数
function returnFoo() {
return this.foo;
}
// 变量在作用域中不存在,因此显示undefined
returnFoo(); // => undefined
// 如果我们把它绑定在context上下文中
var bound = returnFoo.bind(context);
// 现在的作用域中有这个变量了
bound(); // => "bar"
//
// 这就是Function.prototype.bind的作用.
//由于returnFoo也是函数,因此它继承了function的原型
//
// 如果你觉得享受,接着往下读,下面更精彩
//
// 有许多方法将函数绑定在一个上下文中
// Call和Apply让你能在上下文中调用函数
returnFoo.call(context); // => bar
returnFoo.apply(context); // => bar
// 将函数添加到对象中
context.returnFoo = returnFoo;
context.returnFoo(); // => bar
//
// 现在我们来玩一点诡异的东西
//
// Array.prototype 中有一个叫做slice的方法
// 对一个数组调用slice,可以返回一个从start index到end index的数组
[1, 2, 3].slice(0, 1); // => [1]
// 因此我们把Array.slice赋值给一个本地变量slice
var slice = Array.prototype.slice;
//现在的slice是"自由的",由于Array.prototype中的slice一般指定了上下文
//或者默认为this,此时slice将不起作用
slice(0, 1); // => TypeError: can't convert undefined to object
slice([1, 2, 3], 0, 1); // => TypeError: ...
// 但是如果我们使用call或者apply,slice又将在一个上下文中执行
slice.call([1, 2, 3], 0, 1); // => [1]
// Apply和Call差不多,知识参数要放在一个数组中
slice.apply([1, 2, 3], [0, 1]); // => [1]
// 使用call没错了,那么能不呢使用bind呢?
// 没错,我们来把"call"绑定在slice上
slice = Function.prototype.call.bind(Array.prototype.slice);
// 现在slice可以把第一个参数作为上下文了
slice([1, 2, 3], 0, 1); // => [1]
//
// 很酷,对吧。现在再来完成一件事
//
// 现在我们对bind本身做一件刚才对silce做的事
var bind = Function.prototype.call.bind(Function.prototype.bind);
// 在这里总结一下,好好想想
// 发生了什么事? 我们改变了call,
// 返回一个接收一个函数和一个上下文作为ic桉树的函数
//并且返回了一个完全绑定的函数
// 回到最初的例子
var context = {
foo: "bar"
}; function returnFoo() {
return this.foo;
}
// 现在来使用神奇的"bind"函数
var amazing = bind(returnFoo, context);
amazing(); // => bar
 

Javascript中的bind()函数的更多相关文章

  1. JavaScript中的bind,call和apply函数的用法和区别

    一直没怎么使用过JavaScript中的bind,call和apply, 今天看到一篇比较好的文章,觉得讲的比较透彻,所以记录和总结如下 首先要理解的第一个概念,JavaScript中函数调用的方式, ...

  2. JavaScript中的普通函数和箭头函数

    最近被问到了一个问题: javaScript 中的箭头函数 ( => ) 和普通函数 ( function ) 有什么区别? 我当时想的就是:这个问题很简单啊~(flag),然后做出了错误的回答 ...

  3. 借助JavaScript中的时间函数改变Html中Table边框的颜色

    借助JavaScript中的时间函数改变Html中Table边框的颜色 <html> <head> <meta http-equiv="Content-Type ...

  4. 前端学习 第二弹: JavaScript中的一些函数与对象(1)

    前端学习 第二弹: JavaScript中的一些函数与对象(1) 1.apply与call函数 每个函数都包含两个非继承而来的方法:apply()和call(). 他们的用途相同,都是在特定的作用域中 ...

  5. 理解和使用 JavaScript 中的回调函数

    理解和使用 JavaScript 中的回调函数 标签: 回调函数指针js 2014-11-25 01:20 11506人阅读 评论(4) 收藏 举报  分类: JavaScript(4)    目录( ...

  6. JavaScript中变量和函数声明的提升

    现象: 1.在JavaScript中变量和函数的声明会提升到最顶部执行. 2.函数的提升高于变量的提升. 3.函数内部如果用var声明了相同名称的外部变量,函数将不再向上寻找. 4.匿名函数不会提升. ...

  7. javascript中使用md5函数

    javascript中使用md5函数 这对于js来讲本来是没有的,现在可以自己定义一个md5的函数,达到加密效果. var hexcase = 0; function hex_md5(a) { if ...

  8. 在 JavaScript 中使用构造器函数模拟类

    今天,我们要讲的是在 JavaScript 中使用构造器函数(construcor function)模拟类. 构造器函数简介 你可以使用 ES6 的 class 关键字来实现类,不过我建议你使用传统 ...

  9. 来一轮带注释的demo,彻底搞懂javascript中的replace函数

    javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...

随机推荐

  1. delphi 字符串查找替换函数 转

    1.       提取字符串中指定子字符串前的字符串 Function Before( Src:string ; S:string ): string ; Var   F: Word ; begin ...

  2. MySQL服务器的线程数查看方法

    mysql重启命令:/etc/init.d/mysql restart MySQL服务器的线程数需要在一个合理的范围之内,这样才能保证MySQL服务器健康平稳地运行.Threads_created表示 ...

  3. Chrome 报 Resource interpreted as Script but transferred with MIME type text/plain 警告的解决办法

    http://www.2cto.com/os/201312/262437.html 安装了VS2012之后,chrome在加载页面的时候会报 Resource interpreted as Scrip ...

  4. easyUI parser的使用

    easyUI parser的使用: <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  5. Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式

    解析:Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式.面向字节的操作为以8位为单位对二进制的数据进行操作,对数据不进行转换,这些类都是InputStream和Out ...

  6. 集群环境下JSP中获取客户端IP地址的方法

    String ip = request.getHeader("X-Forwarded-For");if (ip == null || ip.length() == 0 || &qu ...

  7. 利用享元模式来解决DOM元素过多导致的网页解析慢、卡死的问题

    我也不知道应该为本文的思路取一个什么比较恰当的标题,但是感觉符合享元模式的思路. 在一些网页应用中,有时会碰到一个超级巨大的列表,成千上万行,这时大部份浏览器解析起来就非常痛苦了(有可能直接卡死). ...

  8. Hadoop权威指南:HDFS-Hadoop存档

    Hadoop权威指南:HDFS-Hadoop存档 [TOC] 每个文件按块方式存储, 每个块的元数据存储在namenode的内存中 Hadoop存档文件或HAR文件是一个更高效的文件存档工具,它将文件 ...

  9. 未来手机Alo即将问世!全息投影手机的新高峰!全息3d 网

    文章来源:网络         编辑:大熊 [摘要]全息投影手机很早就开始炒,网络上的概念机也是丛出不穷,那么这款出自法国的概念机又是多么的奇葩?全息 3d 网带你一探究竟. 据外媒报道,在不久将来语 ...

  10. Hibernate调用带有输入参数,输出参数为cursor的存储过程

    一.Oracle创建表及存储过程 1.创建表T_MONITOR_DEVICE 创建后的表结构 2.创建存储过程 create or replace procedure ProcTestNew(v_mo ...