jQuery事件绑定语法差异:为何Button2可识别this而Button3为undefined
核心差异来自JavaScript的this传递规则,和jQuery的click()与.on()方法本身无关
首先要明确jQuery的事件绑定默认行为:不管是用on()还是它的简写click(),只要你直接把处理函数作为参数传入绑定方法,jQuery触发事件时都会手动把回调函数的this指向被绑定的DOM元素本身,这也是Button2能正常识别this的根本原因。
逐行拆解各个按钮的绑定逻辑差异:
- Button1用原生
addEventListener绑定,完全遵循DOM事件的规则:事件触发时,回调函数的this直接指向绑定事件的DOM节点,所以handleThis1内部能正常读取到this.id - Button2是把
handleThis1直接作为on('click')的回调传入的,jQuery触发回调时自动把this绑定到#button2节点,自然能正确输出按钮ID - Button3的问题完全出在回调的写法上:你传给
click()的根本不是handleThis1本身,是一层你自己写的匿名函数。
这里要注意:jQuery确实会把这个外层匿名函数的this指向#button3,但你在匿名函数内部调用handleThis1(event)的时候,用的是最普通的独立函数调用模式。按照JavaScript的this规则,独立函数调用时,函数内部的this不会自动继承外层作用域的this——非严格模式下会指向全局window对象,而window本身没有id属性,所以你看到日志里输出的This: undefined,本质是读取this.id得到了undefined,和你描述的现象完全吻合。 - Button4之所以能正常工作,是因为你在匿名函数里没有依赖隐式的this传递,而是主动把匿名函数自己的this(也就是jQuery绑定的
#button4节点)作为参数显式传给了handleThis2,完全绕开了this指向的问题。
如果你想让Button3也能正常读取this,只需要补全this的传递链路即可,常见写法有两种:
- 去掉多余的包裹层,直接把
handleThis1作为回调传入,和Button2的逻辑完全一致:$("#button3").click(handleThis1) - 保留包裹层的匿名函数,在内部调用时用
call/apply把当前的this显式传给处理函数:$("#button3").click(function (event) { handleThis1.call(this, event) })
这里的认知误区需要澄清:你之前了解到的“click()是.on('click', handler)的简写,二者行为一致”这个结论本身是正确的,但二者表现出的行为差异,从来都不是绑定方法自带的,而是你传给方法的回调函数的写法、this传递方式不同导致的,和用哪个绑定方法没有关系。
内容的提问来源于stack exchange,提问作者Adam Sassano
相关产品推荐
相关产品推荐

