Кращий код на JavaScript

Я чітко пам’ятаю свої студентські роки і своє перше знайомство з JavaScript. Окрім C та C++, JavaScript був третьою мовою програмування, яку я вивчав. Не зрозумійте мене неправильно, але це сталося в період, що охоплював перший семестр мого другого курсу.

Тоді не було Node.js, React або Vue. Це була ера чистого JavaScript і неймовірної бібліотеки jQuery — час JavaScript анімацій, рухомих елементів і Ajax запитів. Тоді JavaScript був в основному інструментом, що працює в браузерах.

pic

Фото створене DEEPAI.

У ті часи JavaScript був менш стандартизованим, простішим і, чесно кажучи, трохи наївним.

Нова ера JavaScript

Перемотаємо на сьогодні, і JavaScript скрізь. Тепер у нас є краща стандартизація, сучасні підходи, TypeScript, збірники модулів, і JavaScript, що живить як фронтенд, так і бекенд розробку. Його також використовують для машинного навчання, фреймворків, мобільної розробки, IoT, веб, консольних і десктопних додатків.

Світ еволюціонував, прийнявши кращий JavaScript. Тепер він доступніший, відкритий і підтримується спільнотою.

Однак не все так безхмарно, як здається. Разом з цими досягненнями приходять виклики, такі як застарілі функції і технічний борг, які розробники повинні долати, щоб виконати свою роботу.

Для уточнення: JavaScript може бути неймовірним, але він також може бути джерелом розчарувань.

Як зробити код JavaScript кращим?

Все просто — залежить від того, як ви його пишете і тестуєте належним чином. Це вимагає постійного оновлення знань про тенденції і дотримання загальних практик і стандартів.

У цьому пості я поділюсь кількома порадами, як писати кращий код на JavaScript.

1. Використовуйте let і const замість var
Використовуйте let і const замість var при оголошенні змінних. Вони надають блочну область видимості і допомагають запобігти проблемам, пов'язаним з піднесенням змінних (hoisting).

Приклад:

let name = 'nanorocks';  
const age = 30;

2. Деструктуризація

Використовуйте деструктуризацію для витягування значень з масивів або властивостей об'єктів і безпосереднього присвоєння їх змінним, спрощуючи ваш код.

Приклад:

const person = { name: 'Fill', age: 25 };  
const { name, age } = person;
const numbers = [1, 2, 3];  
const [first, second] = numbers;

3. Використання console для ефективного дебаггінгу

Використовуйте різні методи console для ефективнішого дебаггінгу.

Приклад:

console.log('Log message');  
console.warn('Warning message');  
console.error('Error message');  
console.table([{ name: 'Eva', score: 90 },{ name: 'Dimi', score: 85 }]);  
console.group('Grouped Logs');  
console.log('Log 1');  
console.log('Log 2');  
console.groupEnd();

4. Шаблонні рядки
Використовуйте шаблонні рядки для створення чистих і зрозумілих рядків. На відміну від традиційного конкатенування рядків, шаблонні рядки дозволяють вставляти змінні та вирази безпосередньо в зворотних лапках за допомогою синтаксису ${}. Це підвищує ясність і зменшує ймовірність помилок при створенні динамічних рядків, особливо у складних сценаріях, таких як багаторядкові рядки або вбудовування кількох змінних.

Приклад:

const userName = 'Andrej';  
const age = 30;  
const message = `Hello, ${userName}! You are ${age} years old.`;  
console.log(message);

5. Стрілкові функції

Стрілкові функції пропонують компактніший синтаксис порівняно з традиційними функціями, що робить ваш код чистішим і зручнішим для читання. Крім того, вони автоматично прив'язують контекст this лексично, що спрощує роботу з ключовим словом this у таких ситуаціях, як обробка подій або зворотні виклики (callback functions).

Стрілкові функції особливо корисні при написанні однорядкових функцій або при роботі з методами масивів, такими як map(), filter() та reduce().
Однак вони не мають власного контексту this, arguments або prototype, тому їх не слід використовувати як конструктори або методи, що потребують динамічного зв'язування this.

Приклад:

// Традиційна функція  
const add = function (a, b) {  
 return a + b;  
};
 // Стрілкова функція 
const add = (a, b) => a + b;  
console.log(add(5, 3)); // Виведе: 8

6. Оператор поширення
Оператор поширення дозволяє розширювати елементи ітерабельних об'єктів (наприклад, масивів) або властивості об'єктів.

Приклад:

const arr1 = [1, 2, 3];  
const arr2 = [...arr1, 4, 5];
const obj1 = { name: 'John' };  
const obj2 = { ...obj1, age: 30 };

