3

我发现这个奇怪的 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("");
    }
4

4 回答 4

5

这是一个普通的循环,但在第一部分for有一个很长的语句。var

就像

var a, b, c;

此外,for 循环中的迭代器语句包含很多操作,而不是循环实际上有一个主体。

这个函数要么是由一个糟糕的程序员编写的,不考虑可读代码,要么是被故意缩小和混淆的。

于 2012-05-04T20:17:47.053 回答
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

于 2012-05-04T21:22:23.673 回答
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- 和 update 部分中的所有语句仍将执行,直到 check 不再是true

看起来有人不希望他们的代码可读。还是你在哪里找到的?

于 2012-05-04T20:26:16.260 回答
1

将循环分解为更易读的:

  • 重新排列的循环参数
  • 改变(...)&&(...)if(...){(...)}
  • 改为l_len
  • 搬到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("");
}

最终结果/\

于 2012-05-04T21:20:45.677 回答