深入理解JS中的Function.prototype.bind()方法


Posted in Javascript onOctober 11, 2016

前言

对于函数绑定(Function binding)很有可能是大家在使用JavaScript时最少关注的一点,但是当你意识到你需要一个解决方案来解决如何在另一个函数中保持this上下文的时候,你真正需要的其实就是 Function.prototype.bind() ,只是你有可能仍然没有意识到这点。

第一次遇到这个问题的时候,你可能倾向于将this设置到一个变量上,这样你可以在改变了上下文之后继续引用到它。

一. bind的语法

bind() 方法的主要作用就是将函数绑定至某个对象,bind() 方法会创建一个函数,函数体内this对象的值会被绑定到传入bind() 函数的值。

1.1 定义

bind()的定义如下:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

bind() 函数会创建一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目标函数)具有相同的函数体。当目标函数被调用时 this 值绑定到 bind() 的第一个参数,该参数不能被重写。

1.2 原理

可以用如下代码模拟bind()的原理:

Function.prototype.bind = function(context) {
 var self = this; // 保存原函数
 return function() { // 返回一个新函数
  return self.apply(context, arguments); // 执行新函数时,将传入的上下文context作为新函数的this
 }
}

1.3 语法

Function.prototype.bind(thisArg[, arg1[, arg2[, ...]]])

二. bind的应用场景

2.1 实现对象继承

var A = function(name) {
 this.name = name;
}

var B = function() {
 A.bind(this, arguments);
}

B.prototype.getName = function() {
 return this.name;
}

var b = new B("hello");
console.log(b.getName()); // "hello"

2.2 事件处理

var paint = {
 color: "red",
 count: 0,
 updateCount: function() {
  this.count++;
  console.log(this.count);
 }
};

// 事件处理函数绑定的错误方法:
document.querySelector('button')
 .addEventListener('click', paint.updateCount); // paint.updateCount函数的this指向变成了该DOM对象

// 事件处理函数绑定的正确方法:
document.querySelector('button')
 .addEventListener('click', paint.updateCount.bind(paint)); // paint.updateCount函数的this指向变成了paint

2.3 时间间隔函数

var notify = {
 text: "Hello World!",
 beforeRender: function() {
  alert(this.text);
 },
 render: function() {

  // 错误方法:
  setTimeout(this.beforeRender, 0); // undefined

  // 正确方法:
  setTimeout(this.beforeRender.bind(this), 0); // "Hello World!"
 }
};

notify.render();

2.4 借用Array的原生方法

var a = {};
Array.prototype.push.bind(a, "hello", "world")();

console.log(a); // "hello", "world"

三. bind()方法的浏览器兼容性

深入理解JS中的Function.prototype.bind()方法

四. bind()的兼容性写法

if (!Function.prototype.bind) {
 Function.prototype.bind = function() {
  var self = this, // 保存原函数
   context = [].shift.call(arguments), // 需要绑定的this上下文
   args = [].slice.call(arguments); // 剩余的参数转成数组
  return function() { // 返回一个新函数
   // 执行新函数时,将传入的上下文context作为新函数的this
   // 并且组合两次分别传入的参数,作为新函数的参数
   return self.apply(context, [].concat.call(args, [].slice.call(arguments))); 
  }
 };
}

五. bind与 call/apply方法的区别

共同点:

都可以改变函数执行的上下文环境;

不同点:

bind: 不立即执行函数,一般用在异步调用和事件; call/apply: 立即执行函数。

总结

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者使用Javascript能有一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
基于jquery的Repeater实现代码
Jul 17 Javascript
Ext 今日学习总结
Sep 19 Javascript
jQuery UI Autocomplete 1.8.16 中文输入修正代码
Apr 16 Javascript
JavaScript实现SHA-1加密算法的方法
Mar 11 Javascript
完美解决手机浏览器顶部下拉出现网页源或刷新的问题
Nov 30 Javascript
javascript数组拍平方法总结
Jan 20 Javascript
基于Vue2x的图片预览插件的示例代码
May 14 Javascript
jQuery实现table表格信息的展开和缩小功能示例
Jul 21 jQuery
Vue-cli@3.0 插件系统简析
Sep 05 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
Nov 06 Javascript
JS实现的合并两个有序链表算法示例
Feb 25 Javascript
简单了解微信小程序的目录结构
Jul 01 Javascript
Bootstrap轮播插件使用代码
Oct 11 #Javascript
KnockoutJS 3.X API 第四章之表单textInput、hasFocus、checked绑定
Oct 11 #Javascript
JavaScript获取URL中参数querystring的方法详解
Oct 11 #Javascript
JS实现表单验证功能(验证手机号是否存在,验证码倒计时)
Oct 11 #Javascript
Node.js的环境安装配置(使用nvm方式)
Oct 11 #Javascript
javascript 动态样式添加的简单实现
Oct 11 #Javascript
表单input项使用label同时引用Bootstrap库导致input点击效果区增大问题
Oct 11 #Javascript
You might like
PHP-MySQL教程归纳总结
2008/06/07 PHP
PHP+MYSQL 出现乱码的解决方法
2008/08/08 PHP
关于查看MSSQL 数据库 用户每个表 占用的空间大小
2013/06/21 PHP
php修改NetBeans默认字体的大小
2013/07/02 PHP
PHP函数strip_tags的一个bug浅析
2014/05/22 PHP
php中file_get_content 和curl以及fopen 效率分析
2014/09/19 PHP
PHP实现的随机红包算法示例
2017/08/14 PHP
encode脚本和normal脚本混用的问题与解决方法
2007/03/08 Javascript
jQuery学习笔记[1] jQuery中的DOM操作
2010/12/03 Javascript
JavaScript 布尔操作符解析  && || !
2012/08/10 Javascript
固定背景实现的背景滚动特效示例分享
2013/05/19 Javascript
JQuery实现绚丽的横向下拉菜单
2013/12/19 Javascript
js常用系统函数用法实例分析
2015/01/12 Javascript
JavaScript通过function定义对象并给对象添加toString()方法实例分析
2015/03/23 Javascript
javascript函数式编程实例分析
2015/04/25 Javascript
动态加载js文件简单示例
2016/04/21 Javascript
AngularJS基础 ng-model-options 指令简单示例
2016/08/02 Javascript
JavaScript实现使用Canvas绘制图形的基本教程
2016/10/27 Javascript
node学习记录之搭建web服务器教程
2017/02/16 Javascript
解决Vue2.0中使用less给元素添加背景图片出现的问题
2018/09/03 Javascript
微信小程序实现基于三元运算验证手机号/姓名功能示例
2019/01/19 Javascript
JQuery animate动画应用示例
2019/05/14 jQuery
浅析python 中__name__ = '__main__' 的作用
2014/07/05 Python
python 判断参数为Nonetype类型或空的实例
2018/10/30 Python
python 随机打乱 图片和对应的标签方法
2018/12/14 Python
Python selenium的基本使用方法分析
2019/12/21 Python
python ssh 执行shell命令的示例
2020/09/29 Python
美国运动鞋和运动服零售商:Footaction
2017/04/07 全球购物
德购商城:德国进口直邮商城
2017/06/13 全球购物
董事长职责范文
2013/11/08 职场文书
大学新闻系应届生求职信
2014/06/02 职场文书
师范类求职信
2014/06/21 职场文书
2015年清明节活动总结
2015/02/09 职场文书
MySQL数据库优化之通过索引解决SQL性能问题
2022/04/10 MySQL
Java 数组的使用
2022/05/11 Java/Android
nginx之内存池的实现
2022/06/28 Servers