I have the following code:
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);
I'm confused even where to start. Is || a binary operator? why is there a comma at beginning? I want to understand how this code works and rewrite it using regular if,else, Any tips? Thanks!
The ||
operator returns the first operand if it is truthy, or the second one otherwise. &&
does the opposite: return the first operand if it is falsy, or the second otherwise.
a ? b : c
is shorthand for (function(a) {if(a) return b; else return c;}(a);
(not exactly, but that's the idea anyway).
The ,
operator evaluates both its operands and returns the second.
With all that in mind, the code above becomes:
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;
}
I can't tell you what it means, though. It's just a bunch of numbers being checked. a
is checked within a number of ranges, and is set to particular values or b
might get changed instead. It's a huge mess to me, it needs context to make sense.
Double pipe means OR and double ampersand means AND.
Also, the ?: syntax is a shortcut for if/else.
So
if (a == 3) alert('a is 3')
else alert('a is NOT 3')
can be written like
a == 3 ? alert('a is 3') : alert('a is NOT 3');
or
alert(a == 3 ? 'a is 3' : 'a is NOT 3')
As with single pipe and ampersand signs (that can be combined with some other query operators such as equals - =
), they are bitwise operators and they don't deal with straight forward conditions such as if (a == 3)
etc. that return a boolean value.
Something to note is, double pipe can also be used when checking if a value is undefined. So it apparently casts the type into a boolean. Here's an example.
// 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;
This code is terrible, there's no other word. It seems to be the result of some obfuscater. I understand you want to know how this code works, but the whole point of obfuscated code is that it's either impossible or extremely hard to work it out.
However, knowing what all the operators are, and what they do, is the best place to start, IMO. A full reference of the various kinds of operators is to be found here, on MDN
First off: the Bitwise operartors:k & 3
will return either 0
, 1
or 3
. Why? because &
returns a series of bits that both the left and right operand "share"
Consider the following:
| integer | binary |
====================
| 1 | 0001 |
| 2 | 0010 |
| 3 | 0011 |
| 4 | 0100 |
--------------------
Then it stands to reason that 1 & 3
equals 1
, because only the first bit is "on" in both operands (000>1< & 001>1<
).
Another bitwise operator that your snippet uses is the single pipe: |
, in an expression like b |= 2
. Keeping the above table in mind: 1 | 2
resolves in 3, 1 | 3
returns 3. This is the bitwise OR
: set each bit to 1
if either of the two operands have it set to 1
.
In the case b |= 2
the resulting value is assigned to b
, that's what the assignment operator is for, so if b
is 1, b
will be set to 3, if b
is 2 or 3, nothing is changed and so on.
Other than that, you have a bunch of nested ternary's (x ? a : b
) which, when written in full is the same as:
if (x)//truthy
{
a;
}
else
{
b;
}
Lastly, what threw you the most apparently is that logical operator k & 3 ||...
in the begining. The ||
is just a logical or. Depending on the resulting value of the left operand, either that left operand or the right operand is used. Again, it's short for:
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
}
Just take some time browsing through the MDN reference and get to know the various operators. Once you've gotten to know them, it's like finding out about regex: a vast, exciting realm of possibilities unfolds, things that took many, many lines of code before suddenly can be written using just one operator.
来源:https://stackoverflow.com/questions/13125086/understanding-ternary-operators