renovations

This commit is contained in:
Ilya Kantor 2015-01-10 00:54:38 +03:00
parent 223dd884ae
commit 4b8b168fd2
42 changed files with 562 additions and 490 deletions

View file

@ -27,11 +27,13 @@ else // <- можно на одной строке } else {
Исправленный вариант:
```js
function pow(x,n) {
var result = 1;
function pow(x, n) {
var result = 1;
for(var i = 0; i < n; i++) {
result *=x;
}
}
return result;
}

View file

@ -5,27 +5,70 @@
[cut]
## Синтаксис
Шпаргалка с правилами синтаксиса:
Шпаргалка с правилами синтаксиса (детально они их варианты разобраны далее):
<img src="cheatsheet.png">
Разберём основные моменты.
<img src="code-style.svg">
<!--
```js
function pow(x, n) {
var result = 1;
for (var i = 0; i < n; i++) {
result *=x;
}
return result;
}
var x = prompt("x?", "");
var n = prompt("n?", "");
if (n < 0) {
alert('Степень ' + n +
'не поддерживается, введите целую степень, большую 0');
} else {
alert( pow(x, n) );
}
```
-->
Не всё здесь однозначно, так что разберём эти правила подробнее.
### Фигурные скобки
Пишутся на той же строке, так называемый "египетский" стиль. Перед скобкой -- пробел.
<img src="figure.png">
<!--
```js
if (n < 0) {alert('Степень ' + n + ' не поддерживается');}
Если у вас уже есть опыт в разработке и вы привыкли делать скобку на отдельной строке -- это тоже вариант. В конце концов, решать вам. Но в основных JavaScript-фреймворках (jQuery, Dojo, Google Closure Library, Mootools, Ext.JS, YUI...) стиль именно такой.
Если условие и код достаточно короткие, например `if (cond) return null;`, то запись в одну строку вполне читаема... Но, как правило, отдельная строка всё равно воспринимается лучше.
if (n < 0) alert('Степень ' + n + ' не поддерживается');
if (n < 0) {
alert('Степень ' + n + ' не поддерживается');
}
```
-->
<img src="figure-bracket-style.svg">
Если у вас уже есть опыт в разработке и вы привыкли делать скобку на отдельной строке -- это тоже вариант. В конце концов, решать вам. Но в большинстве JavaScript-фреймворков стиль именно такой.
Если условие и код достаточно короткие, например `if (cond) return null`, то запись в одну строку вполне читаема... Но, как правило, отдельная строка всё равно воспринимается лучше.
### Длина строки
Максимальную длину строки согласовывают в команде. Как правило, это либо `80`, либо `120` символов, в зависимости от того, какие мониторы у разработчиков.
Более длинные строки необходимо разбивать. Если этого не сделать, то перевод очень длинной строки сделает редактор, и это может быть менее красиво и читаемо.
Более длинные строки необходимо разбивать для улучшения читаемости.
### Отступы
@ -36,42 +79,29 @@
Как правило, используются именно пробелы, т.к. они позволяют сделать более гибкие "конфигурации отступов", чем символ "Tab".
Например:
Например, выровнять аргументы относительно открывающей скобки:
```js
function fib(n) {
*!*
var a = 1;
var b = 1;
*/!*
for (var i = 3; i <= n; i++) {
var c = a + b;
a = b;
b = c;
}
return b;
}
show("Строки" +
" выровнены" +
" строго" +
" одна под другой");
```
Кстати, обратите внимание, переменные в выделенном фрагменте объявлены по вертикали, а не в строку `var a=1, b=1`. Так более наглядно, человеческий глаз лучше воспринимает ("сканирует") вертикально выравненную информацию, нежели по горизонтали. Это известный факт среди дизайнеров и нам, программистам, он тоже будет полезен для лучшей организации кода.
</li>
<li>**Вертикальный отступ, для лучшей разбивки кода -- перевод строки.**
Используется, чтобы разделить логические блоки внутри одной функции. В примере ниже разделены функция `pow`, получение данных `x,n` и их обработка `if`.
Используется, чтобы разделить логические блоки внутри одной функции. В примере разделены инициализация переменных, главный цикл и возвращение результата:
```js
function pow(x, n) {
return (n != 1) ? pow(x, n-1) : x;
}
// <--
x = prompt(...);
n = prompt(...);
// <--
if (n >= 1) {
var result = pow(x, n);
alert(result);
var result = 1;
// <--
for (var i = 0; i < n; i++) {
result *=x;
}
// <--
return result;
}
```
Вставляйте дополнительный перевод строки туда, где это сделает код более читаемым. Не должно быть более 9 строк кода подряд без вертикального отступа.
@ -82,9 +112,7 @@ if (n >= 1) {
Точки с запятой нужно ставить, даже если их, казалось бы, можно пропустить.
Есть языки, в которых точка с запятой не обязательна, и её там никто не ставит. В JavaScript она тоже не обязательна, но ставить нужно. В чём же разница?
Она в том, что **в JavaScript без точки с запятой возможны трудноуловимые ошибки.** С некоторыми примерами вы встретитесь дальше в учебнике. Такая вот особенность синтаксиса. И поэтому рекомендуется её всегда ставить.
Есть языки, в которых точка с запятой не обязательна, и её там никто не ставит. В JavaScript перевод строки её заменяет, но лишь частично, поэтому лучше её ставить, как обсуждалось [ранее](#semicolon).
## Именование
@ -102,7 +130,7 @@ if (n >= 1) {
Уровней вложенности должно быть немного.
Например, [проверки в циклах лучше делать через "continue"](#continue), чтобы не было дополнительного уровня `if(..) { ... }`:
Например, [проверки в циклах можно делать через "continue"](#continue), чтобы не было дополнительного уровня `if(..) { ... }`:
Вместо:
@ -159,21 +187,15 @@ function isEven(n) { // проверка чётности
В случае с функцией `isEven` можно было бы поступить и проще:
```js
function isEven(n) { // проверка чётности
return n % 2 == 0;
}
```
..Казалось бы, можно пойти дальше, есть ещё более короткий вариант:
```js
function isEven(n) { // проверка чётности
return !(n % 2);
}
```
...Однако, код `!(n % 2)` менее очевиден чем `n % 2 == 0`. Поэтому, на самом деле, последний вариант хуже. **Главное для нас -- не краткость кода, а его простота и читаемость.**
...Однако, если код `!(n % 2)` для вас менее очевиден чем предыдущий вариант, то стоит использовать предыдущий.
Главное для нас -- не краткость кода, а его простота и читаемость. Совсем не всегда более короткий код проще для понимания, чем более развёрнутый.
## Функции = Комментарии
@ -185,7 +207,7 @@ function isEven(n) { // проверка чётности
Сравните, например, две функции `showPrimes(n)` для вывода простых чисел до `n`.
Первый вариант:
Первый вариант использует метку:
```js
function showPrimes(n) {
@ -201,7 +223,7 @@ function showPrimes(n) {
}
```
Второй вариант, вынесена подфункция `isPrime(n)` для проверки на простоту:
Второй вариант -- дополнительную функцию `isPrime(n)` для проверки на простоту:
```js
function showPrimes(n) {
@ -277,28 +299,41 @@ function walkAround() {
</li>
</ol>
...На самом деле существует еще третий "стиль", при котором функции хаотично разбросаны по коду ;), но это ведь не наш метод, да?
...На самом деле существует еще третий "стиль", при котором функции хаотично разбросаны по коду, но это ведь не наш метод, да?
**Как правило, лучше располагать функции под кодом, который их использует.** То есть, это 2й способ.
**Как правило, лучше располагать функции под кодом, который их использует.**
Дело в том, что при чтении такого кода мы хотим знать в первую очередь, *что он делает*, а уже затем *какие функции ему помогают.* Если первым идёт код, то это как раз дает необходимую информацию. Что же касается функций, то вполне возможно нам и не понадобится их читать, особенно если они названы адекватно и то, что они делают, понятно.
То есть, предпочтителен 2й способ.
У первого способа, впрочем, есть то преимущество, что на момент чтения мы уже знаем, какие функции существуют.
Дело в том, что при чтении такого кода мы хотим знать в первую очередь, *что он делает*, а уже затем *какие функции ему помогают.* Если первым идёт код, то это как раз дает необходимую информацию. Что же касается функций, то вполне возможно нам и не понадобится их читать, особенно если они названы адекватно и то, что они делают, понятно из названия.
Таким образом, если над названиями функций никто не думает -- может быть, это будет лучшим выбором :). Попробуйте оба варианта, но по моей практике предпочтителен всё же второй.
## Комментарии
## Плохие комментарии
В коде нужны комментарии.
**Как правило, комментарии отвечают на вопрос "что происходит в коде?"**
Сразу начну с того, каких комментариев быть почти не должно.
**Должен быть минимум комментариев, которые отвечают на вопрос "что происходит в коде?"**
Что интересно, в коде начинающих разработчиков обычно комментариев либо нет, либо они как раз такого типа: "что делается в этих строках".
Серьёзно, хороший код и так понятен.
Об этом замечательно выразился Р.Мартин в книге ["Чистый код"](http://www.ozon.ru/context/detail/id/21916535/): "Если вам кажется, что нужно добавить комментарий для улучшения понимания, это значит, что ваш код недостаточно прост, и, может, стоит переписать его".
Если у вас образовалась длинная "простыня", то, возможно, стоит разбить её на отдельные функции, и тогда из их названий будет понятно, что делает тот или иной фрагмент.
Да, конечно, бывают сложные алгоритмы, хитрые решения для оптимизации, поэтому нельзя такие комментарии просто запретить. Но перед тем, как писать подобное -- подумайте: "Нельзя ли сделать код понятным и без них?"
## Хорошие комментарии
А какие комментарии полезны и приветствуются?
Например:
<ul>
<li>**Архитектурный комментарий -- "как оно, вообще, устроено".**
Какие компоненты есть, какие технологии использованы, поток взаимодействия. О чём и зачем этот скрипт. Эти комментарии особенно нужны, если вы не один.
Какие компоненты есть, какие технологии использованы, поток взаимодействия. О чём и зачем этот скрипт. Взгляд с высоты птичьего полёта. Эти комментарии особенно нужны, если вы не один, а проект большой.
Для описания архитектуры, кстати, создан специальный язык [UML](http://ru.wikipedia.org/wiki/Unified_Modeling_Language), красивые диаграммы, но можно и без этого. Главное -- чтобы понятно.
</li>
@ -319,18 +354,11 @@ function pow(x, n) {
}
```
Такие комментарии позволяют сразу понять, что принимает и что делает функция, не вникая в код.
Такие комментарии позволяют сразу понять, что принимает и что делает функция, не вникая в код.
Кстати, они автоматически обрабатываются многими редакторами, например [Aptana](http://aptana.com) и редакторами от [JetBrains](http://www.jetbrains.com/), которые учитывают их при автодополнении.
</li>
<li>**Краткий комментарий, что именно происходит в данном блоке кода.**
Что интересно, в коде начинающих разработчиков обычно комментариев либо нет, либо они как раз такого типа: "что делается в этих строках кода".
На самом деле именно эти комментарии, как правило, являются самыми ненужными. Хороший код и так самоочевиден, если не используются особо сложные алгоритмы.
Об этом замечательно выразился Р. Мартин в книге ["Чистый код"](http://www.ozon.ru/context/detail/id/21916535/): "Если вам кажется, что нужно добавить комментарий для улучшения понимания, это значит, что ваш код не достаточно прост, и, может, стоит переписать его".
Кстати, они автоматически обрабатываются многими редакторами, например [Aptana](http://aptana.com) и редакторами от [JetBrains](http://www.jetbrains.com/), которые учитывают их при автодополнении, а также выводят их в автоподсказках при наборе кода.
Кроме того, есть инструменты, например [JSDoc 3](https://github.com/jsdoc3/jsdoc), которые умеют генерировать по таким комментариям документацию в формате HTML. Более подробную информацию об этом можно также найти на сайте [](http://usejsdoc.org/).
</li>
</ul>
@ -342,9 +370,9 @@ function pow(x, n) {
Например:
<ul>
<li>**Есть несколько способов решения задачи. Почему выбран именно этот?**
<dl>
<dt>Есть несколько способов решения задачи. Почему выбран именно этот?</dt>
<dd>
Например, пробовали решить задачу по-другому, но не получилось -- напишите об этом. Почему вы выбрали именно этот способ решения? Особенно это важно в тех случаях, когда используется не первый приходящий в голову способ, а какой-то другой.
Без этого возможна, например, такая ситуация:
@ -354,18 +382,18 @@ function pow(x, n) {
<li>...Порыв, конечно, хороший, да только этот вариант вы уже обдумали раньше. И отказались, а почему -- забыли. В процессе переписывания вспомнили, конечно (к счастью), но результат - потеря времени на повторное обдумывание.</li>
</ul>
Комментарии, которые объясняют поведение кода, очень важны. Они помогают понять происходящее и принять правильное решение о развитии кода.
</li>
<li>**Какие неочевидные возможности обеспечивает этот код?** Где в другом месте кода они используются?
Комментарии, которые объясняют выбор решения, очень важны. Они помогают понять происходящее и предпринять правильные шаги при развитии кода.
</dd>
<dt>Какие неочевидные возможности обеспечивает этот код? Где ещё они используются?</dt>
<dd>
В хорошем коде должно быть минимум неочевидного. Но там, где это есть -- пожалуйста, комментируйте.
</li>
</dd>
</dl>
</ul>
[smart header="Комментарии -- это важно"]
Один из показателей хорошего разработчика -- качество комментариев, которые позволяют эффективно поддерживать код, возвращаться к нему после любой паузы и легко вносить изменения.
[/smart]
## Руководства по стилю
@ -382,21 +410,23 @@ function pow(x, n) {
<li>[Dojo Style Guide](http://dojotoolkit.org/community/styleGuide)</li>
</ul>
Для того, чтобы начать разработку, вполне хватит элементов стилей, обозначенных в этой главе. В дальнейшем, посмотрите на эти руководства, найдите "свой" стиль ;)
Для того, чтобы начать разработку, вполне хватит элементов стилей, обозначенных в этой главе. В дальнейшем, посмотрев эти руководства, вы можете выработать и свой стиль, но лучше не делать его особенно "уникальным и неповторимым", себе дороже потом будет с людьми сотрудничать.
### Автоматизированные средства проверки
Существуют онлайн-сервисы, проверяющие стиль кода.
Существуют средства, проверяющие стиль кода.
Самые известные -- это:
<ul>
<li>[JSLint](http://www.jslint.com/) -- проверяет код на соответствие [стилю JSLint](http://www.jslint.com/lint.html), в онлайн-интерфейсе вверху можно ввести код, а внизу различные настройки проверки, чтобы сделать её более мягкой. </li>
<li>[JSHint](http://www.jshint.com/) -- ещё один вариант JSLint, ослабляющий требования в ряде мест.</li>
<li>[JSHint](http://www.jshint.com/) -- вариант JSLint с большим количеством настроек.</li>
<li>[Closure Linter](https://developers.google.com/closure/utilities/) -- проверка на соответствие [Google JavaScript Style Guide](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml).</li>
</ul>
Все они также доступны в виде программ, которые можно скачать.
В частности, JSLint и JSHint интегрированы с большинством редакторов, они гибко настраиваются под нужный стиль и совершенно незаметно улучшают разработку, подсказывая, где и что поправить.
Побочный эффект -- они видят некоторые ошибки, например необъявленные переменные. У меня это обычно результат опечатки, которые таким образом сразу отлавливаются. Очень рекомендую поставить что-то из этого. Я использую [JSHint](http://www.jshint.com/).
## Итого

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 125 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB