Javascript高级技巧系列--函数绑定bind

515

函数绑定 要创建一个函数,可以在特定的 this 环境中以指定参数调用另一个函数。该技巧常常和回调函数与事件处理程序一起使用,以便在将函数作为变量传递的同时保留代码执行环境.

关于this,需要再开一个系列总结一下哦~

如下示例:

 var handler = {
        message: "Event handled",
        handleClick: function(event){
            alert(this.message);
        } 
 };
 document.getElementById("my-btn").addEventListener("click", handler.handleClick)
 // 点击"my-btn" this.message为undefined
 

上述示例中,由于没有保存 handler.handleClick()的环境,所以 this 对象最后是指向了 DOM 按钮而非 handler(在 IE8 中, this 指向 window。)

那么怎么修改呢?

// 在调用时,使用闭包,增加一个匿名函数,在闭包内调用handler.handleClick
 document.getElementById("my-btn").addEventListener("click", function(){
     handler.handleClick() // this.message为Event handled
 })

通常情况下,频繁使用匿名函数,会导致代码不易于维护。因此,很多js库维护了一个将函数绑定到指定环境中执行的函数,通常叫bind

function bind(fn, context){
        return function(){
            return fn.apply(context,args)
        }
}

这个函数似乎简单,但其功能是非常强大的。在 bind()中创建了一个闭包,闭包使用 apply()调用传入的函数,并给 apply()传递 context 对象和参数。注意这里使用的 arguments 对象是内部函数的,而非 bind()的。当调用返回的函数时,它会在给定环境中执行被传入的函数并给出所有参数。

使用方式:

document.getElementById("my-btn").addEventListener("click", bind(handler.handleClick,  handler)

其实,ECMAScript 5为所有函数定义了一个原生的 bind()方法(浏览器有 IE9+Firefox 4+Chrome),进一步简单了操作。换句话说,你不用 再自己定义 bind()函数了,而是可以直接在函数上调用这个方法.

document.getElementById("my-btn").addEventListener("click", handler.handleClick.bind(handler)

注意:被绑定的函数,开销要大于普通函数,非必要情况下,还是不要使用的好哟~