JavaScript中removeEventListener取消事件监听的常见陷阱与解决方案

作者:函数茶馆

时间:2026-10-25

浏览:179

本文详解JavaScript中removeEventListener取消事件监听的原理与常见陷阱。重点分析为何匿名函数无法取消监听,以及如何通过封装函数实现带参回调。针对TypeScript中因参数类型不匹配导致的编译报错,提供使用any类型或正确定义可选参数的解决方案,帮助开发者避免内存泄漏和类型错误。

文章目录

addEventListener与回调函数传参限制

首先从addEventListener的使用方式谈起,具体代码如下所示。

onMounted(() => {
    window.addEventListener("click", ()=>{
        doSth(param)//param为参数
    })
})

在addEventListener中,如果直接传入箭头函数作为回调,该箭头函数本身无法直接接收除event以外的参数。若需传递参数,必须在doSth函数内部处理。另一种做法是将箭头函数替换为普通函数,但该函数同样不能带有参数。

onMounted(() => {
    window.addEventListener("click", doSth)//这个doSth就没有参数了
})

如果确实需要让doSth接收参数,可以在函数外部再包裹一层函数来实现。

let doSth1=()=>{
    doSth(param)
}
onMounted(() => {
    window.addEventListener("click", doSth1)//这个doSth1就是外面包装的函数
})

removeEventListener取消监听的引用匹配问题

上述原理同样适用于removeEventListener,但在使用removeEventListener时还有一个关键注意点,详见下文。

onMounted(() => {
    window.addEventListener("click", () => {
        doSth()
    })
})
onUnmounted(() => {
    window.removeEventListener("click", () => {
        doSth()
    })
})

前文提到的写法无法成功取消监听,因为removeEventListener的第二个参数(即回调函数)必须与addEventListener中传入的回调函数是同一个引用,共享内存地址。采用以下写法即可正确执行。

onMounted(() => {
    window.addEventListener("click", doSth)
})
onUnmounted(() => {
    window.removeEventListener("click",doSth)
})

然而,上述写法依然无法直接传递参数。若需传参,仍需在外层包裹一个函数,具体实现如下。

let doSth = (str: string) => {
    console.log(str);
}
let doSth1 = () => {
    doSth("haha")
}
 
onMounted(() => {
    window.addEventListener("click", doSth1)
})
onUnmounted(() => {
    window.removeEventListener("click", doSth1)
})

TypeScript环境下的类型错误与解决方案

如果使用TypeScript,doSth函数的参数可以定义为可选参数,实现方式如下。

let doSth = (str?: string) => {
    if (typeof str == "string") {
        console.log("传参了");
    } else {
        console.log("没传参");
    }
 
}
onMounted(() => {
    window.addEventListener("click", doSth)
})
onUnmounted(() => {
    window.removeEventListener("click", doSth)
})

此时编译器会提示一条错误信息。

显示“没有与此调用匹配的重载”。

第1个重载(共2个):(type: "click", listener: (this: Window, ev: MouseEvent) => any, options?: boolean | AddEventListenerOptions | undefined): void,出现以下错误。

第2个重载(共2个):(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void,出现以下错误。

尽管这样在实际运行中并无问题,但报错信息较为繁琐。若希望避免在外层再包裹一层函数,可以直接将doSth的类型定义为any。

let doSth: any = (str: string) => {
    if (typeof str == "string") {
        console.log("传参了");
    } else {
        console.log("没传参");
    }
 
}
onMounted(() => {
    window.addEventListener("click", doSth)
})
onUnmounted(() => {
    window.removeEventListener("click", doSth)
})

其根本原因目前尚不明确,后续需进一步研究。

总结

至此,关于JavaScript中removeEventListener取消事件监听的讲解结束。如需了解更多相关内容,可搜索本站往期文章或继续浏览相关文章。感谢大家的支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章