Подтвердить что ты не робот

Обоснование заявлений Крокфорда

Я прочитал Crockford JavaScript: Хорошие части и использовал свой валидатор JSLint. Иногда мне остается удивляться обоснованию его рекомендаций. Ниже приведен список примеров, которые я хочу обосновать.


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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Чтобы перейти по списку:

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

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

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

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

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

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

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

var a, b, c;

или

var a; var b; var c;

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

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

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

Это относится только к анонимным функциям. Согласно CCJPL, это происходит потому, что:

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

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

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

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

Он имеет тенденцию скрывать управляющий поток функции.

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

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

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

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

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, даже если они не нужны.

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

Ответ 2

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

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

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

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

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

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

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

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