【问题标题】:Why Did Filatov Use an OR Statement?为什么 Filatov 使用 OR 语句?
【发布时间】:2021-02-09 01:21:22
【问题描述】:

我已经对 Dmitry Filatov 的 jQuery-Plugins (https://github.com/dfilatov/jquery-plugins) 进行了分支,以努力了解这个 @#^#$% 男巫如何编写他的油门和去抖动包装器。

在所有对我来说完全没有意义的事情中,他的油门将 setTimeout() 作为 OR 语句的一部分包装在 IIFE 中:

// why the extra complexity here?
timer || (function() {
   if (needInvoke) {
     fn.apply(ctx, args);
     needInvoke = false;
     timer = setTimeout(arguments.callee, timeout);
   } else {
     timer = null;
   }
})();

据我所知,如果计时器有值,它只会阻止 IIFE 执行。是性能问题吗?

【问题讨论】:

  • 这是为了防止多个定时器运行。此外,该代码非常陈旧; arguments.callee 不应该在现代代码中使用。
  • 请注意存储库自述文件顶部的警告。
  • 这里没有什么非常“神奇”的地方,尽管如果你不熟悉这样的 JavaScript 约定,它可能看起来很神奇。老实说,其中很多只是由于 JavaScript 早期(例如 ES5 之前)版本的限制而造成的语法垃圾。不要被这样的东西弄得眼花缭乱。
  • 这是if (!timer) { if (needInvoke) ... else ... }的快捷方式
  • 我同意 tadman,因为它不是进行外部检查 if (!inThrottle) {....}

标签: javascript throttling iife


【解决方案1】:

由于短路,逻辑运算符可以用作if的替代品。

expr1 || expr2

等价于

if (!expr1) expr2

但是由于|| 的参数必须是表达式,所以不能将语句块放在那里。 IIFE 可用于将语句块包装在表达式中。

如果您撤消这些转换,您将获得更直接的代码:

if (!timer) {
  if (needInvoke) {
    fn.apply(ctx, args);
    needInvoke = false;
    timer = setTimeout(arguments.callee, timeout);
  } else {
    timer = null;
  }
}

【讨论】:

    【解决方案2】:

    对于需要此功能的其他人,我找到了一个使已弃用的被调用者没有实际意义的教程:https://programmingwithmosh.com/javascript/javascript-throttle-and-debounce-patterns/

    我仍然认为 Filatov 是一个 !#$%@$ 巫师。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      • 1970-01-01
      • 2011-06-09
      • 1970-01-01
      • 2011-01-10
      • 1970-01-01
      相关资源
      最近更新 更多