通常情况下,函数或方法的接收者(级绑定到特殊关键字this的值)是由调用者的语法决定性的。特别地,方法调用语法将方法被查找对象绑定到this变量。然而,有时需要使用自定义接收者来调用函数。这时候就需要使用call方法或者bind方法自定义接收者来调用方法
2.4 使用bind方法提取具有确定接受者的方法
由于方法与值为函数的属性没有区别,因此也容易提取对象的方法并提取出函数作为回调函数直接传递给高阶函数。
但这也很容易忘记将提取出来的函数的接受着绑定到该函数被提取出的对象上。
复制代码 代码如下:
var buffer = {
entries: [],
add :function(s){
this.entries.push(s);
}
}
var source = ["867","-","5309"];
source.forEach(butter.add);//error:entries is undefined
这个时候butter.add的接受者不是butter对象。函数的接收者取决于它是如何被调用的,forEach方法在全局作用域中被调用,因此forEach方法的实现使用全局对象作为默认的接收者,由于全局对象中没有entries属性,因此这段代码抛出错误。
forEach方法允许调用者提供一个可选的参数作为回调函数的接收者。
复制代码 代码如下:
var source = ["867","-","5309"];
source.forEach(butter.add,butter);
但并非所有高阶函数都细心周到为使用者提供回调函数的接收者。
解决方法有两种:
1)创建一个显式地一buffer对象方法的方式调用add的封装函数。不管封装函数如何被调用,它总能确保将其参数推送到目标数组中。
复制代码 代码如下:
var source = ["867","-","5309"];
source.forEach(function(s){
butter.add(s);
});
2)函数对象的bind方法需要一个接收者对象,并产生一个以该接收者对象的方法调用的方法调用原来的函数的封装函数。
复制代码 代码如下:
var source = ["867","-","5309"];
source.forEach(butter.add.bind(buffer));
备注
buffer.add.bind(buffer)创建一个新函数而不是修改buffer.add函数:
buffer.add === buffer.add.bind(buffer); //false