V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
pinews
V2EX  ›  程序员

JavaScript 这样写,不知道为什么,总觉有点别扭

  •  
  •   pinews · 2019-06-26 13:34:41 +08:00 · 4646 次点击
    这是一个创建于 2011 天前的主题,其中的信息可能已经有所发展或是发生改变。
    if (xxx) {
    ele.onclick = funA;
    } else {
    ele.onclick = funB;
    }

    总感觉哪里有问题。
    第 1 条附言  ·  2019-06-26 14:28:36 +08:00
    我指的是 onclick 还能变来变去,总感觉应该是唯一的。
    33 条回复    2019-06-27 15:49:06 +08:00
    yxcoder
        1
    yxcoder  
       2019-06-26 13:45:23 +08:00
    xxx?funA:funB
    jowan
        2
    jowan  
       2019-06-26 13:47:23 +08:00
    ele.onclick = () => {
    fn(xxx);
    }
    sutang
        3
    sutang  
       2019-06-26 13:54:17 +08:00   ❤️ 4
    ele.onclick = xxx ? funA : funB
    azh7138m
        4
    azh7138m  
       2019-06-26 14:00:29 +08:00
    没有缩进肯定别扭。
    Mitt
        5
    Mitt  
       2019-06-26 14:01:15 +08:00 via iPhone
    能用语法糖解决的问题都不是问题,"编译器"可以帮你优化掉的
    zjsxwc
        6
    zjsxwc  
       2019-06-26 14:10:48 +08:00
    function Condition1(){/*do sth when condition1*/}
    function Condition2(){/*do sth when condition2*/}

    xxx = "Condition1";
    ele.onclick = window[xxx];
    uxstone
        7
    uxstone  
       2019-06-26 14:33:37 +08:00
    动态类型嘛 习惯就好
    tinycold
        8
    tinycold  
       2019-06-26 14:35:43 +08:00   ❤️ 1
    你的直觉是对的,对一个 DOM 元素动态地绑定 /移除事件监听是很蠢的事情,编译器到底能不能优化到那一步我不知道,不过你的同事肯定是还没优化到那个地步。

    如果你实在是有这么两个函数要重用,这个代码会写成:
    ```
    el.onclick = clickHandler

    // clickHandler
    if (xxx) {
    funA()
    } else {
    funB()
    }
    ```
    banricho
        9
    banricho  
       2019-06-26 14:36:26 +08:00   ❤️ 2
    写的什么鬼……

    ```JS
    const fnA = () => {}
    const fnB = () => {}
    const handle = () => {
    isA ? fnA() : fnB()
    }

    ele.addEventListener('click', handle)
    ```
    wenzhoou
        10
    wenzhoou  
       2019-06-26 14:42:19 +08:00 via Android
    @tinycold 这两种写法明显不等价。
    tinycold
        11
    tinycold  
       2019-06-26 14:45:17 +08:00
    @wenzhoou 我理解的「等价」是运行结果一样,不知道你说的「等价」是哪一层意思。
    pinews
        12
    pinews  
    OP
       2019-06-26 14:45:44 +08:00
    @wenzhoou 是的,当 click 发生的时候,xxx 判断的结果可能已经变了
    hackfly
        13
    hackfly  
       2019-06-26 14:45:53 +08:00
    函数在 js 属于第一类值,和 c 之类的有点不一样
    no1xsyzy
        14
    no1xsyzy  
       2019-06-26 14:49:36 +08:00
    Qt 信号槽,handler 就是可以变的,甚至两个的。
    no1xsyzy
        15
    no1xsyzy  
       2019-06-26 14:52:26 +08:00   ❤️ 2
    @pinews #12 也有可能需要保留那时的判断结果
    单独存一个变量不如还是直接传函数。

    不过如果这些个 funA funB 还会在其他地方用,我想还是存变量好,方便调试,知道是点击事件触发的。
    pinews
        16
    pinews  
    OP
       2019-06-26 15:09:28 +08:00
    @no1xsyzy 感谢,解答了我的疑惑
    2kCS5c0b0ITXE5k2
        17
    2kCS5c0b0ITXE5k2  
       2019-06-26 15:25:13 +08:00
    ele.onclick: (() => {
    if(xxx) {
    funA()
    } else {
    funB()
    }
    })
    lraining
        18
    lraining  
       2019-06-26 15:27:25 +08:00 via Android
    onclick 本质上是一个函数指针,直接指定函数指针或者在一个函数中指定,两者没有本质上的差别,但是有的时候给 onclick 赋值的时候要去掉之前的赋值,否则有可能 onclick 会指向多个函数
    markyun
        19
    markyun  
       2019-06-26 16:51:18 +08:00
    // handleClick
    let handleClick;
    if (field === 'a') {
    handleClick = () => {
    this.a(row);
    };
    } else if (field === 'b') {
    handleClick = () => {
    this.b(row);
    };
    }
    learnshare
        20
    learnshare  
       2019-06-26 17:07:17 +08:00
    理论上不建议 onclick,因为只能关联一个函数。应该是

    target.addEventListener('click', () => {
    xxx ? funA : funB;
    });
    tofishes
        21
    tofishes  
       2019-06-26 17:20:01 +08:00
    你对 if-else 是不是有什么误解?两个条件分支是不假,但同时只会执行其中一条分支,只执行一条分支的话,哪里来的变来变去?

    ok,就算变来变去,同一个元素的 onclick 被覆盖一下不行么,跟变量重新赋值一样,有什么不能接受的?
    mooncakejs
        22
    mooncakejs  
       2019-06-26 17:23:26 +08:00
    没问题啊,上面给 ternary 的,感觉还不如 if
    mooncakejs
        23
    mooncakejs  
       2019-06-26 17:23:50 +08:00
    不过确实 onclick 不如 addEventListener,逻辑可以在两个里面实现
    libook
        24
    libook  
       2019-06-26 17:30:27 +08:00
    不如试试在内部判断分流?

    ele.onclick = ()=>{
    if(xxx) _funcA() else _funcB();
    };
    Trim21
        25
    Trim21  
       2019-06-26 17:45:04 +08:00 via iPhone
    onclick 这里只被赋值了一次 也没有变来变去的啊
    overflow99
        26
    overflow99  
       2019-06-26 18:32:45 +08:00
    这样写不合理,函数有声明提升,建议把判断卸载函数里
    aleen42
        27
    aleen42  
       2019-06-26 22:00:58 +08:00 via Android
    小心點,可能會內存洩漏
    Sparetire
        28
    Sparetire  
       2019-06-27 01:33:55 +08:00 via Android
    楼上一群说不合理,讲道理合不合理也要具体情况具体分析吧,这里 if 写里面和写外面明显不等价,而如果 if 的判断条件 xxx 是一个开销很大的函数调用,写外面甚至还算得上是一个小优化
    jingyulong
        29
    jingyulong  
       2019-06-27 02:33:28 +08:00 via iPhone
    if 里面写函数怪怪的,感觉哪里有问题
    Mutoo
        30
    Mutoo  
       2019-06-27 06:58:23 +08:00
    1) 函数在 JS 里是第一公民( first class ),与变量可以被赋值传递。
    2) onclick 是 DOM LEVEL 0 的事件机制,非常原始。如果开发现代应该建议直接上 DOM LEVEL 3 的事件机制 dom.addEventListener()
    dzm
        31
    dzm  
       2019-06-27 09:54:45 +08:00
    还没这样写过 onclick...总感觉这样写有点理解障碍?
    purelanren
        32
    purelanren  
       2019-06-27 11:43:01 +08:00
    前提:这个判断应该是个业务逻辑,业务逻辑是客观存在的,这个判断是难以避免的
    所以这个判断不是以现在的写法,就是统一写在一个函数里面,在新的函数里面进行判断

    那么就要分两种情况:
    1. 这段代码是需要多次执行的,那些外面和写里面性能没区别
    2. 这段代码是一次性执行的,那写在外面在性能上而言甚至优于写里面

    至于 onClick 还是 addEventListener,看业务情况:
    1. 需要兼容 ie 较低版本,或者这个 dom 只需要绑定一个 click 回调,onClick 无疑是最方便的,既不需要兼容也不需要在再次绑定时卸载事件
    2. 多个点击回调,肯定用 addEventListener,不过就上面这段代码已经存在而言,应该不是这类情况

    结论:目前业务逻辑下没啥问题,但是你改成自己喜欢的写法也没问题。只能说对业务和性能没啥产出,不过自己维护的代码让自己舒服这点很重要~
    meepo3927
        33
    meepo3927  
       2019-06-27 15:49:06 +08:00
    好久不写 onclick 了, 都是 addEventListener 或者 attachEvent
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5438 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 08:40 · PVG 16:40 · LAX 00:40 · JFK 03:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.