在Javascript中奇怪地使用“for”循环,请解释

时间:2012-05-04 20:15:59

标签: javascript for-loop cycle

我发现这个奇怪的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 个答案:

答案 0 :(得分:5)

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

就像

var a, b, c;

for循环中的iterator语句也包含很多操作,而不是实际拥有正文的循环。

这个函数是由一个可怕的程序员编写的,不考虑可读代码,或者它是故意缩小和混淆的。

答案 1 :(得分: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

答案 2 :(得分: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部分中的所有语句仍然是执行,直到支票不再是true

看起来某人希望他们的代码是可读的。无论如何,你在哪里找到它?

答案 3 :(得分: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("");
}

最终结果 / \