JSLint Брекеты вокруг If-Block
В Javascript, если if
выражение не имеет фигурную скобку после него, следующее выражение помещается внутри if
блок. То есть,
if(foo)
bar();
baz();
эквивалентно
if(foo) {
bar();
}
baz();
Дуглас Крокфорд рекомендует не использовать первое, потому что это сбивает с толку и может привести к трудным для отслеживания ошибкам, если программист пытается добавить оператор к if
блок без брекетов. По этой причине JsLint жалуется, если вы используете первую форму.
Я использую это все время, и я чувствую, что это не проблема, при условии, что вы помещаете заявление в ту же строку, что и if
утверждение, как это:
if(foo) bar();
baz();
Это более кратко визуально, чем полная форма скобки, и у меня никогда не было путаницы с этим. Чтобы я мог передавать JsLint и не иметь такого большого визуального шума, я иногда прибегал к использованию менее идиоматической формы, которая полагается на короткое замыкание оператора, например так:
foo && bar();
baz();
Вы, вероятно, все ждете, пока я потороплюсь и задам вопрос, поэтому здесь все так: считается ли вообще плохой практикой не использовать фигурные скобки в однострочных условных выражениях, если вы правильно их форматируете? Зачем? Есть ли законная причина для жалобы JsLint по этому поводу?
2 ответа
В чтении:
Возможно, вы не привыкли к этому стилю кодирования и можете подумать, что он выполняет две функции:
if(foo) bar(); baz();
Поскольку JS имеет автоматическую вставку точек с запятой, существуют еще более мрачные обстоятельства. Мне, например, не нравится то, что ASI будет делать с этим кодом, даже если я могу это объяснить:
if(foo) bar() baz()
Это не невозможно понять или даже трудно, если вы знаете, что делает ASI, но ASI является нетривиальным алгоритмом. Необходимость запускать его в своей голове обходится дорого с точки зрения времени, поэтому лучше, если вы просто избегаете неоднозначных (в этом смысле не неоднозначных, как в спецификации ECMA-262) ситуаций.
Это делает ваши строки длиннее, чем они должны быть. Это может считаться бесполезным в зависимости от ваших соглашений о кодировании, если ваше условие длинное, и ваше утверждение также, результирующее однострочное утверждение будет более обременительным для глаз для чтения (хорошо известно, что ваши глаза трудно читать очень одинокие строки, следовательно, параграф).
Вы можете, если вы по какой-то причине, несмотря на фигурные скобки, по-прежнему использовать что-то в форме:
if(foo) bar();
И это практически идентично коду, который у вас был, но я не вижу причин, чтобы не просто поставить там скобки.
На письме:
Когда вам нужно добавить еще одно утверждение, вы просто не напишите его. Для этого вам придется провести рефакторинг окрестностей. Опять же, это совсем не сложно, но об этом стоит подумать, это не связано ни с вашей проблемой, ни с ее решением проблемы, это просто синтаксическая изюминка.
Я думаю, вы уже поняли, но это был бы такой сценарий.
Исходный код:
if(foo) bar();
Измененный код:
if(foo) bar(); baz();
Вы можете ясно увидеть проблему, но она не обязательно появится в обычном обзоре кода. Если ваши тестовые сценарии не охватывают этот конкретный путь кода, это может быть запущено в производство из-за неоднократных упущений кодера, которые облегчаются, не требуя явного разграничения блоков. Решение, которое вы могли бы принять, как у вас есть, это сказать что-то вроде
if(foo) bar() && baz()
, но это не получится, еслиbar()
это ложь, так что вы в конечном итоге с такими уродливыми вещами, какif(foo) (bar(), baz());
который работает, но решительно очень уродлив.
Лично я пользуюсь однострочным if
операторы только тогда, когда строка очень короткая, а сам алгоритм также короткий. Что-то вроде if(extra_loop) --i;
или же if(!valid) break;
Когда вы начинаете добавлять else
Для этих однострочных операторов структура становится все более опасной для манипулирования.
Короче говоря, вы можете использовать его, но используйте его, зная плюсы и минусы, как и любой другой инструмент.
JSLint проверяет, выполнен ли ваш код в стиле Крокфорда. Есть его форк, называемый JSHint, который настраивается и намного менее раздражает в работе.
Вот код, который хорошо проверяет (кроме крошечной ошибки, которая, вероятно, будет исправлена в ближайшее время:)
/*jshint curly: false */
var a = true;
function work() {
console.log('work');
}
if (a) work();