Как применяется ошибка функции внутри цикла в JSLint при использовании .each () в jQuery? - PullRequest
4 голосов
/ 09 августа 2010

Я использую вызов jQuery .each(), который использует анонимную функцию из цикла for. JSLint предлагает предупреждение «Не выполнять функции в цикле».

Вот фрагмент кода из более крупной функции - по сути, он проверяет, все ли игроки в игре «живы» (имеет хотя бы одну фигуру на доске).

for( i=0 ; i<PLAYERLIMIT ; ++i ) {
    if( player[i].status !== 0 ) { //skip already dead players
        var stillAlive = false;
        $board.find("td").each( function() { //this func causes JSLint warning
            if( $(this).data("owner") === player[i].number ) {
                stillAlive = true;
                return false;
            }
        });
        if( !stillAlive ) {
            //... action to take for dead players
        }
    }
}

Я вижу, как убрать это предупреждение - просто объявите функцию отдельно и вызовите ее. Но это очень маленькая однократная функция, и, по сути, я рассматриваю это как тело вложенного цикла for, (я по сути читаю вызов .each() как нечто вроде for $("td") in $board {})

Этот JSLint предоставляет одно из предупреждений style , или это более серьезно?
В общем, лучше ли мне это исправить?

Я хотел бы понять причину предупреждения, поэтому любые комментарии по поводу того, почему существует предупреждение, будут полезны (опять же, я хочу знать, практично ли это или стиль).

Ответы [ 2 ]

3 голосов
/ 01 октября 2010

Итак, я считаю, что JSLint обеспокоен чем-то вроде этого:

for (var i=0; i<10; i++) {
    $("#my-elem" + i.toString()).click(function() { alert(i)});
}

Это приведет к тому, что все элементы с идентификаторами my-elem0 - my-elem9 будут предупреждать "10" при нажатии - iнаходится в области действия содержащейся функции, а не в цикле for.JSLint пытается защитить вас от этого, говоря вам не делать функции в цикле.Недостаточно разумно знать, что each будет вызывать вашу функцию сейчас, а не позже.

3 голосов
/ 09 августа 2010

В основном это просто стиль, возможно, некоторая эффективность, полученная в IE, хотя новые движки JS будут в любом случае встроены в функцию через механизм трассировки.Вы можете избавиться от "ошибки" JSLint жестко, как это:

function setupPlayer(player) {
  var stillAlive = false;
  $board.find("td").each( function() {
      if( $(this).data("owner") === player.number ) {
          stillAlive = true;
          return false;
      }
  });
  if( !stillAlive ) {
      //... action to take for dead players
  }
}

for(var i=0 ; i<PLAYERLIMIT ; ++i ) {
    if( player[i].status !== 0 ) { //skip already dead players
        setupPlayer(player[i]);
    }
}

Стоит ли вам?Лично я бы проигнорировал это в этом случае для удобства обслуживания, ваша текущая версия намного легче читать / поддерживать, для меня .Ваш звонок здесь, какая версия вам лучше?Любой способ, вероятно, окажет небольшое влияние на производительность.


Немного касательно, но связано:
Что будет иметь большее влияние на производительностькеширует, что <td> селектор, обход DOM довольно дорог.Я бы сделал это прямо перед вашим for циклом:

var cells = $board.find("td");

И использовал бы cells внутри цикла, нет необходимости снова находить те же самые элементы:)

...