V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
Daoma
V2EX  ›  JavaScript

JS 的&&和||在语句中的用法请教

  •  
  •   Daoma · 2018-03-25 09:28:18 +08:00 · 8295 次点击
    这是一个创建于 2195 天前的主题,其中的信息可能已经有所发展或是发生改变。

    ##最近正在学 JS,找了点练习来做,然后看到如下的代码:
    for (var i = 0; i < oBtn.length; i++)
    {
    oBtn[i].index = i;
    oBtn[i].onclick = function ()
    {
    this.index == oBtn.length - 1 && (oDiv.style.cssText = "");
    changeStyle(oDiv, oAtt[this.index], oVal[this.index]);
    }
    }
    然后我上网搜了一下明白了 var c=a||b;这种情况时
    a && b :如果执行 a 后返回 true,则执行 b 并返回 b 的值;如果执行 a 后返回 false,则整个表达式返回 a 的值,b 不执行。和
    a || b :如果执行 a 后返回 true,则整个表达式返回 a 的值,b 不执行;如果执行 a 后返回 false,则执行 b 并返回 b 的值。

    但还是不明白这句 this.index == oBtn.length - 1 && (oDiv.style.cssText = "");怎么操作的 index ???萌新望大佬解答

    57 条回复    2018-03-27 10:13:05 +08:00
    whileFalse
        1
    whileFalse  
       2018-03-25 09:33:09 +08:00   ❤️ 4
    这种炫技代码是需要被狠狠修理的。
    aa6563679
        2
    aa6563679  
       2018-03-25 09:37:11 +08:00 via iPhone   ❤️ 1
    js 其实不管什么东西都能往判断语句里塞。那段代码等同与 if(this.index == oBtn.length - 1){
    oDiv.style.cssText = "";
    }
    Daoma
        3
    Daoma  
    OP
       2018-03-25 09:50:43 +08:00
    @aa6563679 噢噢,我明白了!
    Daoma
        4
    Daoma  
    OP
       2018-03-25 09:51:53 +08:00
    @whileFalse 刚刚搞懂了。。。这种写法除了图省事炫技外有弊端吗?
    DOLLOR
        5
    DOLLOR  
       2018-03-25 10:01:07 +08:00 via Android
    短路求值
    gam2046
        6
    gam2046  
       2018-03-25 10:16:36 +08:00   ❤️ 2
    反正我觉得这样的写法并不好,除了提升逼格,毫无意义。因为令人更难理解了。常见的写法还有

    foo = a || b

    a 和 b 都是一个对象,表达的意思就是
    if( typeof(a) == "undefined"){
    foo = b
    }else{
    foo = a
    }

    也就是说 b 是一定兜底的值,确保 foo 一定被定义了。

    反正自己觉得动态语言真的是写的一时爽,重构火葬场。
    crysislinux
        7
    crysislinux  
       2018-03-25 10:18:54 +08:00
    弊端就是会挨打
    lihongjie0209
        8
    lihongjie0209  
       2018-03-25 10:32:26 +08:00   ❤️ 1
    傻逼写法, 不可取
    mywaiting
        9
    mywaiting  
       2018-03-25 10:35:49 +08:00
    && 相当于 and, || 相当于 or 这样理解就可以了~
    Pastsong
        10
    Pastsong  
       2018-03-25 10:40:36 +08:00
    var a = b && c || d ? e : f
    we2ex
        11
    we2ex  
       2018-03-25 11:02:55 +08:00 via Android
    || 在 ES6 之前经常被作为实现默认参数的 tricky 手段
    vegito2002
        12
    vegito2002  
       2018-03-25 11:56:19 +08:00
    short circuit. 严格来说并不算是炫技了. 上 OS 的时候的 Pintos 系统的源码里面就有这种写法.
    vegito2002
        13
    vegito2002  
       2018-03-25 11:57:35 +08:00
    至于赋值语句直接当成 boolean 来用这个的话, 除了 C 以外的语言确实推荐少用, 是容易被喷.
    watzds
        14
    watzds  
       2018-03-25 12:36:20 +08:00 via Android
    || 在其他语言里也差不多啊,不就是前面不满足就用后面嘛,只是其他语言里要求 bool
    xjp
        15
    xjp  
       2018-03-25 12:42:10 +08:00 via iPhone
    && || 返回的值并不是 boolean
    codermagefox
        16
    codermagefox  
       2018-03-25 13:42:25 +08:00
    @gam2046 说&&炫技我资磁,但是||咋就炫技了?
    不用这个,如何确保自己传值的时候每个字段名都有缺省值?
    raawaa
        17
    raawaa  
       2018-03-25 14:12:12 +08:00   ❤️ 1
    || 不算啥,&& 才比较绕。
    第一次见到 return a && b 的时候我是懵逼的。
    不过弄懂了之后其实也很简单。
    raawaa
        18
    raawaa  
       2018-03-25 14:14:15 +08:00
    其实很简单啊。
    || 是如果前面的结果是 true,就不运行后面的了。
    && 是如果前面的结果是 false,就不运行后面的了。
    许多语言的 boolean 运算不都是这样的嘛。
    lihongjie0209
        19
    lihongjie0209  
       2018-03-25 18:27:19 +08:00
    @raawaa #18 真的简单的话就不需要你去弄懂了, 也不需要你去解释给我们听了
    SoloCompany
        20
    SoloCompany  
       2018-03-25 18:54:21 +08:00 via iPhone
    只要写过 shell 脚本的根本不会存在理解门槛
    wee911
        21
    wee911  
       2018-03-25 20:06:32 +08:00
    这种代码人见人恨,一行代码做两件事情,你是爽,其他都不爽
    noe132
        22
    noe132  
       2018-03-25 20:44:08 +08:00
    写这种代码的人会被下一个接手的维护者掘地三尺
    codehz
        23
    codehz  
       2018-03-25 21:23:21 +08:00
    其实||这种还是可以理解的(如果用于 null 判断,毕竟 js 没有二元的?:/??运算符
    kotokz
        24
    kotokz  
       2018-03-25 21:42:12 +08:00
    short circuit 这种写法能避免尽量避免吧
    多少会导致 cpu 没办法做 branch prediction 优化,从而影响效率
    不是一个好的编程习惯
    kingwl
        25
    kingwl  
       2018-03-25 21:45:40 +08:00 via Android   ❤️ 7
    你们是不是对炫技有什么误解?
    weixiangzhe
        26
    weixiangzhe  
       2018-03-25 21:47:19 +08:00 via iPhone
    我接触的前端 大都这样写啊
    shisang
        27
    shisang  
       2018-03-25 22:01:01 +08:00
    正常写法啊,这有什么不好理解的
    tomychen
        28
    tomychen  
       2018-03-25 22:41:53 +08:00
    同感,很不喜欢这种写法,不是看不明白,而是看到一半的时候要停下来思考一下这是啥意思的时候,那种不连续感,是极其不舒服的。

    而不是所有人都喜欢这种表示法的。
    Hsinchu
        29
    Hsinchu  
       2018-03-26 01:48:00 +08:00 via Android
    我只说一下我写这种代码的场景。var a = b || {},把 b 赋值给 a 但如果 b 为空值 a 赋值为一个空对象,var a = b && b.data,把 b 的属性 data 赋值给 a,但 b 可能为 undefined。这两个场景下这样写可以少写一个几乎没实际意义的 if 语句,我也只在这两种场景下使用&&和||的这个特殊用法,没有炫技成分,就是很实在的减少代码长度。
    congeec
        30
    congeec  
       2018-03-26 02:26:22 +08:00
    楼上有几个写过 shell 的?我还以为搞前端的学了 node.js ,会顺带学一下 shell 啥的呢
    Mutoo
        31
    Mutoo  
       2018-03-26 07:54:27 +08:00
    举一个栗子

    function example(options /*optional*/ ) {
    let paramOne = options && options.p1 || "default";
    ...

    这里 options 为可选参数对象,p1 为可选参数,"default" 为默认值
    witcherhope
        32
    witcherhope  
       2018-03-26 08:03:30 +08:00 via iPhone
    这种用法还是蛮常见的,写 React 组件时候用这个进行短路渲染因为 JSX 不支持 if/else 写法
    uolcano
        33
    uolcano  
       2018-03-26 08:12:26 +08:00 via Android
    @codehz js 里有?: 的,再查查 cheatsheet 吧
    weixiangzhe
        34
    weixiangzhe  
       2018-03-26 08:43:03 +08:00 via iPhone
    所以最新的草案里有
    var a = b?.c
    这种写法了
    KuroNekoFan
        35
    KuroNekoFan  
       2018-03-26 09:32:20 +08:00 via iPhone
    这种算是表达式,有的地方会有用,比如 jsx 里面
    faceRollingKB
        36
    faceRollingKB  
       2018-03-26 09:34:59 +08:00
    我懒,所以经常这么写,比如 this.dispose && this.dispose(),清晰明了
    baixiangcpp
        37
    baixiangcpp  
       2018-03-26 09:58:37 +08:00
    短路求值成了炫技了,我也是服了
    scofieldpeng
        38
    scofieldpeng  
       2018-03-26 10:08:51 +08:00
    楼上那些说炫技的,我真的快笑死了,这种最常见的写法难道一样写一堆 if else ?
    royzxq
        39
    royzxq  
       2018-03-26 10:12:10 +08:00
    是不是对炫技有什么误解。
    codehz
        40
    codehz  
       2018-03-26 10:30:34 +08:00
    @uolcano #33 没有二元?: 就是 gcc 扩展里那种 a ?: b 的写法
    LeungJZ
        41
    LeungJZ  
       2018-03-26 10:35:38 +08:00
    楼上说炫技的,估计不是写前端的吧??

    data.errors = data.unusual ? data.unusual.map(error => ({
    type: errorTypes[error.unusualType],
    record: error['unusualRecord'],
    time: error['unusualTime']
    })) : []

    难道我每次都要用 if else 去校验存在不存在????
    LeungJZ
        42
    LeungJZ  
       2018-03-26 10:42:13 +08:00   ❤️ 1
    @Daoma
    a && b 的意思是,先执行 a 语句,如果执行结果不是假值(不一定必须是 true ),则执行 b 并返回 b 的执行结果。
    多数用于判断 a 是否存在,并执行 b 语句。如根据是否传入回调来判断是否需要执行回调:
    function(cb => {
    // do sth.
    cb && cb(result)
    })
    a || b 的意思是,先执行 a 语句,如果执行结果不是假值(不一定必须是 true ),则直接返回。否则,则执行 b 并返回 b 的执行结果。
    以前多数用来判断是否传参,是否使用默认值。
    function (one, two) {
    one = one || 'one'
    two = two || 'two'
    }
    uolcano
        43
    uolcano  
       2018-03-26 11:26:41 +08:00 via Android
    codehz
        44
    codehz  
       2018-03-26 11:40:57 +08:00
    @uolcano #43 所以你是没看二元这个词吗,用三元运算符要表达同样的意思就得 a ? a : b 不仅看着长而且如果 a 是一个有副作用的求值表达式就会出问题
    GabrielChen
        45
    GabrielChen  
       2018-03-26 12:36:19 +08:00
    这样设置默认值也有 falsy 值问题,这样写比较好
    ES6:
    ```
    function fn(opts = {}) {
    // ...
    }
    ```

    ES5:
    ```
    function fn(opts ) {
    opts = (typeof opts !== 'undefined') ? opts : {};
    //..
    }
    ```
    GabrielChen
        46
    GabrielChen  
       2018-03-26 12:42:27 +08:00
    如果执行 a 后返回 false,则整个表达式返回 a 的值,b 不执行。
    应该为如果执行 a 后返回假值,则整个表达式返回 a 的值,b 不执行,所以用来做默认参数是不安全的

    ```
    var a=undefined ,b=true ; a&&b;
    //=>undefined
    var a=null,b=true ; a&&b;
    //=>null
    var a=0,b=true ; a&&b;
    //=>0
    var a="",b=true ; a&&b;
    //=>""
    var a=false,b=true ; a&&b;
    //=>false
    var a="1",b=true ; a&&b;
    //=>true
    var a=1,b=true ; a&&b;
    //=>true

    ```
    uolcano
        47
    uolcano  
       2018-03-26 12:44:40 +08:00 via Android
    @codehz ?:在语言标准里,不都是三元的么?我是直接忽略了你说的“二元”。你说的 gcc 和 js 本就没有可比性,?: 二元是哪个语言的标准,还是插件支持?比较也要将基本法吧。
    wangcheng
        48
    wangcheng  
       2018-03-26 12:47:38 +08:00
    不要写这样的代码,别人看了会骂的。反正最后要 uglify,何必呢?
    codehz
        49
    codehz  
       2018-03-26 13:27:40 +08:00
    @uolcano #47 都是 C-like 语言,有何不可比较的? 二元 ?: 是 GCC 和 clang 支持的扩展,好多项目里都有使用,目的就是提供类似 Csharp 的那种??的语法(以及单次求值的特性) https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Conditionals.html 我只是随口提了一下,你要较真就看这个链接吧
    SimbaPeng
        50
    SimbaPeng  
       2018-03-26 14:00:31 +08:00
    写个短路求值就要被骂了?还傻逼写法?真是笑喷。最近爬微信公众号的文章,微信 web 端的 js 代码全是这种写法,某些人没那个实力还喜欢喷人装逼,真是醉了。。。
    SimbaPeng
        51
    SimbaPeng  
       2018-03-26 14:01:40 +08:00
    一个成语能搞定的事情,非要别人用一段话来描述,到底是谁的问题?
    DOLLOR
        52
    DOLLOR  
       2018-03-26 14:21:02 +08:00
    知道 JAVA 语法为何啰嗦冗长么?就是因为想加一点方便的语法就被喷成炫技。
    说好的,谁在 JAVA 用 lambda 和 var 谁是小狗。
    grewer
        53
    grewer  
       2018-03-26 15:47:38 +08:00
    这也算炫技? 前端工作 1,2 年后只能算基础写法吧
    当然 && 这种 1 行最多一个,不然可读性太差
    duzhihao
        54
    duzhihao  
       2018-03-26 16:59:16 +08:00
    我也不理解为什么这么写是"炫技",自从用了 react 感觉三元表达式和一元表达式太好用了。阅读起来也没什么障碍
    imn1
        55
    imn1  
       2018-03-26 17:07:08 +08:00
    其实,我不太明白这问题跟&&||有啥关系
    h1367500190
        56
    h1367500190  
       2018-03-26 17:14:56 +08:00
    其它语言中 a ?: b 是正常的写法,到了 JS 里 a || b 就成了炫技,也是佩服一些人的思维
    zhengxiaowai
        57
    zhengxiaowai  
       2018-03-27 10:13:05 +08:00
    JS 中 || 和 && 还算常用,但是有人和我炫 !!'' 我也是比较无语的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5503 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 08:25 · PVG 16:25 · LAX 01:25 · JFK 04:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.