Мы часто сталкиваемся с тем, что многочисленные ресурсы и руководства по JavaScript предлагают свой уникальный подход к кодированию. И хотя они дают ценные знания, порой они также могут создавать проблемы с пониманием кода из-за непоследовательных соглашений об именовании и неясных структур.
Это руководство посвящено написанию чистого и удобного кода на JavaScript и TypeScript. Мы рассмотрим лучшие практики работы с функциями, переменными и методами, чтобы ваш код был не только эффективным, но и понятным как вам, так и другим разработчикам. Статья будет полезна для новичков, которые хотят улучшить свои навыки кодирования.
Имена переменных
Одним из ключевых принципов написания чистого и удобного кода является использование осмысленных имен переменных и функций. Читаемость кода имеет решающее значение для командной работы и для дальнейшего обращения к вашему коду в будущем. Использование описательных имен, которые точно передают назначение и функциональность переменных и функций, является важным шагом к достижению этой цели.
Избегайте соблазна использовать однобуквенные имена переменных или загадочные сокращения, которые могут затруднить чтение и понимание вашего кода. При выборе имен для переменных всегда стремитесь к ясности и информативности.
Давайте рассмотрим эту концепцию на примере JavaScript и TypeScript:
// Плохой подход var c; var d; var cd; var u; // Хороший подход let counter = 0; let date = null; let currentDate = null; let user = "";
Булевы (или логические) переменные
При работе с логическими переменными в JavaScript и TypeScript важно поддерживать ясность в коде. Вместо использования одиночных букв или неоднозначных слов, постарайтесь называть логические переменные в виде вопросов или утверждений, которые чётко передают их назначение. TypeScript добавляет к JavaScript мощный уровень статической типизации, что ещё больше повышает читаемость и поддерживаемость кода.
Вот пример того, как писать чистые и понятные логические переменные на TypeScript:
var v=false; var w=false; var c=false; var l=false; // Наилучший подход в данном случае let isValid: boolean = false; let isWritable: boolean = false; let isCleared: boolean = false; let isLoading: boolean = false;
Числовые переменные
При работе с числовыми переменными в коде JavaScript и TypeScript важно использовать осмысленные и описательные имена переменных. Эта практика улучшает читаемость и сопровождение кода, облегчая вам и вашей команде понимание, почему назначены эти переменные. Вместо использования вызывающих вопросы имён, таких как bMax, bMin и bTot, выбирайте имена, которые чётко передают их смысл. Кроме того, используйте систему типов TypeScript для обеспечения типобезопасности — это помогает выявлять потенциальные ошибки на этапе разработки.
Ниже улучшенный пример на TypeScript:
var bMax=false; var bMin=false; var bTot=false; // Наилучший подход в данном случае let booksMaximum: number = 50; let booksMinimum: number = 1; let booksTotal: number = 51;
Имена массивов
При работе с массивами или списками в JavaScript и TypeScript также важно выбирать осмысленные и описательные имена для ваших переменных. Используйте стиль написания camelCase для наименования и давайте понятные имена, которые указывают на назначение массива. Вот как можно улучшить код:
// Плохой подход к именованию и отсутствие информации о типе var f = ["Mango", "Papaya", "Apple", "Banana"]; var c = ["Mazda", "Toyota", "Nissan", "Ford"]; var m = ["Fish", "Pork", "Beef", "Chicken"]; // Наилучший подход к случае массивов или списков let fruits: string[] = ["Mango", "Papaya", "Apple", "Banana"]; let carBrands: string[] = ["Mazda", "Toyota", "Nissan", "Ford"]; let meatsType: string[] = ["Fish", "Pork", "Beef", "Chicken"];
Функции должны быть короткими и целенаправленными
Один из основных принципов написания чистого и поддерживаемого кода на JavaScript и TypeScript заключается в том, чтобы ваши функции были лаконичными и сосредоточенными на одной задаче. Для этого разбивайте большие функции на более мелкие, модульные компоненты, каждая из которых выполняет одну чётко определённую задачу. Такой подход улучшает модульность кода, облегчая его тестирование и поддержку.
Рассмотрим пример, демонстрирующий, как преобразовать функцию JavaScript в TypeScript, следуя принципу «коротких и целенаправленных» функций.
До рефакторинга (JavaScript):
function calculateOrderTotal(order) { let total = 0; for (const item of order.items) { total += item.price * item.quantity; } if (order.promoCode) { total -= total * 0.1; } if (total > 1000) { total -= 100; } return total; }
После рефакторинга (TypeScript):
interface Order { items: Array<{ price: number; quantity: number }>; promoCode?: string; } function calculateOrderTotal(order: Order): number { const subtotal = calculateSubtotal(order.items); const discountedTotal = applyPromoCode(subtotal, order.promoCode); return applyDiscountIfApplicable(discountedTotal); } function calculateSubtotal(items: Array<{ price: number; quantity: number }>): number { return items.reduce((acc, item) => acc + item.price * item.quantity, 0); } function applyPromoCode(subtotal: number, promoCode?: string): number { if (promoCode) { return subtotal - subtotal * 0.1; } return subtotal; } function applyDiscountIfApplicable(total: number): number { if (total > 1000) { return total - 100; } return total; }
Не забывайте комментировать код
Использование комментариев для объяснения смысла кода — важная практика поддержания чистого и понятного кода. Комментарии в правильных местах могут внести ясность как для вас, так и для других разработчиков, которые будут работать с вашим кодом в будущем. Комментарии должны описывать цель кода, его ожидаемое поведение и любую значимую информацию, которая может быть не очевидна из самого кода.
Вот пример на TypeScript, иллюстрирующий использование комментариев:
// Определение пользовательского типа для структуры объектов массива type MyObject = { id: number; name: string; }; /** * Сортируеем массив MyObject по свойству 'id' в порядке возрастания. * * @param array - Массив, который необходимо отсортировать. * @returns Новый массив с объектами, отсортированными по 'id'. */ function sortObjectsById(array: MyObject[]): MyObject[] { return array.slice().sort((a, b) => a.id - b.id); } const arrDevelopers = [ { id: 3, name: "Jorgel", language: "PHP" }, { id: 0, name: "Eleazar", language: "Python" }, { id: 1, name: "Hector", language: "Java" }, { id: 2, name: "Alvison", language: "Golang" }, { id: 4, name: "Bill", language: "JavaScript" }, ]; sortObjectsById(arrDevelopers)
Используйте пробелы
Правильное использование разрывов строк, отступов и пустых строк улучшает читаемость и делает его более визуально приятным. Сгруппируйте связанные строки кода вместе и отделите их от других блоков кода с помощью пустых строк. Давайте рассмотрим пример на языке TypeScript:
function calculateTotalPrice(items: Item[]): number { let totalPrice = 0; for (const item of items) { totalPrice += item.price * item.quantity; } return totalPrice; } class Item { constructor(public name: string, public price: number, public quantity: number) {} } const shoppingCart: Item[] = [ new Item("Laptop", 1000, 2), new Item("Mouse", 30, 3), new Item("Keyboard", 50, 1), ]; const total = calculateTotalPrice(shoppingCart); console.log(`Total price: $${total}`);
Избегайте использования вложенных условных операторов
Используйте шаблоны раннего возврата или защитные условия (guard clauses), для улучшения читаемости кода и снижения его сложности. Вместо множества вложенных операторов if-else создавайте функции или методы, которые возвращают результат, как только выполняется условие. Такой подход улучшает организацию кода и упрощает его понимание для разработчиков.
Вот пример на TypeScript, демонстрирующий использование ранних возвратов:
function calculatePrice(quantity: number, price: number, discountApplied: boolean): number { if (quantity <= 0) { return 0; // Защитное условие для обработки невалидного ввода } let total = quantity * price; if (discountApplied) { total *= 0.9; // Применение скидки 10% } return total; }
Избегайте глобальных переменных
Один из ключевых принципов написания чистого и поддерживаемого кода на JavaScript и TypeScript — это уменьшение использования глобальных переменных. Злоупотребление глобальными переменными может привести к таким нежелательным последствиям, как конфликты имён, непредвиденные побочные эффекты и усложнение кода. Чтобы избежать этих проблем, используйте замыкания или модульные паттерны для инкапсуляции кода и предотвращения загрязнения глобального пространства имён.
Вот пример, демонстрирующий, как избежать глобальных переменных, инкапсулируя функциональность в модуле TypeScript:
// Вместо глобальных переменных инкапсулируйте свой код в модуль namespace MyModule { // Приватная переменная, доступная только в пределах модуля let counter = 0; // Публичная функция для взаимодействия с модулем export function incrementCounter(): void { counter++; } // Публичная функция для получения значения счетчика export function getCounterValue(): number { return counter; } } // Использование функций модуля MyModule.incrementCounter(); console.log(MyModule.getCounterValue()); // Вывод: 1
Используйте const и let вместо var
При объявлении переменных в JavaScript или TypeScript лучше всего использовать const и let, а не var. Этот выбор улучшает читаемость кода, обеспечивает блочную структуру и снижает риск случайного переназначения переменных. Использование const для значений, которые не будут меняться, и let для переменных, которые нужно переназначить, поможет создавать более чистый и предсказуемый код. Вот пример на языке TypeScript:
// Использование const для констант const pi = 3.14; const appName = "MyApp"; // Использование let для переменных let counter = 0; let username = "JohnDoe"; // Попытка переназначить константу приведет к ошибке компиляции // pi = 3.14159; // Error: Cannot assign to 'pi' because it is a constant. // Переназначение переменной вполне допустимо counter = 1; username = "JaneDoe";
Используйте шаблонные строки
Одной из важных практик написания чистого и поддерживаемого кода в JavaScript и TypeScript является использование шаблонных строк для интерполяции строк. Шаблонные строки обеспечивают краткий и удобный способ встраивания переменных и выражений в строки, избавляя от необходимости конкатенации или сложных манипуляций со строками. Шаблонные строки заключаются в обратные кавычки и могут содержать заполнители для переменных или выражений, заключенных в «${}»
Вот пример на EcmaScript:
// Определение имени и фамилии const firstName = "John"; const lastName = "Doe"; // Создание полного имени с использованием шаблонного литерала const fullName = `My name is ${firstName} ${lastName}.`; // Вывод полного имени в консоль console.log(fullName);
Используйте стрелочные функции
При работе с простыми функциями обратного вызова (коллбэками) в JavaScript и TypeScript рекомендуется использовать стрелочные функции. Стрелочные функции предоставляют более лаконичный и удобочитаемый синтаксис по сравнению с традиционными функциональными выражениями. Они автоматически привязываются к окружающему контексту, что помогает уменьшить многословие кода. Вот пример на TypeScript, иллюстрирующий это:
// Традиционное функциональное выражение const add = function (a: number, b: number): number { return a + b; }; // Стрелочная функция для той же задачи const add = (a: number, b: number): number => a + b;
Используйте деструктуризацию объектов
В JavaScript и TypeScript чистота и поддерживаемость кода во многом зависят от деструктуризации объектов. Этот приём упрощает доступ к свойствам, улучшает читаемость кода и снижает его избыточность, особенно при работе с вложенными объектами. Вместо индивидуального обращения к каждому свойству, деструктуризация позволяет извлекать необходимые свойства, что способствует более чистому и интуитивно понятному коду.
Пример на TypeScript, иллюстрирующий эту концепцию:
// Пример пользовательского объекта const user = { id: 1, name: 'John Doe', email: 'john@example.com', address: { street: '123 Main St', city: 'Anytown', zipCode: '12345', }, }; // Без деструктуризации const userName = user.name; const userCity = user.address.city; // С деструктуризацией const { name, address: { city } } = user; console.log(`User Name: ${name}`); console.log(`User City: ${city}`);
Имена функций
При наименовании функций в JavaScript и TypeScript используйте понятные комбинации глагол-существительное, чтобы эффективно передать их назначение, делая код более понятным для разработчиков. Например, если у вас есть функция, которая вычисляет общую стоимость товаров в корзине, хорошее название для такой функции может быть calculateTotalPrice
:
function calculateTotalPrice(items: Item[]): number { // Логика расчета общей цены }
Бонус: оптимизируйте свой код, используя режим EcmaScript и стрелочные функции. Вот несколько примеров:
const paymentUpdatedMessage = 'Payment has been updated!'; function payment(){ console.log(paymentUpdatedMessage); } // Лучший подход при использовании обычного JS и ES6 function updatePayment(){ console.log(paymentUpdatedMessage); } // Лучший подход с использованием EcmaScript const updatePayment = () => console.log(paymentUpdatedMessage); }
Заключение
В этом руководстве по JavaScript и TypeScript мы рассмотрели лучшие практики для того, чтобы ваш код оставался эффективным, масштабируемым и подходящим для командной работы. Постоянное применение таких принципов, как DRY, KISS, SOLID, а также фокус на осмысленных названиях и документации повысят качество вашего кода и сэкономит время, делая вас ценным членом команды.
Всех тех, кто использует или планирует использовать JavaScript для написания автотестов, приглашаем на открытый урок, посвященный оптимизации автоматизации тестирования с применением Page Object в JavaScript.
На этом занятии мы погрузимся в мир Page Object и рассмотрим, как эта популярная практика может значительно улучшить процесс автоматизации тестирования в JavaScript. Мы изучим основные концепции Page Object, принципы его использования, а также рассмотрим методы оптимизации автоматизированных тестов с помощью Page Object.
Записаться на урок можно по ссылке.
ссылка на оригинал статьи https://habr.com/ru/articles/841866/
Добавить комментарий