2012-05-04 14 views
3

を説明してください。 forサイクルには奇妙な構文(多くのパラメータ)がありますが、どのように動作させるのか説明できますか?おかげで普通のforループだが、最初の部分では非常に長いvar声明で奇妙な使用、私は理解できないこの奇妙なJavaScriptを見つけ

decode: function(s){ 
     for(var a, b, i = -1, l = (s = s.split("")).length, o = String.fromCharCode, c = "charCodeAt"; ++i < l; 
      ((a = s[i][c](0)) & 0x80) && 
      (s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ? 
      o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "") 
     ); 
     return s.join(""); 
    } 
+1

Ewwwww ......... –

答えて

2

興味深い機能、明らか種類の難解な文字の特定のセットを、トランスコーディングのみASCIIコードで動作しますが、ここ内訳です:

for (var i = 0; i < s.length; i++) { 
     var a = s.charCodeAt(i); 

     if (a & 0x80) { // (a >= 128) if extended ascii 

      var b = s.charCodeAt(i + 1); 

      var specialA = (a & 0xfc) === 0xc0; // a IS [À, Á, Â or Ã] essentially [192, 193, 194, 195] 
      var specialB = (b & 0xc0) === 0x80; // b >= 128 & b <= 191 eg. b is not a special Latin Ascii Letter 

      if (specialA && specialB) { 

       var txA = (a & 0x03) << 6; // [0, 64, 128, 192] 
       var txB = b & 0x3f; // 0 - 63 

       s[i] = String.fromCharCode(txA + txB); 

      } else { 
       s[i] = String.fromCharCode(128); 
       s[++i] = ""; 
      } 
     } 
    } 

これは、どちらの方法でもデコードが面白いと思っています。生のアセンブラを読んでいるのを思い出します.Lol -ck

+0

興味深いデコーディングテクニックn_n – ajax333221

+0

ありがとう、今それは非常に明確です!これは、** unicode **形式の文字列をデコードする関数でなければなりません(つまり、éはéにデコードされるべきです) – niente3

5

それはちょうど

var a, b, c; 

ようなものだ。また、forループでイテレータ文は操作の多くはなく、実際に本体を有するループが含まれています。

この機能は、読み取り可能なコードのために関わらず、ひどいプログラマによって書かれた、またはそれが意図的に縮小さと、難読化されましたか。

+0

それをやり遂げるために何らかのパフォーマンス上の勝利(現実か想像)がありました。 –

+0

@Codemonkey:恐ろしいプログラマーはそれを書いていませんでした。 – SLaks

+2

@SLaksあなたは間違っています。良いプログラマは、そこにすべての変数を設定しませんでした。優れたプログラマが読みやすさを気にします。 –

1

forループの異なる部分は、セミコロン(;)で割った、すべてがあります。

のvar一部:

var a, b, i = -1, l = (s = s.split("")).length, o = String.fromCharCode, c = "charCodeAt"; 

チェック部分:

++i < l; 

更新部:

((a = s[i][c](0)) & 0x80) && 
     (s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ? 
     o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = "") 

for()文があることを意味し、すぐに;が来るの後ループには本体がありませんが、var-、checkのすべての文 - 、更新部分は、チェックがもはやtrueでなくなるまで実行されます。

は誰かいない自分のコードが読めるようにしたいんでしたように見えます。とにかくどこでそれを見つけましたか?

1

をより読みやすいものにループを壊す:

  • 再配置ループパラメータ
  • if(...){(...)}
  • llen
s = s.split(...)移動
  • lenに変わっと (...)&&(...)を変更しました

    var a, b, s = s.split(""), o = String.fromCharCode, c = "charCodeAt"; 
    
    for(var i = -1, len = s.length; ++i < len;){ 
        if((a = s[i][c](0)) & 0x80){ 
         (s[i] = (a & 0xfc) == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ? o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = ""); 
        } 
    } 
    

    • i初期値とどのように/それが
    • a = s[i][c](0)

    外側を移動増大場所を変更しました。

    var a, b, s = s.split(""), o = String.fromCharCode, c = "charCodeAt"; 
    
    for(var i = 0, len = s.length; i < len; i++){ 
        a = s[i][c](0); 
    
        if(a & 0x80){ 
         s[i] = (a & 0xfc); 
         (s[i] == 0xc0 && ((b = s[i + 1][c](0)) & 0xc0) == 0x80 ? o(((a & 0x03) << 6) + (b & 0x3f)) : o(128), s[++i] = ""); 
        } 
    } 
    

    • を読むために物事を簡単にするためにtmpを作成tmp
    • に三項演算結果を格納し if(...){s[++i] = "";}
    • (s[i] == 0xc0 && tmp, s[++i] = "");を分割さあなたの例の内側に新しいループを置き換えます

    decode: function(s){ 
        var tmp, a, b, s = s.split(""), o = String.fromCharCode, c = "charCodeAt"; 
    
        for(var i = 0, len = s.length; i < len; i++){ 
         a = s[i][c](0); 
    
         if(a & 0x80){ 
          s[i] = (a & 0xfc); 
    
          if(((b = s[i + 1][c](0)) & 0xc0) == 0x80){ 
           tmp = o(((a & 0x03) << 6) + (b & 0x3f)); 
          }else{ 
           tmp = o(128); 
          } 
    
          if(s[i] == 0xc0 && tmp){ 
           s[++i] = ""; 
          } 
         } 
        } 
    
        return s.join(""); 
    } 
    

    最終結果/\