JS 的&&和||在语句中的用法请教 - V2EX
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 8977 次点击
    这是一个创建于 2756 天前的主题,其中的信息可能已经有所发展或是发生改变。

    ##最近正在学 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 刚刚搞懂了。。。这种写法除了图省事炫技外有弊端吗?
    AV1
        5
    AV1  
       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 语句。如根据是否传入回调来判断是否需要执行回调:
    funcion(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
    一个成语能搞定的事情,非要别人用一段话来描述,到底是谁的问题?
    AV1
        52
    AV1  
       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     Solana     1025 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 18:32 PVG 02:32 LAX 11:32 JFK 14:32
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86