2012-05-04 61 views
3

我發現了這個奇怪的JavaScript,我聽不懂。 For循環有一個奇怪的語法(很多參數),你能解釋一下它是如何工作的嗎?由於在Javascript中奇怪地使用「for」循環,請解釋

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] = ""; 
      } 
     } 
    } 

希望這有幫助,無論哪種方式我發現解碼有趣,提醒讀取原始彙編程序,哈哈-ck

+0

有趣的解碼技術n_n – ajax333221

+0

謝謝,現在很清楚!這應該是一個函數來解碼** unicode **格式化的字符串(即é應解碼爲é) – niente3

5

這是一個普通的for循環,但在第一部分很長var聲明。

這就像

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-中的所有語句都檢查 - ,更新部分仍然會執行,直到支票不再是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
  • 分裂(s[i] == 0xc0 && tmp, s[++i] = "");if(...){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(""); 
} 

最終結果/\