理解Function.prototype.bind

原创 2016年08月30日 12:55:41

       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.namepig,原因是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值被忽略,同事调用的参数被提供给模拟函数。

版权声明:本文为博主原创文章,转载时请标注原创地址。

理解 JavaScript 中的 Function.prototype.bind

函数绑定(Function binding)很有可能是你在开始使用JavaScript时最少关注的一点,但是当你意识到你需要一个解决方案来解决如何在另一个函数中保持this上下文的时候,你真正需要的其...

理解javascript的 Function.prototype.bind

当你开始写js代码的时候,函数绑定可能是你要考虑的问题,在函数嵌套里面,怎麽处理上下文的this呢?其实你需要考虑的就是                    Function.prototype.b...
  • ikscher
  • ikscher
  • 2014年12月15日 17:24
  • 900

js关于Function.prototype.bind

bind()方法会创建一个新函数,称为绑定函数。当调用这个绑定函数时,绑定函数会以创建它时传入bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行...

搞懂JavaScript的Function.prototype.bind[译]

搞懂JavaScript的Function.prototype.bind[译] Ben Howdle binding可能是初学Javascript的人最不关心的函数,当你意识到...

Function.prototype.bind、call与apply方法简介

前言前段时间面试遇见一题,题目内容大概是function Parent() { this.prop = 'parent'; }Parent.prototype.get = function()...

JavaScript笔记2--Function.prototype.bind动态绑定函数

对于Function.prototype.bind的解释,我觉得可以这么说:.bind()创建了一个函数,当这个函数在被调用的时候,它里面的 this 关键词会被设置成被传入的参数。下面举例一个使用....

javascritp学习笔记之理解构造器Function.prototype

前言: 本文逻辑稍显混乱,因为当时是自己想来理解这部分概念,调试环境是Google Chrome。 而且这也只是浅显的探讨。 很多知识点,请参考《javascript权威指南》先说prototy...

Object与Function的理解,原型链,prototype与__proto__

1、prototype与__proto var ff=function(){} ff.__proto__==Function.prototype ff.prototype==ff{}; ...

C++中function和bind是如何实现的

  • 2013年10月25日 22:05
  • 6KB
  • 下载

Prototype Function关系图

  • 2013年09月04日 16:22
  • 67KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:理解Function.prototype.bind
举报原因:
原因补充:

(最多只允许输入30个字)