В чем причина того, что JSLint говорит, что «слишком много выражений var» - PullRequest
63 голосов
/ 01 мая 2009

JSLint (с включенным флагом onevar) помечает некоторый код JavaScript, который у меня есть, с помощью следующего:

Problem at line 5 character 15: Too many var statements.

Я рад исправить эти ошибки, но я хотел бы знать, делаю ли я это для повышения производительности или потому, что это просто плохая практика и имеет больший потенциал для появления ошибок в моем коде javascript. В чем причина флага onevar?

Я просматривал документы JSLint для ключевого слова var , но в нем конкретно не говорится о том, почему несколько операторов var в одной и той же функции плохие.

Вот попытка примера. Объясните, как будет полезен код, если иметь только 1 оператор var:

function Test(arg) {
   var x = arg + 1,
       y = cache.GetItem('xyz');
   if (y !== null) {
      // This is what would cause the warning in JSLint
      var request = ajaxPost(/* Parameters here */);

   }
}

Ответы [ 7 ]

98 голосов
/ 01 мая 2009

Javascript не имеет области видимости блока. В других языках с ним (например, c), если вы объявляете переменную в операторе if, вы не можете получить к ней доступ за ее пределами, но в javascript вы можете. Автор JSLint считает, что это плохая практика, поскольку вы (или другие читатели) можете запутаться и подумать, что вы больше не можете получить доступ к переменной, но на самом деле можете. Поэтому вы должны объявить все свои переменные в верхней части функции.

28 голосов
/ 19 ноября 2009

Официальная причина здесь , Дуглас Крокфорд.

Цитировать:

Во многих языках блок вводит область действия. Переменные, введенные в блок не виден за пределами блока.

В JavaScript блоки не вводят область действия. Есть только Функция-сфера. Переменная, введенная в любом месте функции виден везде в функции. Блоки JavaScript сбивают с толку опытные программисты и приводят к ошибкам, потому что знакомый синтаксис дает ложное обещание.

JSLint ожидает блоки с функцией if, switch, while, for, do и попробуй заявления и больше нигде.

На языках с областью действия блока обычно рекомендуется переменные должны быть объявлены на сайте первого использования. Но потому что JavaScript не имеет блока видимости, разумнее объявить все функции переменные в верхней части функции. Рекомендуется, чтобы один оператор var будет использоваться для каждой функции. Это может быть отклонено с помощью переменных опция.

6 голосов
/ 05 ноября 2009

Просто объявите свои переменные в одном месте, как это:

var request,x,y;
3 голосов
/ 01 мая 2009

Если для опции "onevar" установлено значение true, если разрешен только один оператор var для каждой функции.

if (funct['(onevar)'] && option.onevar) {
    warning("Too many var statements.");
}
2 голосов
/ 14 октября 2012

Аргументация уже описана.

Рекомендуется использовать эту форму:

var myVar1 = document.getElementById("myDiv1"),
  myVar2 = document.getElementById("myDiv2");

или это:

var myVar1, myVar2;
myVar1 = document.getElementById("myDiv1");
myVar2 = document.getElementById("myDiv2");

Но это выглядит не очень хорошо, особенно если вы хотите задокументировать переменные.

Так что вы можете просто временно отключить это предупреждение:

  /*jslint vars: true*/
  /**
   * @returns {HTMLDivElement}
   */
  var myVar1 = document.getElementById("myDiv1");
  /**
   * @returns {HTMLDivElement}
   */
  var myVar2 = document.getElementById("myDiv2");
  /*jslint vars: false*/

Предупреждение: убедитесь, что это сделано в верхней части функции.

Я думаю, что это сделано, потому что jslint не может надежно определить, были ли переменные объявлены в начале функции или нет.

1 голос
/ 01 мая 2009

Просто предположение, но это может быть время для функциональной декомпозиции . Функции должны делать одну вещь и делать это хорошо.

Слишком много переменных наводит на мысль о функции, которая пытается сделать слишком много. Или случай, когда вы должны использовать массив.

0 голосов
/ 21 сентября 2009

Идея в том, что вы должны использовать объект вместо отдельных переменных. Итак, где вы получили:

var x = arg + 1,
    y = cache.GetItem('xyz');

Измените его на:

var dimensions = {};
dimensions.x = arg + 1;
dimensons.y = cache.GetItem('xyz');
dimensions.request = ...

Затем вы можете получить доступ к этим переменным через объект, то есть иметь по одному объекту на функцию, чтобы содержать переменные этих функций. Тогда вы не получите предупреждение.

...