JavaScript становится все более популярным языком благодаря распространению веб-приложений и принятию HTML5. Частью привлекательности JavaScript является легкость, с которой можно начать писать полезные и забавные вещи с ним. Нет необходимости в тяжелых интегрированных средах разработки (IDE) или сторонних приложениях. Просто откройте любой текстовый редактор, сохраните файл и откройте его в веб-браузере.
Приманка JavaScript может легко превратиться в ловушку для начинающих программистов. Податливость языка может создавать чудовищные ошибки в сложных скриптах. Например, отсутствующее объявление локальной переменной может таинственным образом проявляться в другом месте страницы путем изменения глобальных переменных.
Введите JSLint . Согласно его веб-сайту, JSLint является «инструментом качества кода JavaScript». Его автор, Дуглас Крокфорд, хорошо известен своей работой по разработке JavaScript (также известного как ECMAScript) и JSON. JSLint помогает программистам JavaScript, следуя определенным правилам кодирования. JSLint основан на предпосылке строгого режима, который доступен в пятом издании стандарта ECMAScript. В строгом режиме ваш код запускается с набором более строгих правил, чем обычно.
Использование JSLint
Давайте рассмотрим пример использования JSLint. Мы пишем простой плагин jQuery, который отображает сообщение, указанное в параметре msg
с префиксом. Префикс скрыт, если мы передаем значение false
через параметр type
.
(function ($) { $.fn.loading = function(msg, type, cssClass){ var prefixes = { warning: 'Warning: ' + msg, error: 'Error: ' + msg, info: 'Info: ' + msg, warning: 'Caution: ' + msg, }; if (type) { concatMsg = prefixes[type]; } else { concatMsg = msg; } $(this).each(function() { var tis = $(this) if (msg == false) { tis.html(''); } else { tis.html(concatMsg); } }); } })(jQuery);
Хотя этот фрагмент кода отлично работает как плагин для jQuery, когда вы используете его в Firefox или Chrome, вы можете увидеть, что есть некоторые явные ошибки и некоторые очень тонкие. Вместо того чтобы тратить свою умственную энергию на решение проблем, давайте использовать JSLint, чтобы помочь нам. Скопируйте код функции в текстовую область на сайте JSLint и нажмите кнопку «JSLint». Некоторые из полученных результатов JSLint показаны на рисунке ниже.
Первая ошибка, на которую указывает JSLint, заключается в том, что отсутствует выражение "use strict"
. Эта ошибка указывает на то, что функция не выполняется в строгом режиме. Чтобы исправить эту ошибку, включите строгий режим, добавив следующий строковый литерал в начало тела функции.
'use strict';
После включения строгого режима снова нажмите кнопку «JSLint». Сообщаемая ошибка отсутствующего "use strict"
должна исчезнуть. Теперь мы можем перейти к следующей ошибке, показанной на следующем рисунке. Эта ошибка связана с пробелами и является скорее косметической, чем функциональной. Так как это не фактическая ошибка, вы можете спокойно ее игнорировать.
Вы можете выбрать придерживаться без пробела после ключевого слова function
и подавить сообщение об ошибке, прокрутив страницу вниз и переключив параметр «грязный пробел» на true
. Однако сейчас мы хотим сохранить поведение по умолчанию, поскольку эта опция также проверяет другие проблемы с пробелами, как мы увидим позже.
Также обратите внимание, что вторая и третья ошибки, о которых сообщает JSLint, также находятся в одной строке, но в разных позициях. Похоже, пробел между закрывающей скобкой и открывающей скобкой также рекомендуется JSLint, поэтому исправьте это сейчас.
Снова нажав кнопку «JSLint», мы увидим, что следующая проблема находится в строке 8, в позиции 39. Литерал prefixes
объекта содержит два идентичных свойства warning
, что, очевидно, является ошибкой. Давайте исправим проблему, заменив второе warning
caution
.
Не нажимая кнопку «JSLint» снова, давайте посмотрим на следующую ошибку, показанную на следующем рисунке. Литерал объекта содержит запятую. Браузеры, такие как Chrome и Firefox, могут быть терпимы к таким ошибкам, но Internet Explorer не слишком любезен к таким нарушениям. Чтобы исправить проблему, просто удалите запятую.
Следующие две ошибки указывают на то, что concatMsg
использовался до его определения. Когда переменная не определена в текущей области, JavaScript проверяет объемы, чтобы определить, была ли она определена в другом месте. Если вы используете код из стороннего источника, который определяет эту точную переменную в глобальной области видимости, вам может потребоваться бесчисленное количество утомительных часов, чтобы найти ошибку. К счастью, с JSLint мы можем устранить проблему в зародыше.
Решая эту проблему, мы также можем реорганизовать наш код. Поскольку значением по умолчанию для concatMsg
является msg
, мы можем немедленно назначить это значение и изменить его позже, если это будет необходимо. Код для concatMsg
теперь можно переписать, как показано ниже.
var concatMsg = msg; if (type) { concatMsg = prefixes[type]; }
Далее мы сталкиваемся с той же проблемой пробелов, что и ранее, которая может быть исправлена таким же образом. Далее JSLint сообщает, что точка с запятой отсутствует. Это сообщение показано ниже. Без точки с запятой JSLint предполагает, что оператор никогда не завершается. Вот почему он видел, ожидая точки с запятой. Хотя в спецификации языка говорится, что конечная точка с запятой необязательна, целесообразно включить ее. Это еще одна область, в которой неаккуратное кодирование может приводить к труднопроходимым ошибкам в крупномасштабном производстве. Путем написания нашего кода мы можем быстро и легко решить такие проблемы.
Следующая ошибка является еще одним хорошим. В JavaScript есть равенство и строгие проверки на равенство. В нашем коде, не проверяя на строгое равенство, плагин ведет себя одинаково, если в качестве первого параметра указана либо пустая строка, либо логическое значение false
. Чтобы исправить ошибку, используйте оператор строгого равенства.
Сейчас самое время снова нажать кнопку «JSLint». Первая ошибка, показанная ниже, сообщается в строке 10. Похоже, что JSLint считает, что другой наилучшей практикой для написания JavaScript является группирование объявлений переменных вместе. Хотя concatMsg
идет сразу после prefixes
, JSLint предпочитает группировать объявления переменных в одном операторе, разделенном запятыми.
Следующая ошибка — еще одно косметическое предложение от JSLint. Тот факт, что на один пробел больше ожидаемого, на первый взгляд довольно тривиален. Однако проблемы с отступами могут привести к ошибкам, которые трудно обнаружить в больших сценариях. Для обеспечения согласованности верните закрывающую скобу на место, удалив лишнее пространство.
Следующая проблема, о которой сообщает JSLint, похожа на ту, что мы видели раньше, но проявляется в другой форме. Функции JavaScript могут быть назначены переменным. Как и с любым другим назначением переменной, JSLint ожидает завершающую точку с запятой.
Наконец, две проблемы сообщаются в последней строке, как показано ниже. Первая проблема — это предложение поместить закрывающие скобки после закрывающей скобки за jQuery, потому что не оставляет двусмысленности, что вы хотите, чтобы определение функции было закрывающим. Вторая проблема заключается в том, что, по мнению JSLint, переменная jQuery отсутствует, хотя, возможно, она была включена в веб-страницу путем ссылки на файл jQuery. Чтобы решить эту проблему, введите jQuery
в нижнее текстовое поле.
Если вы снова запустите JSLint, он обнаружит, что функция принимает три параметра. Однако в этом примере третий параметр никогда не используется. Здесь есть два подхода. Первый — удалить параметр, поскольку он никогда не используется. Второй вариант — установить для свойства JSLint «неиспользуемые параметры» значение true
, как показано ниже. Выберите эту опцию, только если вы действительно хотите по какой-то причине сохранить параметр в сигнатуре функции.
После использования JSLint для улучшения нашего кода, конечный продукт показан ниже.
(function ($) { 'use strict'; $.fn.loading = function (msg, type, cssClass) { var prefixes = { warning: 'Warning: ' + msg, error: 'Error: ' + msg, info: 'Info: ' + msg, caution: 'Caution: ' + msg }, concatMsg = msg; if (type) { concatMsg = prefixes[type]; } $(this).each(function () { var tis = $(this); if (msg === false) { tis.html(''); } else { tis.html(concatMsg); } }); }; }(jQuery));
Директивы JSLint
Директивы JSLint позволяют определять переменные и предоставлять другие параметры JSLint непосредственно из исходного кода. Это освобождает вас от необходимости многократно устанавливать параметры графического интерфейса JSLint. Например, комментарии в следующем примере определяют глобальную переменную с именем jQuery
и устанавливают для параметра «unparam» значение true
.
/*global jQuery*/ /*jslint unparam: true */ (function ($) { 'use strict'; … }(jQuery));
Вывод
В этом коротком примере JSLint указал на некоторые критические ошибки и некоторые, казалось бы, незначительные. Тот факт, что JSLint помогает нам уладить эти проблемы до того, как мы действительно запустим код, чрезвычайно полезен с точки зрения производительности труда разработчиков и качества приложений. Если вы серьезно относитесь к написанию производственного кода качества, всегда запускайте его через JSLint, прежде чем отправлять его на сервер. JSLint даже содержится в одном файле JS, так что вы можете скачать его, используя его в автономном режиме!