为何单独引用普通对象方法可执行,调用e.preventDefault却失效?
造成差异的根本原因
核心是JavaScript函数执行时的this绑定规则,以及两个方法对执行上下文的依赖程度完全不同:
- 第一个普通对象示例里的
hi是箭头函数,本身不绑定专属的this,且函数内部逻辑完全没有用到this——执行逻辑只有固定的alert('hi'),和函数挂载在哪个对象上、以什么方式调用没有任何关系。哪怕你把它从对象上摘出来赋值给变量单独调用,执行逻辑不会受任何影响,自然能正常弹出提示。
const obj = { hi: () => alert('hi') } obj.hi() // 'hi' const myMethod = obj.hi myMethod() // 'hi'
- 而
e.preventDefault是浏览器原生挂载在Event原型上的方法,它内部强依赖执行时的this指向当前事件实例:方法需要通过this访问事件对象的内部状态,才能完成「标记阻止默认行为」的逻辑。
当你把方法单独赋值给变量const doNotFollowLink = e.preventDefault时,只是拷贝了函数本身的引用,丢失了和原事件对象e的绑定关系。事件回调运行在严格模式下,直接调用无绑定的doNotFollowLink()时,函数内部的this为undefined,原生方法检测不到合法的Event实例就会直接抛出类型错误,后续的alert语句自然不会执行。
const link = document.querySelector('a') link.addEventListener('click', (e) => { const doNotFollowLink = e.preventDefault doNotFollowLink() // 此处因this丢失抛出错误 alert('this line was never reached') })
对应的HTML示例:
<a href="https://google.com">Click here</a>
如果需要把preventDefault摘出来单独调用,手动绑定上下文即可正常运行:
const doNotFollowLink = e.preventDefault.bind(e) doNotFollowLink() // 等效于e.preventDefault()
内容的提问来源于stack exchange,提问作者Anton Arbus
相关产品推荐
相关产品推荐

