阵列索引是否代价高昂?

时间:2013-02-19 21:29:16

标签: javascript backbone.js

backbone下面的代码段中,此行

(ev = events[i]).callback.call(ev.ctx);

尚不清楚。我想假设ev = events[i]ev.ctx之前被解释,因为除了减少数组索引之外,变量似乎没有其他目的。

假设这是正确的,这样做是因为数组索引成本很高吗?我知道在嵌入式工程中,当您使用有限的资源时,索引编制成本很高。但我认为这不是JavaScript中的一个问题。

Backbone Snippet

triggerEvents = function(events, args) {
    var ev, 
        i = -1, 
        l = events.length;
    switch (args.length) {
        case 0: 
            while (++i < l) {
                (ev = events[i]).callback.call(ev.ctx);
            }
            return;
        case 1: 
            while (++i < l) {
               (ev = events[i]).callback.call(ev.ctx, args[0]);
            }
            return;
        case 2: 
            while (++i < l) { 
                (ev = events[i]).callback.call(ev.ctx, args[0], args[1]);
            }
            return;
        case 3: 
            while (++i < l) { 
                (ev = events[i]).callback.call(ev.ctx, args[0], args[1], args[2]);
            }
            return;
        default: 
            while (++i < l) {
                (ev = events[i]).callback.apply(ev.ctx, args);
            }
    }
};

1 个答案:

答案 0 :(得分:1)

确定使用treehugger.js demo生成AST backbone.js方法,并使用这段简化的代码:

var ev, i = -1, l = 3;
while (++i < l) { 
  (ev = events[i]).callback.call(ev.ctx, args[0], args[1], args[2]);
}

生成此AST:

[
  VarDecls(
      [
        VarDecl("ev"),
        VarDeclInit(
            "i",
            PrefixOp(
                "-",
                Num("1")
            )
        ),
        VarDeclInit(
            "l",
            Num("3")
        )
      ]
  ),
  While(
      Op(
          "<",
          PrefixOp(
              "++",
              Var("i")
          ),
          Var("l")
      ),
      Block(
          [
            Call(
                PropAccess(
                    PropAccess(
                        Assign(
                            Var("ev"),
                            Index(
                                Var("events"),
                                Var("i")
                            )
                        ),
                        "callback"
                    ),
                    "call"
                ),
                [
                  PropAccess(
                      Var("ev"),
                      "ctx"
                  ),
                  Index(
                      Var("args"),
                      Num("0")
                  ),
                  Index(
                      Var("args"),
                      Num("1")
                  ),
                  Index(
                      Var("args"),
                      Num("2")
                  )
                ]
            )
          ]
      )
  )
]

虽然隐含的“清洁”方法:

var ev, i = -1, l = 3;
while (++i < l) {
  ev = events[i];
  ev.callback.call(ev.ctx, args[0], args[1], args[2]);
}

生成此AST:

[
  VarDecls(
      [
        VarDecl("ev"),
        VarDeclInit(
            "i",
            PrefixOp(
                "-",
                Num("1")
            )
        ),
        VarDeclInit(
            "l",
            Num("3")
        )
      ]
  ),
  While(
      Op(
          "<",
          PrefixOp(
              "++",
              Var("i")
          ),
          Var("l")
      ),
      Block(
          [
            Assign(
                Var("ev"),
                Index(
                    Var("events"),
                    Var("i")
                )
            ),
            Call(
                PropAccess(
                    PropAccess(
                        Var("ev"),
                        "callback"
                    ),
                    "call"
                ),
                [
                  PropAccess(
                      Var("ev"),
                      "ctx"
                  ),
                  Index(
                      Var("args"),
                      Num("0")
                  ),
                  Index(
                      Var("args"),
                      Num("1")
                  ),
                  Index(
                      Var("args"),
                      Num("2")
                  )
                ]
            )
          ]
      )
  )
]

这两者之间的唯一区别是Assign()发生在PropAccess()内,而“清洁”方法则发生在外面。它们具有相同数量的步骤。您可以将Assign全部放在一起,并将其与第二个Index交换。我担心我对JS内部知识不够了解,知道这是否更快。我猜它是平台依赖的。

相关问题