renovations
This commit is contained in:
parent
223dd884ae
commit
4b8b168fd2
42 changed files with 562 additions and 490 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 |
94
1-js/3-writing-js/2-coding-style/code-style.svg
Normal file
94
1-js/3-writing-js/2-coding-style/code-style.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 125 KiB |
32
1-js/3-writing-js/2-coding-style/figure-bracket-style.svg
Normal file
32
1-js/3-writing-js/2-coding-style/figure-bracket-style.svg
Normal file
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 |
Loading…
Add table
Add a link
Reference in a new issue