Обоснование претензий Крокфорда - PullRequest
20 голосов
/ 05 августа 2011

Я прочитал Крокфорда JavaScript: The Good Parts и использовал его валидатор JSLint .Меня иногда удивляет обоснованность его рекомендаций.Ниже приведен список примеров, которые я хочу обосновать.


  1. Почему JSLint выдает ошибку, если вы не включили "use strict";?[См. этот поток SO .]

  2. Почему объявления переменных внутри функции должны выполняться с использованием одного var?[См. этот поток SO .]

  3. Почему нам нужно поместить пробел между function и () в function ()?

  4. Почему мы не можем использовать continue?

  5. Что не так с ++ и --?

  6. Почему мы не можем использовать оператор запятой , (за исключением частей инициализации и приращения оператора for)?[См. этот пост .]

  7. Почему каждое утверждение должно заканчиваться ;?[См. это сообщение в блоге .]

Ответы [ 2 ]

30 голосов
/ 06 августа 2011

Большая часть поведения JSLint объясняется на странице инструкций JSLint .Я буду называть его JIP с этого момента.

Большая часть поведения, которое не объясняется JIP, объясняется Соглашениями по коду для языка программирования JavaScript Крокфорда.С этого момента я буду называть его CCJPL.

Для перехода по списку:

1) Почему JSLint выдает ошибку, если вы не включили "use strict";?

Поскольку строгий режим навязывает много хороших практик;JSLint также нацелен на применение передовой практики, поэтому, естественно, это его поведение.Просмотр того, что позволяет "use strict", поможет прояснить ситуацию.Я просто иду вниз по списку этого сообщения в блоге от Resig , так что здесь следует отдать должное.Я не комментирую все, что он делает, потому что я не уверен в точных рассуждениях Крокфорда для каждой функции.

  1. Переменные должны быть объявлены с var, прежде чем вы сможете присвоить значение: это останавливаетсянеявные глобалы от появления.Глобальные переменные рассматриваются Крокфордом как злые, и это помогает устранить глобальные переменные, которые вы не указали явно.
  2. Это несколько ограничивает eval, который Крокфорд считает злым согласно JIP .
  3. Отключает оператор with.Это Крокфорд считает вредным .

Я пропустил только две особенности строгого режима: изменение поведения оператора delete и перезапись переменной arguments.Я не знаю, согласен или не согласен Крокфорд с этими двумя вещами, но, учитывая, что он помог создать стандарт ECMAScript 5, я склонялся бы к согласию.

2) Почему объявления переменных внутри функциидолжно быть сделано с использованием одного var?

Во-первых, любая переменная, которая определена без объявления var, является неявно глобальной, что, согласно JIP , может«Маскировать неправильно написанные имена и другие проблемы».Итак, это рассуждение, требующее var.

Что касается требования one var, все объявления переменных поднимаются на вершину своей области видимостиМеханизм JavaScript автоматически, поэтому я предполагаю, что Крокфорд хочет, чтобы разработчик остро знал об этом.В прошлом это, наверное, вопрос стиля.Что вы предпочитаете между двумя следующими частями кода:

var a, b, c;

или

var a; var b; var c;

Я предполагаю, что Крокфорд считает, что несколько var там ужасны.Я согласен с ним в этом вопросе.

По иронии судьбы, согласно CCJPL , он фактически предлагает разместить все объявления переменных в разных строках с соответствующими комментариями.JSLint не согласен с ним в этом отношении!

3) Зачем нам ставить пробел между function и () в function ()?

Thisприменяется только к анонимным функциям.В соответствии с CCJPL это происходит потому, что:

Если литерал функции является анонимным, между словом function и ((левой скобкой) должен быть один пробел. Еслипробел опущен, и может показаться, что имя функции - это функция, что является неправильным чтением.

Когда я был в гуще изучения JavaScript, я неукоснительно начал следовать соглашениям Крокфорда ... номоя логическая часть говорит, что если у вас есть код, который называет функцию function, то она, вероятно, в любом случае нуждается в доработке (не говоря уже о том, что в JavaScript это SyntaxError, потому что function является ключевым словом).

4) Почему мы не можем использовать continue?

Чтобы процитировать CCJPL :

Это имеет тенденцию затенять поток управления функцией.

Не совсем подробный ответ, но я видел в Интернете аргументы, сравнивающие его с goto.Примите это как хотите.

5) Что не так с ++ и --?

Как сказано в JIP :

