看到前同事的一段代码:
var st = $("#idA");
$("#idB").val() == "1" ? st.removeClass("hide") : [st.addClass("hide")][st.val("")];
虽然我也喜欢用js三元运算式,但后面这个用中括号括起来的语法还是第一次见,网上查了很久,最接近的答案也不过是在一篇文章里说到“JavaScript中括号有四种语义”:
语义1,声明数组
语义2,取数组成员
语义3,定义对象成员(可以不遵循标识符规则)
语义4,取对象成员
但我却依然很困惑:按照这四个语义解释,也就是中括号里面的都是数组或对象,但我上面的代码里,中括号里的明明是语句呀。求高手指导!
迷茫2017-04-10 16:56:52
这段代码很糟糕,一定要避免这样写。
但是,并没有任何神奇的。
[st.addClass("hide")][st.val("")];
这一条语句,等价于下面两条语句
st.addClass("hide");
st.val("");
他用这种少见的方式强行把两个表达式合并成一个表达式,为的就是能够塞进三元运算符的第三个操作数位置。
正如@kikong说的,用逗号表达式也一样。
至于你问有什么语法意义:
[expression1][expression2]
第一个中括号是“Array Initialiser”,说白了就是数组字面量,用来定义一个数组。
第二个中括号是“Property Accessor”,也就是用来访问对象的属性(包括数组的元素)。
以上两种情况下,都会首先计算中括号中的表达式的值。你的代码并不是为了得到一个值,而是利用了求值过程中产生的副作用。
所以,这段代码逻辑上没有问题,但千万不可模仿。
阿神2017-04-10 16:56:52
[st.addClass("hide")][st.val("")]
^语义1 ^语义2
和三元运算没关系。就是把st.addClass("hide")
和st.val("")
各求值一次,结果固定为undefined
但是这样写没啥意义。。用三元运算符一般是图它会返回一个表达式的值。如果根本不需要那个值,直接if() {} else { st.addClass().val(); }
要清晰得多
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("")
后被执行,然后[][]整个属性取值表达式被执行
PHPz2017-04-10 16:56:52
没想到别的更好的解释。或者说这本来就是一段不太好代码。
这里还是数组。 最后那一段其实就是这样的 [1,2,3][1]
结果为2
对于你的,就是这样的[obj][obj]
结果是undefined
天蓬老师2017-04-10 16:56:52
var st = $("#idA");
$("#idB").val() == "1" ?
st.removeClass("hide") :
[st.addClass("hide")][st.val("")];
st.addClass("hide")
返回的是一个jQuery对象(addClass文档),因此[st.addClass("hide")]
获得一个jQuery数组(根据语义3),这里定义var st1 = [st.addClass("hide")]
st.val("")
因为val
接受了一个字符串参数,因此该方法返回的也是一个jQuery对象。令var st2 = st.val("")
(val(string)文档)。
原式简化为st1[st2]
。也就相当于是把jQuery对象当做数组,用另外一个jQuery对象来取数组下标。需要将st2强制转换为number类型。JQuery对象
jQuery没法转换为number。
感觉这段代码有问题。