2012-10-29 151 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