为何无法直接向事件监听器传入额外参数?
事件处理函数传参的问题解析
先看你的基础事件监听器代码:
private _foo(event: KeyboardEvent) { // 处理逻辑 } <div @keydown=${this._foo}>test</div>
你疑惑的是,为什么不能直接给_foo加参数,比如这样写:
<div @keydown=${this._foo(myOtherFunc)}>test</div>
反而必须用匿名函数包裹:
private _foo(event: KeyboardEvent, myOtherFunc: Function) { // 处理逻辑 } <div @keydown=${(event: KeyboardEvent) => this._foo(event, myOtherFunc)}>test</div>
核心原因:函数调用和函数引用的区别
- 当你写
this._foo(myOtherFunc)时,这是立即执行函数——在模板渲染/解析的瞬间就会调用_foo,而不是等到keydown事件触发时才执行。此时@keydown接收到的是_foo的返回值(如果没写return就是undefined),浏览器无法把这个值当成事件处理函数,自然不会在按键时触发你要的逻辑。 - 而匿名函数
(event) => this._foo(event, myOtherFunc)是传递了一个函数引用给@keydown。这个匿名函数不会立即执行,只有当keydown事件触发时,浏览器才会调用它,然后在函数内部再调用_foo,同时把事件对象和你要传的myOtherFunc一起传进去,既保留了事件对象,又实现了自定义参数的传递。
补充:另一种写法——bind
你也可以用bind来实现传参,写法如下:
<div @keydown=${this._foo.bind(this, myOtherFunc)}>test</div>
但要注意,bind会把传入的参数排在事件对象前面,所以_foo的参数顺序需要调整:
private _foo(myOtherFunc: Function, event: KeyboardEvent) { // 处理逻辑 }
不过匿名函数的写法更直观,参数顺序也符合常规的事件处理逻辑,所以更常用。
内容的提问来源于stack exchange,提问作者sal3jfc
相关产品推荐
相关产品推荐

