绑定函数是为了纠正函数的执行上下文,把this绑定到指定对象上,避免在不同执行上下文中调用函数时,this指代的对象不断变化。
【实现代码】
function bind(fn, context) { //绑定函数
return function() {
return fn.apply(context, arguments); //在指定上下文对象上动态调用函数
};
}
bind()函数接收一个函数和一个上下文环境,返回一个在给定环境中调用给定函数的函数,并且将返回函数的所有的参数原封不动地传递给调用函数。
注意,这里的arguments属于内部函数,而不属于bind()函数。在调用返回的函数时,会在给定的环境中执行被传入的函数,并传入所有参数。
【应用代码】
函数绑定可以在特定的环境中为指定的参数调用另一个函数,该特征常与回调函数、事件处理函数一起使用。
<button id="btn">测试按钮</button>
<script>
var handler = { //事件处理对象
message : 'handler', //名称
click : function(event) { //事件处理函数
console.log(this.message); //提示当前对象的message值
}
};
var btn = document.getElementById('btn');
btn.addEventListener('click', handler.click); //undefined
</script>
在上面示例中,为按钮绑定单击事件处理函数,设计当单击按钮时,将显示handler对象的message属性值。但是,实际测试发现,this最后指向了DOM按钮,而非是handler。
解决方法:使用闭包进行修正。
var handler = { //事件处理对象
message : 'handler', //名称
click : function(event) { //事件处理函数
console.log(this.message); //提示当前对象的message值
}
};
var btn = document.getElementById('btn');
btn.addEventListener('click', function(){ //使用闭包进行修正:封装事件处理函数的调用
handler.click();
}); //'handler'
改进方法:使用闭包比较麻烦,如果创建多个闭包可能会令代码变得难于理解和调试,因此使用bind()绑定函数就很方便。
var handler = { //事件处理对象
message : 'handler', //名称
click : function(event) { //事件处理函数
console.log(this.message); //提示当前对象的message值
}
};
var btn = document.getElementById('btn');
btn.addEventListener('click', bind(handler.click, handler)); //'handler'