Операторы ++ (приращение) и - (приращение), как известно, способствуют плохому коду, поощряя чрезмерную хитрость.Они уступают только неисправной архитектуре в плане защиты от вирусов и других угроз безопасности.Кроме того, путаница в преинкременте и постинкременте может привести к ошибкам, которые очень трудно диагностировать.

6) Почему мы не можем использовать оператор запятой , (кроме случаев, когдачасти инициализации и приращения оператора for?

Еще одно подробное объяснение из JIP :

Оператор запятой может привести кчрезмерно хитрые выражения.Это также может маскировать некоторые ошибки программирования.

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

Во многих конвенциях Крокфорда вы заметите общую тему: понятный, читаемый код.Это просто еще один пример этого.Многие соглашения сосредоточены вокруг запрета доступа к «хитрым» выражениям.

Но я думаю, что реальное слово, которое я использовал бы для описания некоторых из этих выражений, было бы «кратким» - что само по себе не обязательно плохо, но оно может быть злым, если используется неправильно.Соглашения Крокфорда иногда пытаются разбить неправильно использованную краткость, удаляя некоторые инструменты, которые используют эти выражения, даже если они имеют законное использование в некоторых контекстах.

7) Почему каждый оператор должен заканчиваться ;?

Чтобы снова процитировать JIP :

JavaScript использует C-подобный синтаксис, который требует использования точек с запятой для разграничения определенных операторов.JavaScript пытается сделать эти точки с запятой необязательными с помощью механизма вставки точек с запятой.Это опасно, потому что может маскировать ошибки.

Как и C, JavaScript имеет ++ и - и (операторы, которые могут быть префиксами или суффиксами. Устранение неоднозначности выполняется точкой с запятой.

Обычно я нахожу часть объяснений Крокфорда «можно скрыть ошибки» довольно широкой и расплывчатой, но вставка точек с запятой - это действительно та область, в которой я могу искренне согласиться. Проще использовать явные точки с запятой после каждого утверждения, чем рисковать сузить опасные воды.вставки точки с запятой.

Вот классический пример неправильной вставки точки с запятой на странице Википедии на Синтаксис JavaScript :

return
a + b;

// Returns undefined. Treated as:
//   return;
//   a + b;

И если вы используете литерал объектанапример, код из этого поста в блоге (довольно распространенный стиль скобок), тогда он также может вас испортить:

function shoeFactory() {
    return // <--- semicolon inserted here
    {
        shoeSize: 48
    };
}

var shoe = shoeFactory();
console.log(shoe); // undefined

Еще один пример из приведенной выше статьи в Википедии:

a = b + c
(d + e).foo()

// Treated as:
//   a = b + c(d + e).foo();

Меня никогда не беспокоило добавление явных точек с запятой. Они приходят ко мне очень естественно, когдапочти любой код.На самом деле, я часто ловлю себя на том, что ставлю точки с запятой в Python, хотя в этом нет необходимости.

В этом случае я совершенно искренне согласен с Крокфордом.Я думаю, что один сеанс отладки, касающийся вставки точек с запятой, вероятно, убедил бы большинство людей, что было бы легче просто поместить их в код.

12 голосов
/ 05 августа 2011

Вы правы, Крокфорд не очень часто обосновывает свои действия.

Например, определение var s где-то, кроме вершины области действия, на мой взгляд, хорошо, если вы осведомлены . Javascript все равно поднимет их на верхнюю часть области видимости. Кроме того, я думаю, что это действительно полезно, потому что вы можете легко выбрать начальное значение переменной, все, что вам нужно сделать, это найти var.

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

if и for с одним оператором после них, без фигурных скобок, тоже подойдет. Люди писали С таким образом на протяжении десятилетий.

Если вы знаете, что представляет собой конец оператора javascript, точки с запятой также не нужны. Вставка точки с запятой не случайна, она не поддается расшифровке вопреки распространенному мнению.

Крокфорд известен тем, что уничтожает регулярные выражения ... что ужасно. Очень мощные (и быстрые) лексеры могут быть написаны с использованием регулярных выражений в качестве лексем / правил / грамматики / whathaveyou.

По большей части Крокфорд знает, о чем говорит, но не воспринимает его личный стиль как Евангелие. Это очень необоснованно на мой взгляд. Некоторые из лучших javascript-кодеров, которые я видел, прямо противоположны стилю Крокфорда в отношении их кода.

edit: Я не понимаю, почему этот вопрос был закрыт. Об этом можно говорить объективно, и о нем стоит поговорить.

...