- 绑定函数
bind()最简单的用法是创建一个函数,使这个函数不论怎么调用都有同样的this值。常见的错误就像上面的例子一样,将方法从对象中拿出来,然后调用,并且希望this指向原来的对象。如果不做特殊处理,一般会丢失原来的对象。使用bind()方法能够很漂亮的解决这个问题:
this.num = 9;
var mymodule = {
num: 81,
getNum: function() { return this.num; }
};
module.getNum(); // 81
var getNum = module.getNum;
getNum(); // 9, 因为在这个例子中,"this"指向全局对象
// 创建一个'this'绑定到module的函数
var boundGetNum = getNum.bind(module);
boundGetNum(); // 81
偏函数(Partial Functions)
这是一个很好的特性,使用bind()我们设定函数的预定义参数,然后调用的时候传入其他参数即可:
function list() {
return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]
// 预定义参数37
var leadingThirtysevenList = list.bind(undefined, 37);
var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]
和setTimeout一起使用
一般情况下setTimeout()的this指向window或global对象。当使用类的方法时需要this指向类实例,就可以使用bind()将this绑定到回调函数来管理实例。
function Bloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
// 1秒后调用declare函数
Bloomer.prototype.bloom = function() {
window.setTimeout(this.declare.bind(this), 1000);
};
Bloomer.prototype.declare = function() {
console.log('我有 ' + this.petalCount + ' 朵花瓣!');
};
绑定函数作为构造函数
绑定函数也适用于使用new操作符来构造目标函数的实例。当使用绑定函数来构造实例,注意:this会被忽略,但是传入的参数仍然可用。
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function() {
return this.x + ',' + this.y;
};
var p = new Point(1, 2);
p.toString(); // '1,2'
var emptyObj = {};
var YAxisPoint = Point.bind(emptyObj, 0/*x*/);
// 实现中的例子不支持,
// 原生bind支持:
var YAxisPoint = Point.bind(null, 0/*x*/);
var axisPoint = new YAxisPoint(5);
axisPoint.toString(); // '0,5'
axisPoint instanceof Point; // true
axisPoint instanceof YAxisPoint; // true
new Point(17, 42) instanceof YAxisPoint; // true
捷径
bind()也可以为需要特定this值的函数创造捷径。
例如要将一个类数组对象转换为真正的数组,可能的例子如下:
var slice = Array.prototype.slice;
// ...
slice.call(arguments);
如果使用bind()的话,情况变得更简单:
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);
// ...
slice(arguments);