Javascript中的bind()函数
今天看到公司大神的一段代码:
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()函数的更多相关文章
- JavaScript中的bind,call和apply函数的用法和区别
一直没怎么使用过JavaScript中的bind,call和apply, 今天看到一篇比较好的文章,觉得讲的比较透彻,所以记录和总结如下 首先要理解的第一个概念,JavaScript中函数调用的方式, ...
- JavaScript中的普通函数和箭头函数
最近被问到了一个问题: javaScript 中的箭头函数 ( => ) 和普通函数 ( function ) 有什么区别? 我当时想的就是:这个问题很简单啊~(flag),然后做出了错误的回答 ...
- 借助JavaScript中的时间函数改变Html中Table边框的颜色
借助JavaScript中的时间函数改变Html中Table边框的颜色 <html> <head> <meta http-equiv="Content-Type ...
- 前端学习 第二弹: JavaScript中的一些函数与对象(1)
前端学习 第二弹: JavaScript中的一些函数与对象(1) 1.apply与call函数 每个函数都包含两个非继承而来的方法:apply()和call(). 他们的用途相同,都是在特定的作用域中 ...
- 理解和使用 JavaScript 中的回调函数
理解和使用 JavaScript 中的回调函数 标签: 回调函数指针js 2014-11-25 01:20 11506人阅读 评论(4) 收藏 举报 分类: JavaScript(4) 目录( ...
- JavaScript中变量和函数声明的提升
现象: 1.在JavaScript中变量和函数的声明会提升到最顶部执行. 2.函数的提升高于变量的提升. 3.函数内部如果用var声明了相同名称的外部变量,函数将不再向上寻找. 4.匿名函数不会提升. ...
- javascript中使用md5函数
javascript中使用md5函数 这对于js来讲本来是没有的,现在可以自己定义一个md5的函数,达到加密效果. var hexcase = 0; function hex_md5(a) { if ...
- 在 JavaScript 中使用构造器函数模拟类
今天,我们要讲的是在 JavaScript 中使用构造器函数(construcor function)模拟类. 构造器函数简介 你可以使用 ES6 的 class 关键字来实现类,不过我建议你使用传统 ...
- 来一轮带注释的demo,彻底搞懂javascript中的replace函数
javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...
随机推荐
- spring3.1........jar包下载
1.common-dbcp-1.4.jar 下载地址:http://commons.apache.org/dbcp/ 2.common-pool-1.6.jar 下载地址:http://commons ...
- Selenium2(java)框架设计 九
设计框架原则: 数据分离,业务层和逻辑层不要混杂在一起. 设计图: 框架结构初始化: com.wymall.test:这是存放这个框架源代码的根目录 base:里面有个基类(BaseParpaare. ...
- 2.3. 实体(Core Data 应用程序实践指南)
Entity 实体,就像是数据表的映射类.用实体就可以创建托管对象了. 实体需要做的就是设置实体名称.实体属性及属性数据类型. 还可以根据实体配置NSManagedObject的子类(可选),创建子类 ...
- delphi 获得memo,Richedit焦点所在行
procedure TForm1.Button1Click(Sender: TObject); var i:Integer; begin i:=SendMessage(Richedit1.handle ...
- js原生设计模式——8单例模式之简约版属性样式方法库
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- eclipse调试找不到源解决办法
eclipse调试时有时显示找不到源码,首先得确定代码没问题 这是eclipse没有发现工程源码,解决办法是 右键工程>>Debug As >> Debug configura ...
- 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 ...
- 你真的懂ajax吗?
前言 总括: 本文讲解了ajax的历史,工作原理以及优缺点,对XMLHttpRequest对象进行了详细的讲解,并使用原生js实现了一个ajax对象以方便日常开始使用. damonare的ajax库: ...
- 三分钟解读springmvc依赖
长期以来都在写SSM框架的项目,却未能深入理解框架的搭建原理,而只是浅薄的理解前辈的架构,然后不断套用,项目做过几个,但框架的内涵却没有把握.小编打算今天从SpringMVC的依赖分析做起,一步步进行 ...
- 深圳尚学堂:Web程序员应该会的知识
互联网的行业里涌入了很多的程序员, 都在为互联网的发展添砖加瓦.程序员可以分为很多种,像Unix程序员.Windows程序员,或是C++程序员.Delphi程序员,等等.今天我们谈谈Web程序员,一名 ...