search

Home  >  Q&A  >  body text

javascript - js三元运算式中的中括号[]有什么语法意义?

看到前同事的一段代码:

var st = $("#idA");
$("#idB").val() == "1" ? st.removeClass("hide") : [st.addClass("hide")][st.val("")];

虽然我也喜欢用js三元运算式,但后面这个用中括号括起来的语法还是第一次见,网上查了很久,最接近的答案也不过是在一篇文章里说到“JavaScript中括号有四种语义”:

语义1,声明数组
语义2,取数组成员
语义3,定义对象成员(可以不遵循标识符规则)
语义4,取对象成员

但我却依然很困惑:按照这四个语义解释,也就是中括号里面的都是数组或对象,但我上面的代码里,中括号里的明明是语句呀。求高手指导!

PHP中文网PHP中文网2819 days ago606

reply all(8)I'll reply

  • 迷茫

    迷茫2017-04-10 16:56:52

    这段代码很糟糕,一定要避免这样写。

    但是,并没有任何神奇的。

    [st.addClass("hide")][st.val("")];

    这一条语句,等价于下面两条语句

    st.addClass("hide");
    st.val("");

    他用这种少见的方式强行把两个表达式合并成一个表达式,为的就是能够塞进三元运算符的第三个操作数位置。

    正如@kikong说的,用逗号表达式也一样。

    至于你问有什么语法意义:

    [expression1][expression2]

    第一个中括号是“Array Initialiser”,说白了就是数组字面量,用来定义一个数组。
    第二个中括号是“Property Accessor”,也就是用来访问对象的属性(包括数组的元素)。

    以上两种情况下,都会首先计算中括号中的表达式的值。你的代码并不是为了得到一个值,而是利用了求值过程中产生的副作用。

    所以,这段代码逻辑上没有问题,但千万不可模仿。

    reply
    0
  • 阿神

    阿神2017-04-10 16:56:52

    [st.addClass("hide")][st.val("")]
    ^语义1               ^语义2
    

    和三元运算没关系。就是把st.addClass("hide")st.val("")各求值一次,结果固定为undefined

    但是这样写没啥意义。。用三元运算符一般是图它会返回一个表达式的值。如果根本不需要那个值,直接if() {} else { st.addClass().val(); }要清晰得多

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 16:56:52

    效果和如下代码相同

    var p=(1==2?2:(a=2,c=3));

    (a=2,c=3)表达式会在前面条件为false时被执行
    a为2
    c为3
    p为3

    问题中的表达式
    [st.addClass("hide")][st.val("")]也会在$("#idB").val() == "1"时被执行,st.addClass("hide")先被执行,st.val("")后被执行,然后[][]整个属性取值表达式被执行

    reply
    0
  • PHPz

    PHPz2017-04-10 16:56:52

    没想到别的更好的解释。或者说这本来就是一段不太好代码。

    这里还是数组。 最后那一段其实就是这样的 [1,2,3][1] 结果为2
    对于你的,就是这样的[obj][obj] 结果是undefined

    reply
    0
  • 高洛峰

    高洛峰2017-04-10 16:56:52

    我从没见过这种写法。。。不过括号里面不是语句,是个对象(如果用的是jq的话)。。。

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-10 16:56:52

    var st = $("#idA");
    $("#idB").val() == "1" ? 
        st.removeClass("hide") : 
        [st.addClass("hide")][st.val("")];

    分析

    1. st.addClass("hide")返回的是一个jQuery对象(addClass文档),因此[st.addClass("hide")]获得一个jQuery数组(根据语义3),这里定义var st1 = [st.addClass("hide")]

    2. st.val("")因为val接受了一个字符串参数,因此该方法返回的也是一个jQuery对象。令var st2 = st.val("")(val(string)文档)。

    3. 原式简化为st1[st2]。也就相当于是把jQuery对象当做数组,用另外一个jQuery对象来取数组下标。需要将st2强制转换为number类型。JQuery对象

    4. jQuery没法转换为number。

    结论

    感觉这段代码有问题。

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-10 16:56:52

    这种写法很没有必要,这样代码可理解性不好,不够直观

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-10 16:56:52

    只是为了满足三元运算的格式而已,没什么意义,而且可读性太差

    reply
    0
  • Cancelreply