Почему Филатов использовал оператор OR?

#javascript #throttling #iife

#javascript #регулирование #iife

Вопрос:

Я разветвил jQuery-плагины Дмитрия Филатова (https://github.com/dfilatov/jquery-plugins ) в попытке узнать, как этот @ # ^# $% человек-волшебник написал свои обертки для дроссельной заслонки и дебаунса.

Из всех вещей, которые не имеют для меня абсолютно никакого смысла, его throttle оборачивает setTimeout() в IIFE как часть оператора OR:

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

Насколько я могу судить, это просто предотвращает выполнение IIFE, если таймер имеет значение. Это вопрос производительности?

Комментарии:

1. Это для предотвращения запуска более одного таймера. Кроме того, этот код серьезно устарел; arguments.callee его никогда не следует использовать в современном коде.

2. Обратите внимание на предупреждение в верхней части readme репозитория.

3. Здесь нет ничего ужасно «волшебного», хотя это может показаться волшебным, если вы не знакомы с подобными соглашениями JavaScript. Честно говоря, многое из этого — просто синтаксический мусор, наложенный ограничениями в более ранних (например, до ES5) версиях JavaScript. Не будьте ослеплены подобными вещами.

4. Это ярлык для if (!timer) { if (needInvoke) ... else ... }

5. я согласен с тэдманом, поскольку он вместо того, чтобы проверять, проверяет ли (!inThrottle) {….}

Ответ №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 /

Я все еще думаю, что Филатов — мастер! #$% @ $ .