2012-10-29 224 views
0

我有以下代码:了解三元运营商

c.m & 3 || (b |= 2, 
    65 <= a && 90 >= a ? a = 65 
: 48 <= a && 57 >= a ? a = 48 
: b & 1 ? 97 <= a && 122 >= a ? a = 65 
: 197 == a || 229 == a ? b &= 5 
: 192 <= a && 687 >= a ? a = 192 
: 1536 <= a ? a = 1536 
: 912 <= a ? a = 912 
: 160 <= a ? a = 160 
: 127 <= a ? b &= 5 
: 33 <= a ? a = 59 
: b &= 5 
: 48 > a ? b &= 5 
: 65 > a ? a = 59 
: 96 > a ? b &= 5 
: 112 > a ? a = 96 
: 187 > a ? b &= 5 
: a = 59); 

我很困惑,甚至从哪里开始。是||一个二元运算符?为什么在开始时有逗号?我想了解这段代码是如何工作的,并使用常规if,else,any重写它的任何提示?谢谢!

+0

从变量名称看,这看起来像缩小的代码。有没有机会访问原始的非缩减源代码? –

+3

你有一个长横向滚动代码片段,没有人可以遵循。我试图编辑但发现它很困难。 – Lion

+0

首先阅读关于JavaScript中的运算符优先级和关联性。它可以让你分开操作员,建立一个操作树,并清楚地看到什么和什么时候被评估。 '||'是二进制(逻辑或),而'''分隔多个表达式并返回最后一个的值。 –

回答

12

||运算符返回第一个操作数(如果它是真的),否则返回第二个操作数。 &&会做相反的处理:如果它是假的,返回第一个操作数,否则返回第二个操作数。

a ? b : c(function(a) {if(a) return b; else return c;}(a);的简写(不完全是,但这就是主意)。

,运算符评估它的两个操作数并返回第二个操作数。

有了这些想法,上面的代码变成:

if(!(k & 3)) { 
    b |= 2; 
    if(65 <= a && 90 >= a) 
     a = 65; 
    else if(48 <= a && 57 >= a) 
     a = 48; 
    else if(b & 1) { 
     if(97 <= a && 122 >= a) 
      a = 65; 
     else if(197 == a || 229 == a) 
      b &= 5; 
     else if(192 <= a && 687 >= a) 
      a = 192; 
     else if(1536 <= a) 
      a = 1536; 
     else if(912 <= a) 
      a = 912; 
     else if(160 <= a) 
      a = 106; 
     else if(127 <= a) 
      b &= 5; 
     else if(33 <= 1) 
      a = 59; 
     else 
      b &= 5; 
    } 
    else if(48 > a) 
     b &= 5; 
    else if(65 > a) 
     a = 59; 
    else if(96 > a) 
     b &= 5; 
    else if(112 > a) 
     a = 96; 
    else if(187 > a) 
     b &= 5; 
    else 
     a = 59; 
} 

我不能告诉你这是什么意思,但。这只是一堆被检查的数字。 a在多个范围内检查,并设置为特定值或b可能会改变。这对我来说是一个巨大的混乱,它需要上下文才有意义。

+0

很酷,非常感谢很多人,我真的很感激它! – Kristian

+0

+1,用于解决全部写入片段的麻烦。您是否真的自己做过,或者您是否使用过工具/脚本,如果是这样的话:我在哪里可以找到该工具? (我目前正在编写一些代码,看起来似乎是对'if'和'else'有害的人) –

2

双管意味着和双和号意味着
另外,?:语法是if/else的快捷键。

所以

if (a == 3) alert('a is 3') 
else alert('a is NOT 3') 

可以写成像

a == 3 ? alert('a is 3') : alert('a is NOT 3'); 

alert(a == 3 ? 'a is 3' : 'a is NOT 3') 

与单管和符号标志(即可以与一些其它查询操作符,如结合等于 - =),他们是按位运算符,他们不处理直接战争d条件,例如返回布尔值的if (a == 3)等。

需要注意的是,检查值是否未定义时也可以使用双管道。所以它显然将类型转换为布尔类型。这是一个例子。

// note that val is not defined yet 
var val = num || 0; 
// so val will be assigned 0. same as: 
if (typeof num == 'undefined') val = 0; 
else val = num; 
+0

感谢您的解释! – Kristian

+1

没问题。不要忘记,为了准确,您可能需要在多个三元运算符中使用括号。 – inhan

2

此代码是可怕,有没有其他的字。这似乎是一些混淆器的结果。我知道你想知道这段代码是如何工作的,但是混淆代码的重点在于它要么是不可能的,要么是非常困难的。
然而,知道所有的操作员,他们做什么,是最好的开始,IMO。在各种运营商is to be found here, on MDN

的完整参考第一关:在Bitwise operartors
k & 3将返回013。为什么?因为&返回一系列位,无论是左边和右边的操作数“共享”
考虑以下几点:

| integer | binary | 
==================== 
| 1 | 0001 | 
| 2 | 0010 | 
| 3 | 0011 | 
| 4 | 0100 | 
-------------------- 

然后按理说,1 & 3等于1,因为只有第一位是“上“在两个操作数中(000>1< & 001>1<)。
您的代码段使用的另一个按位运算符是单个管道:|,其表达式如b |= 2。记住上面的表格:1 | 2在3中解析,1 | 3返回3.这是按位OR:如果两个操作数中的任何一个设置为1,则将每个位设置为1
b |= 2的情况下,结果值分配给b,这就是赋值运算符的用途,所以如果b为1,则b将设置为3,如果b为2或3,则不会更改等等。

除此之外,你有一大堆的嵌套三元的(x ? a : b)的,写的全时是一样的:

if (x)//truthy 
{ 
    a; 
} 
else 
{ 
    b; 
} 

最后,什么扔你最明显的是,逻辑运算符k & 3 ||...在开始时。 ||只是逻辑。根据左操作数的结果值,使用左操作数或右操作数。再次,它的简称:

if (k & 3) 
{//will be true if either the first, second or both the second and first bits are set on k 
    k & 3; 
} 
else 
{//if k is 4, for example 
    all the other stuff 
} 

只需要花一些时间浏览MDN参考并了解各种运营商。一旦你了解了它们,就像发现正则表达式一样:一个巨大的,激动人心的可能性领域展现出来,突然之间需要使用许多或许多代码行才能使用一个运算符来编写。

+0

非常棒的人,非常感谢! – Kristian