汐辰  +

理解bind()

简介

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

语法

    fun.bind(thisObj[, arg1[, arg2[, ...]]])

参数

thisObj:当新的function被调用时,thisObj会赋给其this值。如果使用new操作符调用function,则会忽略thisObj.

arg1,arg2...:当新的 Function 被调用时,当作参数列表传入,插入在调用时实际参数之前。

示例一:创建一个绑定函数

    var first_object  = {
        num: 15 
    };
    var second_object = {
        num: 20
    };
    function multiply(mult) {
        return this.num * mult;
    }
    /**bind内部
    function.prototype.bind = function(){
        var that = this,
        temp = function(){
            return that.apply(obj,arguments);
    }
    return temp;
    } 
    */
    var first_multiply = multiply.bind(first_object);
    first_multiply(6); //return 15*6
    var second_multiply = multiply.bind(second_object);
    second_multiply(8);//return 20*8


实例二(from MDN)

var x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 81

var getX = module.getX;
getX(); // 9, because in this case, "this" refers to the global object

// create a new function with 'this' bound to module
var boundGetX = getX.bind(module);
boundGetX(); // 81

使用bind实现currying

那就简单写一个货币转换函数吧

    
function converter(toUnit, factor, input) {
   return[(input*factor).toFixed(2),toUnit].join(" ");
}
var RMBToJPY = converter.bind(undefined,"yen",16.481);
var RMBToUSD = converter.bind(undefined,"dollar",0.163);

RMBToJPY(15);//return "247.22 yen"
RMBToUSD(15);//return "2.45 dollar"

    

使用setTimeout

setTimeout中的this指向问题 先看简化的例子:

function Foo(){
    
    var that = this;
    setTimeout(that.bar,2000);//延迟后下面的this就指向window了,这样就无法引用类里面其他的原型了。
}

foo.prototype= {
    bar:function(){
    var _this = this; //这里的this指向window,在里面无法引用类的原型的函数
}
}

var foo = new Foo();
    

那么可以用bind来绑定this

function Foo(){
    var that = this;
    setTimeout(this.bind(this,this.bar),2000);
}

Foo.prototype={
    bar:function(){
    var _this=this;//这里的this就是指向Foo这个类,可以正常使用类里面的方法了
}
}

结论

bind()函数可以巧妙地运用于很多不同的用途,同时可以精简现有代码,但是在浏览器支持方面,IE9之前的版本还不支持,所以要考虑之前的版本还得用其他的方法。

Blog

Opinion

Extract

Fork me on GitHub