Помилка JSLint: Перемістіть усі декларації 'var' у верх функції


77

Сайт JSLint оновлено, і я більше не можу перевіряти сценарії JS. Для мене це попередження не є критичним, і я не хочу проходити через тисячі рядків, щоб це виправити, я хочу знайти більше критичних проблем.

Хтось знає, як вимкнути цю помилку або використовувати застарілий JSLint?

ОНОВЛЕННЯ

Приклад:

function doSomethingWithNodes(nodes){
  this.doSomething();

  for (var i = 0; i < nodes.length; ++i){
    this.doSomethingElse(nodes[i]);
  }

  doSomething(); // want to find this problem
}

Вивід jslint.com:

Error:
Problem at line 4 character 8: Move all 'var' declarations to the top of the function.

for (var i = 0; i < nodes.length; ++i){

Problem at line 4 character 8: Stopping, unable to continue. (44% scanned).

Проблема:

Наявність змінних поверх функцій - нова вимога. Я не можу використовувати JSLINT для тестування коду, оскільки він зупиняє сканування сценарію щодо цієї помилки.

У мене багато коду, і я не хочу загрожувати цьому попередженню критичною помилкою.

ОНОВЛЕННЯ 22.08.2011: знайдено http://jshint.com , він виглядає набагато краще, ніж http://jslint.com/


Чи можете ви уточнити своє запитання? Ви насправді відповідаєте на два запитання?
James Wiseman

1
Чи все одно зупиняється при першій помилці, якщо ви зняли позначку Stop on first error?
Девід

цей сайт буде краще працювати -> glat.info/jscheck
vsync

@Lee Kowalkowski - просто скопіюйте свій код туди та запустіть його. Я оголошую змінні вгорі, щоб він ігнорував їх. (наприклад, Window, $ тощо)
vsync

2
JSHint - хороший вибір.
B Robster

Відповіді:


151

Оновлення, червень 2017 р .: За умови підтримки (наприклад, якщо ви не використовуєте JavaScript в Internet Explorer 10 або старішій версії), вам слід розглянути можливість використання let замість var .

Наприклад: for(let i=0; ...; i++)


Я ніяк не збираюся ставити var i;з a for(var i=0; ...; i++)у верхній частині своїх функцій. Особливо, коли Специфікація JavaScript має його як прийнятний синтаксис у forрозділі (12.6). Крім того, це синтаксис, який Брендан Ейх використовує у своїх прикладах.

Ідея переміщення декларації вгору полягає в тому, що вона повинна точніше відображати те, що відбувається під капотом, однак, робити це буде лише відображати, а не впливати.

Для мене це смішне очікування forповторень. Тим більше, що JSLint припиняє обробку, коли виявляє це.

Чи є змінні, оголошені у верхній частині функції, більш читабельними, дискусійно. Я особисто вважаю за краще, щоб змінні-ітератори оголошувались при їх використанні. Мені байдуже, чи змінна вже створена всередині, я ініціалізую її тут, щоб я був у безпеці.

Я б стверджував, що оголошення змінної ітератора там, де вони використовуються, гарантує, що вони випадково не стануть глобальними (якщо ви перемістите цикл в іншу функцію, змінна ітератора рухається разом з нею). Це набагато зручніше, ніж необхідність підтримувати оголошення змінних у верхній частині функцій.

На даний момент я використовую http://www.javascriptlint.com/online_lint.php, оскільки, схоже, це зосереджено на важливих речах.


12
Також перевірте JSHint, який був створений частково у відповідь на подібні матеріали в JSLint. І побачити це обговорення: stackoverflow.com/questions/6803305 / ...
B Robster

1
Дякуємо, що вказали на javascriptlint.com/online_lint.php . Я використовував JSLint, але важко перебирати всі безглузді міркування про помилки, які навіть не є помилками на JSLint.

14
Я з вами не погоджуюсь, але важливо зазначити, що javascript має лише функціональну область. Він не має області блоків у циклі for. Отже, навіть якщо змінна i, визначена в for(var i=0; i<10; i+=1)ній, буде доступна для всієї функції та буде піднята вгору при ініціалізації. JSLint є синтаксично правильним, але в цьому випадку за домовленістю ніхто не кодує таким чином.
mastaBlasta

2
NVM ви абсолютно праві. Я тестував, щоб побачити, що станеться, якщо у вас буде два цикли у функції for(var i=0; i<5; i+=1), якщо компілятор видасть variable already definedпопередження, але цього не сталося! Навіть у суворому режимі повторне оголошення змінної не призвело до попереджень та помилок. Тоді так, JSLint помиляється.
mastaBlasta

2
@Zon: або просто використовуйте iзнову, як будь-який розумний розробник. Не має значення де ви заявляєте var i, повторне використання дозволено незалежно.
Lee Kowalkowski

7

Компілятор Google Closure насправді не зможе правильно визначити тип змінної циклу циклу for ... in, якщо він не оголошений як for (var i in ...), і жодна анотація, здається, не виправляє цього, тому декларацію не можна переміщати до верху.


О справді ?! Шкода, але справді корисно поділитися, +1.
Lee Kowalkowski

@jjrv у вас є приклад коду, який не працює з компілятором закриття? Я використовую його і не бачив жодних проблем.
JavaKungFu

Ознакою @JavaKungFu було те, що компілятор повідомляє код, набраний менш ніж на 100%, і відображає попередження, якщо ви встановите reportUnknownTypes = CheckLevel.WARNING у CompilerOptions.java.
jjrv

О гаразд, я неправильно зрозумів вашу відповідь, я думав, що це насправді створило проблему в складеному коді. Дякую.
JavaKungFu

5

Ви можете будь-коли завантажити застарілі версії або змінити останню версію . Це не так складно, насправді (шукати move_var). Потім запустіть jslint локально, або за допомогою вузла, або за допомогою браузера з простою формою HTML - можливо, ви захочете скопіювати оригінал Крокфорда.

Зауважте, що попередження було введено як частина основного перезапису , і воно з’являється лише після for(, тому повідомлення трохи вводить в оману.



3

У мене була ця проблема в моїй кодовій базі, коли ми хотіли перейти на останню версію JSLINT. У нас їх було багато, і люди були не раді перенести декларацію. Ми фактично виявили, що найелегантнішим рішенням було використання underscore.js і замість повного багатослівного циклу використовувати функцію _.each (), яка видалила помилку JSLint і зробила наш код більш функціональним, чистим, жорсткішим та простішим для читати.


1

Незважаючи на те, що нова бета-версія JSLint не документує директиву про коментарі щодо множинних varдопусків у межах функції, вона , схоже, підтримує директиви з початкової версії.

Оригінальний JSLint дозволив вам зробити це:

/*jslint vars: true */

З мого досвіду це все ще працює - я думаю, для зворотної сумісності. Час написання - червень 2015 року.


0

Я виявив, що наступний синтаксис видалить помилку:

function doSomethingWithNodes(nodes) {
    this.doSomething();
    var i; // HERE is where you move the 'var' to the top of the function
    for (i = 0; i < nodes.length; ++i) {
        this.doSomethingElse(nodes[i]);
    }

    doSomething(); // want to find this problem
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.