V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
qaqLjj
V2EX  ›  问与答

关于前端的闭包和事件解绑问题

  •  
  •   qaqLjj · 2020-05-18 22:11:24 +08:00 · 780 次点击
    这是一个创建于 1679 天前的主题,其中的信息可能已经有所发展或是发生改变。

    add,remove 这两个闭包访问的 hide 函数为什么不是同一个函数呢,
    正因为不是同一个函数,导致事件解绑失败了。
    求高手指教


    -------借助全局变量 addHide 保存调用 add 时访问的 hide ,代码如下-------

    let addHide = null
    
    function clickListener() {
      function hide() {
        console.log('hide exc')
      }
    
      function add() {
        addHide = hide
        document.addEventListener('click', hide, false)
      }
    
      function remove() {
        console.log(hide === addHide);
        document.removeEventListener('click', hide, false)
      }
    
      return {
        add,
        remove
      }
    }
    
    clickListener().add()
    clickListener().remove()
    
    xxx749
        1
    xxx749  
       2020-05-18 22:24:55 +08:00
    你这代码跑了两次,所有 hide 函数也声明了两次,你把 clickListener 函数的返回值赋值给变量再试一次就相等了
    xxx749
        2
    xxx749  
       2020-05-18 22:25:56 +08:00
    @xxx749 #1 所有 -> 所以
    qaqLjj
        3
    qaqLjj  
    OP
       2020-05-18 22:28:47 +08:00
    @xxx749 你说的对,我发完问题也看出来了,执行一次就创建了一个新的闭包
    rabbbit
        4
    rabbbit  
       2020-05-18 22:29:18 +08:00
    const {add, remove} = clickListener()
    add()
    remove()
    SoloCompany
        5
    SoloCompany  
       2020-05-18 23:17:48 +08:00
    这种问题很常见也是无解的

    如果闭包不保证单例, 一般的解决方案是增加名称空间
    add: $(document).on('click.moduleHash', hide)
    remove: $(document).off('click.moduleHash')
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   986 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:31 · PVG 02:31 · LAX 10:31 · JFK 13:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.