绑定函数

课后整理 2020-12-10

绑定函数是为了纠正函数的执行上下文,把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'