Я пытаюсь понять, почему я получаю следующую ошибку, а не как ее обойти.
Передача следующего кода в JSLint или JSHint дает ошибку "err" уже определено.
/*jslint white: true, devel: true, onevar: true, browser: true, undef: true, nomen: true, regexp: true, plusplus: true, windows: true, bitwise: true, newcap: true, strict: true, maxerr: 50, indent: 4 */
function xyzzy() {
"use strict";
try { /*Step 1*/ } catch (err) { }
try { /*Step 2*/ } catch (err) { }
}
Очевидное предположение здесь состоит в том, что catch
ведет себя или должно вести себя как функция. Таким образом, err
не является глобальной переменной или локальной переменной для xyzzy
, а параметром для блока catch
.
При просмотре ECMA-262 Standard, раздел 12.14, описывающий инструкцию try
указывает, что предложение catch
принимает идентификатор, привязанный к исключению. Кроме того, правило семантического производства для catch
относится к параметру, который передал вызывной идентификатор в качестве аргумента.
Это, по-видимому, подсказывает случайному читателю, что приведенный выше код действителен и что, возможно, в инструментах lint есть ошибка.
Даже IntelliJ строгий анализ проверки кода JavaScript не сообщает об этом проблема с переопределением err
.
Больше беспокойства, если речь идет о переменной неопределенности, то можно предположить, что err
истекает кровью в глобальное пространство, что создает целый ряд других проблем, и вместо этого следует объявить его перед, вот так:
/*jslint white: true, devel: true, onevar: true, browser: true, undef: true, nomen: true, regexp: true, plusplus: true, windows: true, bitwise: true, newcap: true, strict: true, maxerr: 50, indent: 4 */
function xyzzy() {
"use strict";
var err; // DECLARE err SO IT IS CERTAINLY LOCAL
try { /*Step 1*/ } catch (err) { }
try { /*Step 2*/ } catch (err) { }
}
Но это приводит только к двум ошибкам о err
в каждом из операторов catch, что делает проблему хуже и потенциально представляет затенением переменных.
Инструменты lint показывают, что каждый блок catch
вводит не только его собственную лексическую область, но и новую переменную. Это не может быть правильно.
Простое создание err1
, err2
,... для успокоения инструментов статического анализа просто скрывает симптом и не способствует созданию более чистого кода.
Гугеры JavaScript. Является ли это ошибкой в инструменте lint, темном углу с спецификацией JavaScript или фундаментальном непонимании того, что происходит здесь?
ОБНОВЛЕНИЕ: Написал Douglas Crockford, автору JSLint, и, оказывается, есть очень веская причина для этого предупреждения. См. Ответ ниже.