Javascript Function.prototype.bind详细分析

 更新时间:2016年12月29日 10:51:34   投稿:lqh  
这篇文章主要介绍了Javascript Function.prototype.bind详细分析的相关资料,需要的朋友可以参考下

  Function.prototype.bind分析

bind()方法会创建一个新的函数,成为绑定函数。当调用这个绑定函数时,绑定函数会以创建它时传入的第一个参数作为this,传入bind()方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调取原函数。

       实际使用中我们经常会碰到这样的问题:

var name = "pig";
function Person(name){
  this.name = name;
  this.getName = function(){
    setTimeout(function(){
      console.log("Hello,my name is "+this.name);
    },100);
  }
}
var weiqi = new Person("卫旗");
weiqi.getName();  
//Hello,my name is pig

       这个时候输出this.name是pig,原因是this的指向是在运行函数时确定的,而不是在定义函数时确定的,再因为setTimeout是在全局环境下只想,所以this就指向了window。

       以前解决这个问题的办法通常是缓存this,例如:

var name = "pig";
function Person(name){
  this.name = name;
  this.getName = function(){
    //在这里缓存一个this
    var self = this;
    setTimeout(function(){
      //在这里是有缓存this的self
      console.log("Hello,my name is "+self.name);
    },100);
  }
}
var weiqi = new Person("卫旗");
weiqi.getName();
//Hello,my name is 卫旗

       这样就解决了这个问题,非常方便,因为它使得setTimeout函数中可以访问Person的上下文。

       现在有一个更好的解决办法,可以使用bind()函数,上面的例子可以被更新为:

var name = "pig";
function Person(name){
  this.name = name;
  this.getName = function(){
    setTimeout(function(){
      console.log("Hello,my name is "+this.name);
    }.bind(this),100);
    //注意上面这一行,添加了bind(this)
  }
}
var weiqi = new Person("卫旗");
weiqi.getName();
//Hello,my name is 卫旗

       bind()最简单的用法是创建一个函数,使得这个函数无论怎么样调用都拥有同样的this值。JavaScript新手经常犯的一个错误就是将一个方法从一个对象中拿出来,然后再调用,希望方法中的this是原来的对象(比如在回调函数中传入这个方法)。如果不做特殊处理的话,一般会丢失原来的对象。从原来的函数和原来的对象创建一个绑定函数,则可以很漂亮的解决这个问题:

//定义全局变量x
var x = "window";
//在module内部定义x
var module = {
  x:"module",
  getX:function(){
    console.log(this.x);
  }
}
module.getX(); 
//返回module,因为在module内部调用getX()

var getX = module.getX;
getX();
//返回window,因为这个getX()是在全局作用域中调用的

//绑定getX()并将this值设为module
var boundGetX = getX.bind(module);
boundGetX();
//返回module,绑定以后this值始终为module

浏览器支持情况:

Browser Version support
Chrome 7
FireFox(Gecko) 4.0(2)
Internet Explorer 9
Opera 11.60
Safari 5.14

       很不幸,Function.prototype.bind在IE8及以下版本中不被支持,所以如果没有一个备选方案的话,可能会在运行时出现问题。bind函数在ECMA-262第五版才被加入。它可能不无法在所有浏览器上运行。你可以在脚本部分加入如下代码,让不支持的浏览器也能使用bind()功能。

if (!Function.prototype.bind) {
 Function.prototype.bind = function (oThis) {
  if (typeof this !== "function") {
   // closest thing possible to the ECMAScript 5 internal IsCallable function
   throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
  }

  var aArgs = Array.prototype.slice.call(arguments, 1), 
    fToBind = this, 
    fNOP = function () {},
    fBound = function () {
     return fToBind.apply(this instanceof fNOP && oThis
                 ? this
                 : oThis || window,
                aArgs.concat(Array.prototype.slice.call(arguments)));
    };

  fNOP.prototype = this.prototype;
  fBound.prototype = new fNOP();

  return fBound;
 };
}

语法

    fun.bind(thisArg[, arg1[, arg2[, …]]])

参数

       thisArg,当绑定函数被调用时,该参数会作为原函数运行时的this指向,当使用new操作符调用绑定函数时,该参数无效。

       arg1, arg2, …,当绑定函数被调用时,这些参数加上绑定函数本身的参数会按照顺序作为原函数运行时的参数。

描述

       bind()函数会创建一个新的函数(一个绑定的函数)有同样的函数体(在ECMAScript 5 规范内置Call属性),当该函数(绑定函数的原函数)被调用时this值绑定到bind()的第一个参数,该参数不能被重写。绑定函数被调用时,bind()也接受预设的参数提供给原函数。一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。提供的this值被忽略,同事调用的参数被提供给模拟函数。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

相关文章

  • 关于ES6中的箭头函数超详细梳理

    关于ES6中的箭头函数超详细梳理

    箭头函数可以说是es6的一大亮点,使用箭头函数,可以简化编码过程,是代码更加的简洁,下面这篇文章主要给大家介绍了关于ES6中箭头函数的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • IE下双击checkbox反应延迟问题的解决方法

    IE下双击checkbox反应延迟问题的解决方法

    这篇文章主要介绍了IE下双击checkbox反应延迟问题的解决方法,需要的朋友可以参考下
    2014-03-03
  • 对于JavaScript继承你到底了解多少

    对于JavaScript继承你到底了解多少

    js的继承机制不同于传统的面向对象语言,采用原型链实现继承,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法,下面这篇文章主要给大家介绍了关于JS继承的相关资料,需要的朋友可以参考下
    2021-09-09
  • js操作浏览器的参数方法

    js操作浏览器的参数方法

    下面小编就为大家带来一篇js操作浏览器的参数方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • 深入理解Javascript作用域与变量提升

    深入理解Javascript作用域与变量提升

    这篇文章主要是对Javascript作用域与变量提升进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • js中的闭包实例展示

    js中的闭包实例展示

    闭包是js中的一大特色,也是一大难点。下面这篇文章主要给大家介绍了关于js中闭包的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用js具有一定的参考学习价值,需要的朋友们下面来一起看看吧
    2018-11-11
  • JavaScript代码实现左右上下自动晃动自动移动

    JavaScript代码实现左右上下自动晃动自动移动

    最近几天做了一个项目,原来是用css3动画做的,由于不兼容IE,改成用js做了,特此分享给大家,供大家参考
    2016-04-04
  • 小程序websocket心跳库(websocket-heartbeat-miniprogram)

    小程序websocket心跳库(websocket-heartbeat-miniprogram)

    这篇文章主要介绍了小程序websocket心跳库(websocket-heartbeat-miniprogram),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • 微信小程序自定义底部导航栏组件

    微信小程序自定义底部导航栏组件

    这篇文章主要为大家详细介绍了微信小程序自定义底部导航栏组件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 使用JavaScript遍历输出页面中的所有元素的方法详解

    使用JavaScript遍历输出页面中的所有元素的方法详解

    在前端开发中,遍历页面中的所有元素是一个常见需求,无论是调试、页面分析,还是获取元素信息,都会用到遍历 DOM 树的操作,本文将介绍如何通过 JavaScript 编写一个方法,遍历并输出页面中的所有元素,需要的朋友可以参考下
    2024-12-12

最新评论