Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Писать более качественный код.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
79.29 Кб
Скачать

5. Близость

Нужно объявлять переменные как можно ближе к месту их использования.

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

function () {

var a = getA(),

b = getB(),

c = getC(),

d = getD();

doSomething(b);

doAnotherThing(a);

doOtherStuff(c);

finishUp(d);

}

getA() и другие подобные функции не определены в этом сегменте кода, но представьте, что они возвращают полезные значения.

Смотря на этот небольшой метод, можно подумать, что код хорошо организован и легко читается. Но это не так. d, по какой-то причине, объявляется в строке 4, хотя она не используется до строки 9, а это значит, что нужно прочитать весь метод, чтобы убедиться, что переменная больше нигде не используется.

Хорошо организованный метод будет выглядеть так:

function () {

var b = getB();

doSomething(b);

var a = getA();

doAnotherThing(a);

var c = getC();

doOtherStuff(c);

var d = getD();

finishUp(d);

}

Теперь понятно, что переменная будет использоваться сразу после ее объявления.

Конечно, в большинстве случаев ситуация не настолько простая. Что, если b нужно передать два метода: doSomething() и doOtherStuff()? В этом случае вашей задачей будет взвесить параметры и убедиться, что метод все еще прост для чтения (в первую очередь, оставляя его небольшим). В любом случае нужно убедиться в том, что b не объявляется раньше момента ее использования и используется в ближайшем сегменте кода.

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

6. Многоуровневое вложение кода (Deep nesting)

JavaScript известен своей сложной ситуацией, известной как «callback hell»:

Видите )};,повторяющийся начиная с середины кода? Это и есть пресловутый ад обратного вызова (callback hell). Этого можно избежать, но это история для еще одной статьи.

Но давайте рассмотрим нечто, что называется if hell.

callApi().then(function (result) {

try {

if (result.status === 0) {

model.apiCall.success = true;

if (result.data.items.length > 0) {

model.apiCall.numOfItems = result.data.items.length;

if (isValid(result.data) {

model.apiCall.result = result.data;

}

}

}

} catch (e) {

// suppress errors

}

});

Подсчитайте пары фигурных скобок { }. Шесть из которых вложены. Это слишком много. Этот блок кода трудно читать частично из-за того, что код вот-вот закроет правую сторону экрана, а программисты ненавидят горизонтальную прокрутку, ведь придется прочитать все условия if, чтобы выяснить, как вы попали на строку 10.

Теперь посмотрим на это:

callApi().then(function (result) {

if (result.status !== 0) {

return;

}

model.apiCall.success = true;

if (result.data.items.length <= 0) {

return;

}

model.apiCall.numOfItems = result.data.items.length;

if (!isValid(result.data)) {

return;

}

model.apiCall.result = result.data;

});

Так намного лучше. Теперь это нормальный путь кода, и только в некоторых ситуациях код отклоняется в блок if. Процесс отладки упрощается в разы. И если мы хотим добавить дополнительный код для обработки условий ошибки, можно легко написать пару строк внутри этих блоков if (а представьте, что блоки if в исходном коде также имели бы блоки else, ужас).

Кроме этого, были удалены блоки try-catch, потому что не нужно подавлять ошибки. Ошибки — ваш друг, и без них приложение станет мусором.