7. Параметри решти
Параметри решти дозволяють передати невизначену кількість аргументів як масив.

Приклад:

function sum(...numbers) {  
 return numbers.reduce((total, num) => total + num, 0);  
}

8. Оцінка з коротким замиканням (&& та ||)
Використовуйте оцінку з коротким замиканням для умовних виразів і значень за замовчуванням.

Приклад:

const user = { name: 'Jarvis' };  
const name = user.name || 'Гість';  
const isAdmin = user.isAdmin && 'Адміністратор';

9. Стиснута синтаксис властивості об'єкта
Використовуйте стиснутий синтаксис для створення об'єктів, коли ім'я властивості та змінної збігаються.

Приклад:

const name = 'Borey';  
const age = 27;  
const person = { name, age };

10. Опціональний ланцюжок ?.
Опціональний ланцюжок дозволяє безпечно отримувати доступ до вкладених властивостей, не перевіряючи кожну посилання на її дійсність.

Приклад:

const user = { name: 'Bob', address: { city: 'Orman' } };  
const city = user.address?.city;

11. Операція злиття з null ??
Операція злиття з null (??) дозволяє повернути правий операнд, якщо лівий операнд є null або undefined.

Приклад:

const settings = { theme: null };  
const theme = settings.theme ?? 'Тема за замовчуванням';  
console.log(theme); // 'Тема за замовчуванням'

12. Ланцюжок Promise та Async/Await
Операції з асинхронними викликами можна обробляти за допомогою Promises та синтаксису async/await для більш чистого і зрозумілого коду.

Примітка: коли мова йде про вкладені API виклики, важливо ефективно керувати асинхронним кодом. Уникайте callback hell використовуючи сучасні методи, такі як Promises або async/await для чистого та зручного коду.

Приклад з Promises:

fetch('https://api.example.com/users')  
 .then(response => response.json())  
 .then(users => console.log(users))  
 .catch(error => console.error('Помилка:', error));

Приклад з Async/Await:

async function fetchUsers() {  
 try {  
 const response = await fetch('https://api.example.com/users');  
 const users = await response.json();  
 console.log(users);  
 } catch (error) {  
 console.error('Помилка:', error);  
 }  
}  
fetchUsers();

Приклад callback hell.
Уникайте цього.

const https = require('https');
function getTodos(callback) {  
 https.get('https://dummyjson.com/todos', (res) => {  
 let data = '';  
 res.on('data', chunk => {  
 data += chunk;  
 });  
 res.on('end', () => {  
 const todos = JSON.parse(data);  
 callback(null, todos);  
 });  
 }).on('error', (err) => {  
 callback(err, null);  
 });  
}function getTodoById(id, callback) {  
 https.get(`https://dummyjson.com/todos/${id}`, (res) => {  
 let data = '';  
 res.on('data', chunk => {  
 data += chunk;  
 });  
 res.on('end', () => {  
 const todo = JSON.parse(data);  
 callback(null, todo);  
 });  
 }).on('error', (err) => {  
 callback(err, null);  
 });  
}// Callback Hell Example  
getTodos((err, todos) => {  
 if (err) {  
 console.error('Error fetching todos:', err);  
 return;  
 }  
 console.log('Fetched todos:', todos); // Get the first todo's details  
 getTodoById(todos[0].id, (err, todo) => {  
 if (err) {  
 console.error('Error fetching todo details:', err);  
 return;  
 }  
 console.log('Fetched todo details:', todo); // Get the second todo's details  
 getTodoById(todos[1].id, (err, todo) => {  
 if (err) {  
 console.error('Error fetching todo details:', err);  
 return;  
 }  
 console.log('Fetched second todo details:', todo);  
 });  
 });  
});

13. Клонування об'єктів та масивів
Використовуйте оператор поширення (...) для створення поверхневих копій об'єктів та масивів. Альтернативне посилання: https://developer.mozilla.org/en-US/docs/Web/API/Window/structuredClone

Приклад:

const book = { title: '1984', author: 'George Orwell' };  
const bookClone = { ...book };  
const numbers = [5, 10, 15];  
const numbersClone = [...numbers];

14. Використання setTimeout та setInterval
Заплануйте виконання коду за допомогою setTimeout та setInterval. Чудове пояснення концепції polling можна знайти тут.

Приклад:

setTimeout(() => {  
 console.log('Виконано через 1 секунду');  
}, 1000);
const intervalId = setInterval(() => {  
 console.log('Повторюється кожні 2 секунди');  
}, 2000);  
// Щоб очистити інтервал  
setTimeout(() => clearInterval(intervalId), 10000); // Зупиняється після 10 секунд

