javascript - 主干触发事件

标签 javascript jquery backbone.js

我正在阅读事件模块的 Backbone.js 源代码,这段代码让我感到困惑:

var triggerEvents = function(events, args) {
  var ev, i = -1,
    l = events.length,
    a1 = args[0],
    a2 = args[1],
    a3 = args[2];
  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, a1);
      return;
    case 2:
      while (++i < l)(ev = events[i]).callback.call(ev.ctx, a1, a2);
      return;
    case 3:
      while (++i < l)(ev = events[i]).callback.call(ev.ctx, a1, a2, a3);
      return;
    default:
      while (++i < l)(ev = events[i]).callback.apply(ev.ctx, args);
      return;
  }
};

我想知道为什么我们要确定 args.length ?为什么不这样写:

var triggerEvents = function(events, args) {
    var ev, i = -1,
    while (++i < l)(ev = events[i]).callback.apply(ev.ctx, args);

};

所以主要问题是:我们为什么要确定args.length ?为什么不只使用一个 while (++i < l)(ev = events[i]).callback.apply(ev.ctx, args);替换所有 call

最佳答案

这是我的“有根据的猜测”(不知道 Backbone 的内部结构) 似乎每个 event 都有一个回调属性,它是当 event 被触发时要调用的函数。例如 click

这个回调函数可以接受各种数量的参数。参数数量未知。这就是 args.length 发挥作用的地方。当您仅传递单个参数时,它将使用该单个参数调用回调函数。如果你用 2 调用它,它将传递 2 个参数,等等......

之所以有callback.call()callback.apply()是因为.call()将参数传给了“逐个”调用函数,而 .apply() 将所有参数作为单个数组传递。

关于 .call().apply() 之间区别的很好的解释可以在这篇文章中找到 http://hangar.runway7.net/javascript/difference-call-apply

PS:如果我对 Backbone 的猜测是错误的,请纠正我 :)

更新

源码中有注释https://gist.github.com/badsyntax/4663217 ,就在 triggerEvents 声明之上。这就是你的答案。你可以试着找一些性能测试:)

   // Optimized internal dispatch function for triggering events. Tries to
   // keep the usual cases speedy (most Backbone events have 3 arguments).

更新 2

这样优化的原因是.call()可以比.apply()更快,因为.apply()需要构造数组作为参数。 (并且调用 .call() 和 .apply 几乎总是比调用原始方法慢,原因很简单,因为还需要执行一项操作)

关于javascript - 主干触发事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31399652/

相关文章:

javascript - 如何访问已经嵌入的 ContentChild?

jquery - 在触发第二个ajax之前完成第一个ajax,在循环内触发第三个ajax之前完成第二个ajax

javascript - 一页滚动的网站 - 但如何在动画完成之前禁用滚动

jquery - Symfony2 和 Jquery UI 选项卡

javascript - 在 Backbone 中选中复选框时禁用输入字段

javascript - 如何将highchart转换为二值图像

javascript - 导入 es6 模块,一些命名导出未定义

javascript - 如何使用 nodejs 打开默认浏览器并导航到特定 URL

javascript - 用于显示异步请求状态的 GUI 组件

backbone.js - Backbone .js中的集合与模型混淆