引子
第一次看到 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,可以参考一下下面几篇文章:
- 一篇是司徒正美的:javascript的动态this与动态绑定,只能有功夫再看了
- 一篇是 详解 JavaScript 中的 this