Js中的bind()方法


引子

第一次看到 bind() 这个方法,我就直接想起了 jQuery 的 bind ,当然是早期低版本中的,但显然,这里要讲的这个并非 jQuery 的,这个 bind() 方法是在 js1.8 之后引进的,我也是在看 PouchDB 实现的 Todo-list 的demo的代码时看到,当时很不解,所以就开始找寻是怎么应用的道路。

问题的来源

承上,Todo-list 的demo中有好多处用到,我列举一处:

// 这里有一个helper函数
function todoKeyPressed(todo, event) {
    if (event.keyCode === ENTER_KEY) {
        var inputEditTodo = document.getElementById('input_' + todo._id);
        inputEditTodo.blur();
    }
}  
// 调用如下,给一个DOM元素设置监听器,并且通过bind进行参数绑定
inputDom = document.getElementById('input');
inputDom.addEventListener('keypress', todoKeyPressed.bind(this, todo));

上面代码就是监听到 keypress 事件的时候,触发上面定义的 todoKeyPressed(todo, event) 方法,但是通过 bind() 给进去的只有第一个参数,第二个参数 event 怎么去找呢??

问题的探究

我有墙裂的预感,这个肯定是跟参数 arguments 有关的,但是它具体是相关在哪里呢,于是我一顿搜索呀,终于让我给找到有用这个 bind() 的了。灵感来源 以及 这里
最主要的还是自己得有探究精神,还是看到了这个例子,才恍然大悟的感觉,下面的例子虽然简单,但却是能够体会精髓的:

var f=function(a,b){
  alert(this); //1
  alert(a); //2
  alert(b); //3
}.bind(1,2);

f(3);

回到原题

通过类比上面简单的例子,回到原来的问题中,我们可以细分来看:

  • 监听器中是一个回调,正常的监听器是这样的:addEventListener('keypress', function(event) { });
  • 那么这里不是用匿名函数的方法,而是用了一个已经事先定义好的函数,如果正常调用应该是这样的: todoKeyPressed(参数1, 参数2, ..., event) ,参数列表里面最后一个是隐含的 event 参数,是最后进来的
  • 而现在前面的两个参数是通过 bind(this, todo) 来进行传参,这就让我忘记了最后有一个 event 参数了,其实是有的
  • 那么综上,this 参数在自定义的函数调用中没有用到,从 todo 开始匹配,还有 event ,两个参数,刚好对应我们自定义的 todoKeyPressed() 函数中需要的两个参数
  • Problem Solved

另外,这里有 bind在低版本IE中的实现

吐槽

最后,感叹一下国内的所谓技术贴吧,你就算是发帖发到死,也没有人会回复的,没有人会回答,所以实在有问题,只有两条路:

  • 1,不断自己找出路
  • 2,还是不断自己摸索(最多到sto上找点解决)

结尾

Js中还亟需理解掌握的几个概念:this, arguments, call/apply,可以参考一下下面几篇文章:

左银右煌 /
Published under (CC) BY-NC-SA in categories programming  tagged with JavaScript