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 を使用して書き直したいのですが、ヒントはありますか? ありがとう!

4

3 に答える 3

12

||演算子は、それが真である場合は最初のオペランドを返し、そうでない場合は 2 番目のオペランドを返します。&&逆の場合: 最初のオペランドが false の場合はそれを返し、そうでない場合は 2 番目のオペランドを返します。

a ? b : cの省略形です(function(a) {if(a) return b; else return c;}(a);(正確ではありませんが、とにかくそれがアイデアです)。

,演算子は両方のオペランドを評価し、2 番目のオペランドを返します。

上記のすべてを念頭に置いて、上記のコードは次のようになります。

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か、代わりに変更される可能性があります。それは私にとって大きな混乱です。意味をなすには文脈が必要です。

于 2012-10-29T16:04:11.507 に答える
2

このコードはひどいです。他に言葉はありません。難読化ツールの結果のようです。このコードがどのように機能するかを知りたいと思っていることは理解していますが、難読化されたコードの要点は、それを解決することが不可能であるか、非常に困難であるということです。
ただし、すべてのオペレーターが何であるか、および彼らが何をするかを知ることは、IMO を開始するのに最適な場所です。さまざまな種類の演算子の完全なリファレンスは、MDN のここにあります。

まず、ビット単位の演算子:は、または
k & 3を返します。なんで?左オペランドと右オペランドの両方が「共有」する一連のビットを返すため、次のことを考慮してください。013&

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

次に、両方のオペランドで最初のビットのみが「オン」1 & 3であるため、が等しいのは理にかなっています ( )。 スニペットが使用するもう 1 つのビット演算子は、のような式で単一のパイプ:です。上記の表を念頭に置いてください:は3 で解決され、3 を返します。結果の値が に割り当てられる場合、それが代入演算子の目的です。したがって、が 1 の場合は3 に設定され、が 2 または 3 の場合は何も変更されません。1000>1< & 001>1<
|b |= 21 | 21 | 3OR11
b |= 2bbbb

それ以外には、ネストされた三項の ( x ? a : b) がたくさんあり、完全に書くと次​​のようになります。

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

最後に、あなたを最もk & 3 ||...驚かせたのは、最初の論理演算子です。は||単なる論理orです。左オペランドの結果の値に応じて、その左オペランドまたは右オペランドのいずれかが使用されます。繰り返しますが、これは次の略です。

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 リファレンスを参照し、さまざまなオペレーターについて理解してください。それらを理解すると、それは正規表現について知るようなものです: 広大で刺激的な可能性の領域が展開され、以前は非常に多くのコード行を必要としたものが、たった 1 つの演算子を使用して突然記述できるようになります。

于 2012-10-29T16:21:25.867 に答える
2

二重パイプはORを意味し、二重アンパサンドはANDを意味します。
また、?: 構文は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')

シングル パイプおよびアンパサンド記号 (equals - などの他のクエリ演算子と組み合わせることができます) と同様に、これらはビット単位の演算子であり、ブール値を返す etc. など=の単純な条件を処理しません。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;
于 2012-10-29T16:05:46.090 に答える