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

 更新时间:2016年10月11日 11:36:06   作者:子匠_Zijor  
bind 是 ES5 中新增的一个方法,可以改变函数内部的this指向。这篇文章小编将带领大家深入理解Javascript中的Function.prototype.bind()方法。有需要的朋友们可以参考借鉴,下面来一起看看吧。

前言

对于函数绑定(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()方法的浏览器兼容性

四. 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的变量的入门教程

    理解JavaScript的变量的入门教程

    这篇文章主要介绍了理解JavaScript的变量的入门教程,是JS入门学习中的基础知识,需要的朋友可以参考下
    2015-07-07
  • js对象内部访问this修饰的成员函数示例

    js对象内部访问this修饰的成员函数示例

    这篇文章主要介绍了js对象内部访问this修饰的成员函数示例,需要的朋友可以参考下
    2014-04-04
  • js常用函数 不错

    js常用函数 不错

    js常用函数 不错...
    2006-09-09
  • 深入理解JavaScript系列(25):设计模式之单例模式详解

    深入理解JavaScript系列(25):设计模式之单例模式详解

    这篇文章主要介绍了深入理解JavaScript系列(25):设计模式之单例模式详解,本文给出了多种单例模式的实现方式,需要的朋友可以参考下
    2015-03-03
  • 详解原生JS动态添加和删除类

    详解原生JS动态添加和删除类

    这篇文章主要介绍了原生JS动态添加和删除类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • 裁剪字符串trim()自定义改进版

    裁剪字符串trim()自定义改进版

    下面讲述的是自定义trim()函数遇到的问题,改进的过程,建议在支持的浏览器中使用原生函数
    2013-04-04
  • 深入理解ECMAScript的几个关键语句

    深入理解ECMAScript的几个关键语句

    下面小编就为大家带来一篇深入理解ECMAScript的几个关键语句。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • THREE.JS入门教程(5)你应当知道的十件事

    THREE.JS入门教程(5)你应当知道的十件事

    Three.js是一个伟大的开源WebGL库,WebGL允许JavaScript操作GPU,在浏览器端实现真正意义的3D,本文会让你了解一下使用THREE.JS处理3D/避免SetInterval/使用倒序循环等等,感兴趣的朋友可以了解下哦
    2013-01-01
  • JavaScript中的操作符类型转换示例总结

    JavaScript中的操作符类型转换示例总结

    最近发现在前端的面试题目中经常出现操作符类型转换的题目,于是这里来进行一个JavaScript中的操作符类型转换示例总结,需要的朋友可以参考下
    2016-05-05
  • JavaScript基础之this指向

    JavaScript基础之this指向

    这篇文章主要介绍了浅谈JavaScript this指向以及修改指向,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-11-11

最新评论