JSLint Брекеты вокруг If-Block - PullRequest
10 голосов
/ 07 августа 2011

В Javascript, если выражение if не имеет фигурной скобки после него, следующий оператор помещается внутри блока if.То есть

if(foo)
bar();
baz();

эквивалентно

if(foo) {
  bar();
}
baz();

Дуглас Крокфорд рекомендует не использовать первое, потому что это сбивает с толку и может привести к трудным для отслеживания ошибкам, если программист пытается добавитьоператор для блока if без фигурных скобок.По этой причине JsLint жалуется, если вы используете первую форму.

Я использую это все время, и я чувствую, что это не проблема, если вы поместите оператор в ту же строку, что и оператор if, например:

if(foo) bar();
baz();

Это более кратко визуально, чем полная форма скобок, и у меня никогда не было путаницы с этим.Просто чтобы я мог передать JsLint и не иметь такого большого визуального шума, я иногда прибегал к использованию менее идиоматической формы, основанной на коротком замыкании оператора, например:

foo && bar();
baz();

Вы, вероятно, все ждетемне поторопиться и задать вопрос, так что вот так: Обычно считается плохой практикой не использовать фигурные скобки в однострочных условных выражениях, если вы правильно их форматируете?Зачем?Есть ли законная причина для жалобы JsLint по этому поводу?

Ответы [ 2 ]

5 голосов
/ 08 августа 2011

JSLint проверяет, выполнен ли ваш код в стиле Крокфорда.Есть его форк JSHint , который можно настраивать и с ним гораздо меньше работатьэто, вероятно, будет исправлено в ближайшее время:)

/*jshint curly: false */

var a = true;
function work() {
    console.log('work');
}

if (a) work();
4 голосов
/ 08 августа 2011

В чтении:

  • Возможно, вы не привыкли к этому стилю кодирования и можете подумать, что он выполняет две функции:

    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 s к этим однострочным if, структура становится все более опасной для манипулирования.

Короче говоря, вы можете использовать его, но используйте его, зная плюсы и минусы, как и любой другой инструмент.

...