В прошлом мне доводилось писать много некачественного кода. Пересматривая его фрагменты, начинаю даже сомневаться, гожусь ли на роль программиста. Чтобы с вами такого не было, поучитесь на моих ошибках.

1. Неправильное использование промисов

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

// ❌
getUserInfo()
.then((userInfo) => {
getArticles(userInfo)
.then((articles) => {
Promise.all(articles.map((article) => getArticleDetail(article)))
.then((articleDetails) => {
console.log(articleDetails)
})
})
})

Этот фрагмент кода выполняет следующие действия:

  1. Получает основную информацию о пользователе.
  2. Получает краткое резюме всех статей по информации о пользователе.
  3. Получает детали статьи через краткое описание статей.

Тут совершенно не используются преимущества промисов в отличие от приведенного ниже фрагмента:

// ✅
getUserInfo()
.then((getArticles)
.then((articles) => {
return Promise.all(articles.map((article) => getArticleDetail(article)))
})
.then((articleDetails) => {
console.log(articleDetails)
})

2. Игнорирование сообщений об ошибках

Прописывая логику кода для успешных запросов, мы порой игнорируем неудачные запросы.

// ❌
const getUserInfo = async () => {
try {
const userInfo = await fetch('/api/getUserInfo')
} catch (err) {

}
}

Такой код  —  признак неопытности программиста. Необходимо реализовать удобную для пользователя подсказку, а не пускать все на самотек. 

// ✅
const getUserInfo = async () => {
try {
const userInfo = await fetch('/api/getUserInfo')
} catch (err) {
Toast(err.message)
}
}

3. Функции со слишком большим количеством параметров 

Допустим, нужно получить ряд базовых данных о пользователе: имя, пол, возраст и т. д.

// ❌
const getUserInfo = (name, age, weight, gender, mobile , nationality, hobby, address) => {
// ...
}
getUserInfo('fatfish', 100, 2000, ...)

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

// ✅
const getUserInfo = (options) => {
const { name, gender, age, mobile, weight, nationality, hobby, address } = options
// ...
}
getUserInfo({
name: 'fatfish',
age: 100,
weight: 2000
// ...
})

4. Волшебные числа

Вы когда-нибудь писали код, похожий на тот, что приведен ниже? Стоит ли повсеместно использовать числа для логических суждений? Только вот мне не понятно, что именно означают 1, 2, 3.


// component1.js
if (status === 1 || status === 2) {
// ...
} else if (status === 3) {
// ...
}
// component2.js
if (status === 1 || status === 2) {
// ...
}

Лучше определить эти числа как константы.

// ✅
// constants.js
export const STATUS = {
// Это взрослый человек, и он проходит аутентификацию под реальным именем
adultRealName: 1,
// Это несовершеннолетний человек, и он проходит аутентификацию под реальным именем
minorRealName: 2,
// Нет аутентификации под реальным именем
notRealName: 3,
// ...
}
// component1.js
import { STATUS } from './constants.js'
if ([ STATUS.adultRealName, STATUS.minorRealName ].includes(status)) {
// ...
} else if (status === STATUS.notRealName) {
// ...
}
// component2.js
import { STATUS } from './constants.js'
// component2.js
if ([ STATUS.adultRealName, STATUS.minorRealName ].includes(status)) {
// ...
}

5. Использование .length для суждения о длине строки

В большинстве случаев использование .length для суждения о длине строки безопасно. Но следует быть осторожным в случае ввода формы.

При вводе 🍫 значение nameLen будет равно 2. Что за странности?

// ❌
<input type="text" id="name">
<script>
const $name = document.getElementById('name')
$name.addEventListener('blur', () => {
const name = $name.value
const nameLen = name.length
// ввод: fatfish => nameLen: 7
// ввод: 🍫 => nameLen: 2
console.log(`name: ${name}, nameLen: ${nameLen}`)
}, false)
</script>

И на это есть причина.

// ✅
<input type="text" id="name">
<script>
const $name = document.getElementById('name')
$name.addEventListener('blur', () => {
const name = $name.value
const nameLen = name.length
const spRegexp = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g
const nameRealLen = name.replace(spRegexp, '_').length
// ввод: fatfish => nameLen: 7, nameRealLen: 7
// ввод: 🍫 => nameLen: 2, nameRealLen: 1
console.log(`name: ${name}, nameLen: ${nameLen}, nameRealLen: ${nameRealLen}`)
}, false)
</script>

6. Отсутствие комментариев к коду

Мы часто упрекаем в этом коллег, но себя не утруждаем комментированием.

// ❌
const fn = (dpr) => {
if (dpr >= 2) {
// ...
} else {
}
}

Как думаете, что значит dpr? Это window devicePixelRatio.

// ✅
// dpr: Введите значение для window.devicePixelRatio
const fn = (dpr) => {
if (dpr >= 2) {
// ...
} else {
}
}

7. Бессмысленные комментарии к коду

Хуже полного отсутствия комментариев к коду могут быть только бессмысленные комментарии. Их чтение отнимает кучу времени.

Почему бы не объяснить, что означает “a” или использовать осмысленные имена переменных?

// ❌
let a = 1 // Установите значение "a" в 1

8. Случайное именование

Фрагменты кода со случайными именами переменных затрудняют чтение.

// ❌
const mw = 375

Лучше давать переменным корректные и осмысленные имена.


const maxWidth = 375

9. Сохранение устаревшего кода

Функции на сайте постоянно корректируются. В результате появляются новые и устаревшие функции. Но программист-новичок ничего не удаляет, поскольку беспокоится: а вдруг устаревшие функции пригодятся в будущем?

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

10. Более тысячи строк в коде компонента

У вас получилось более тысячи строк в коде компонента? Это никуда не годится. Следует разделить функциональность на более мелкие компоненты.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи fatfish: 10 Must-Know JavaScript Tricks & Tips to Make You a Better Programmer

Предыдущая статьяСоздание среды AWS Boto3 на Python с Docker Compose
Следующая статьяСпецификация API — основа успешной разработки