15. Методи масивів і рядків для ефективної маніпуляції даними
Поєднуючи методи масивів, такі як map(), filter() і reduce(), з сучасними методами рядків, такими як includes(), startsWith() та endsWith(), можна виконувати ефективну та виразну маніпуляцію даними. Ці методи дозволяють швидко перетворювати, фільтрувати та шукати через масиви та рядки, покращуючи читабельність і підтримуваність вашого коду.

Приклад:

const sentence = 'JavaScript is fun and versatile';
// Розділити речення на масив слів  
const words = sentence.split(' ');  
// Фільтруємо слова, які містять літеру 'a', і перетворюємо їх на великі літери  
const filteredAndUppercased = words.filter(word => word.includes('a')).map(word => word.toUpperCase());  
// Об'єднуємо масив назад у рядок і перевіряємо, чи починається він з 'JAVASCRIPT'  
const result = filteredAndUppercased.join(' ');  
const startsWithJavaScript = result.startsWith('JAVASCRIPT');  
console.log(result); // Виведе: "JAVASCRIPT AND VERSATILE"  
console.log(startsWithJavaScript); // Виведе: true

У цьому прикладі ми використовуємо метод split(), щоб перетворити рядок на масив, потім фільтруємо масив за допомогою filter() і перетворюємо його за допомогою map(). В кінці перевіряємо результатуючий рядок за допомогою startsWith(). Це поєднання методів масивів і рядків дозволяє легко працювати з комплексними трансформаціями рядків у зручний і зрозумілий спосіб.

16. Використання регулярних виразів (Regex) для пошуку патернів
Регулярні вирази (regex) — потужний інструмент для пошуку патернів і маніпуляції рядками.
Вони дозволяють шукати, знаходити, замінювати та перевіряти рядки з комплексними патернами. За допомогою регулярних виразів (regex) можна виконувати операції, такі як валідація електронних адрес, витягування телефонних номерів або пошук конкретних слів у тексті.

Патерни регулярних виразів можна використовувати з методами, такими як match(), replace(), test() та split(), що робить їх універсальними для широкого спектру завдань обробки рядків.

Приклад:

const email = '[email protected]';  
const regex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
const isValidEmail = regex.test(email);  
console.log(isValidEmail); // Виведе: true

У цьому прикладі використовується патерн регулярного виразу для валідації електронної адреси. Метод test() перевіряє, чи відповідає рядок заданому патерну.

Сайти для легкого створення регулярних виразів:

  • Regex101: Популярний онлайн-тестер регулярних виразів, який надає реальний час для матчингів, пояснення та детальне посилання на довідник.
  • RegExr: Зручний інструмент для створення, тестування та розуміння регулярних виразів з корисною бібліотекою посилань та прикладами від спільноти.

17. Динамічні імена властивостей
Використовуйте обчислювані імена властивостей для динамічного встановлення властивостей об'єктів.

Приклад:

const key = 'color';  
const car = {  
 brand: 'Toyota',  
 [key]: 'red',  
};  
console.log(car); // { brand: 'Toyota', color: 'red' }

18. Логічні оператори присвоєння (&&=, ||=)

Логічні оператори присвоєння спрощують умовне оновлення значень:

&&=: Оновлює значення тільки, якщо воно є істинним.
Приклад:

let isAuthenticated = true;   
isAuthenticated &&= 'Authorized'; // Стає 'Authorized'

||=: Оновлює значення тільки, якщо воно є хибним.
Приклад:

let userType = '';   
userType ||= 'Guest'; // Стає 'Guest'

Заключні слова

Кращий JavaScript приходить з відданістю написанню чистого, читабельного коду та ретельному тестуванню. Прийняття новітніх тенденцій, інструментів та загальних практик забезпечує, що наш код залишатиметься підтримуваним, ефективним та готовим до майбутнього. Тому, незалежно від того, чи тільки починаєте ви, чи є відкритим розробником з відкритим кодом, пам'ятайте, що залишатися цікавим та постійно вдосконалювати свої навички — це те, що в кінцевому підсумку робить JavaScript не тільки кращим, а й більш приємним.

Я зробив усе можливе, щоб поділитися деякими своїми ідеями про JS. Не соромтеся коментувати і ділитися вашими думками. Давайте рости, співпрацювати і вчитися разом.

До наступного разу…

Перекладено з: Better JavaScript Code

Leave a Reply

Your email address will not be published. Required fields are marked *