Академический минимум js-разработчика: базовые концепции

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Приветствую всех! Меня зовут Рома, я разработчик в компании АйТи-Баланс. Хочу поделиться с вами своими знаниями и помочь разобраться в базовых концепциях, которые необходимы каждому новичку в мире JavaScript.

Идея этой статьи возникла из популярного репозитория на GitHub. Я немного адаптировал материал, дополнил его и выделил ключевые аспекты, чтобы сделать информацию максимально доступной и полезной.

Эти базовые концепции особенно важны для тех, кто только начинает свой путь в программировании и хочет стать настоящим разработчиком, а не просто освоить фреймворк по видео и начать фрилансить. Понимание принципов ООП и глубокое знание языка программирования — это то, что необходимо каждому современному разработчику.

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

js-разработчик
js-разработчик

Основы ООП (Объектно-Ориентированного Программирования)

ООП — это фундаментальная концепция, которая лежит в основе многих современных языков программирования, включая JavaScript. Вот несколько ключевых аспектов, которые необходимо знать:

  1. Классы и объекты:

  • Класс — это шаблон или blueprint, который описывает структуру и поведение объектов.

  • Объект — это экземпляр класса, который наследует свойства и методы этого класса.

  1. Наследование:

  • Это процесс, при котором один класс наследует свойства и методы другого класса. Это позволяет создавать иерархии классов и повторно использовать код.

  • Пример:

class Vehicle {
  constructor(name) {
    this.name = name;
  }
  displayName() {
    return this.name;
  }
}

class Car extends Vehicle {
  constructor(name, model) {
    super(name);
    this.model = model;
  }
  displayModel() {
    return `Model: ${this.model}`;
  }
}

let car = new Car('Toyota', 'Camry');
console.log(car.displayName() + ' ' + car.displayModel()); // Output: Toyota Model: Camry
  1. Инкапсуляция:

  • Это механизм, который скрывает внутренние детали объекта и предоставляет контролируемый доступ к ним через методы.

  • Пример использования геттеров и сеттеров:

class Person {
  constructor(name, age) {
    this._name = name;
    this._age = age;
  }
  
  getName() {
    return this._name;
  }
  
  setName(newName) {
    this._name = newName;
  }
  
  getAge() {
    return this._age;
  }
}

let person = new Person('Alice', 30);
console.log(person.getName()); // Output: Alice
person.setName('Bob');
console.log(person.getName()); // Output: Bob
console.log(person.getAge()); // Output: 30
  1. Полиморфизм:

  • Это способность объекта принимать различные формы. В программировании это означает, что объект подкласса может быть использован вместо объекта суперкласса.

  • Пример:

class Animal {
  makeSound() {
    return `The animal makes a generic sound.`;
  }
}

class Dog extends Animal {
  makeSound() {
    return 'The dog barks.';
  }
}

let dog = new Dog();
console.log(dog.makeSound()); // Output: The dog barks.

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

Что почитать:

Мэтт Вайсфельд "Объектно-ориентированное мышление".

Марейна Хавербеке "Выразительный JavaScript. Современное веб-программирование".

Гради Буч “Объектно-ориентированный анализ и проектирование с примерами приложений”.

Чистый код

Начну с чистого кода, потому что на практике читать код разработчику приходится чаще, чем писать. Чтобы всем было хорошо и удобно, нужно с первой строчки на JS формировать привычку выбирать понятные имена для сущностей, сокращать функции до единственной операции и делать всё прочее, что делает код понятным и простым для восприятия.

Кроме того, не стоит забывать про написание документации. Она играет ключевую роль в поддержке и развитии проекта, особенно в командах с несколькими разработчиками. Хорошо написанная документация помогает новым членам команды быстрее освоиться, а также облегчает поддержку и обновление кода в будущем.

Существует несколько международных стандартов и лучших практик по написанию кода на JavaScript, которые могут служить ориентиром:

  1. Airbnb JavaScript Style Guide: Этот гайд предлагает рекомендации по стилю написания кода, включая соглашения по именованию переменных, форматированию и другим аспектам, которые способствуют созданию чистого и понятного кода.

  2. Google JavaScript Style Guide: Гайд от Google, который также охватывает различные аспекты написания чистого и эффективного кода.

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

  4. ESLint: Инструмент для линтинга JavaScript кода, который позволяет проверять код на соответствие заданным правилам и стандартам.

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

Что почитать:

  • Макконнелл Стив «Совершенный код»

  • Роберт Дж. Мартин «Чистый код».

  • Учебник по JavaScript.

  • Рекомендации по написанию чистого кода на JavaScript.

Алгоритмы и их сложность

Алгоритмы нужно знать. Понятно, что можно собрать на фреймворке простой сайт без понимания графов и хэшей, только сейчас такие примитивные задачи решают нейросети, а разрабов нанимают для другого. Так что академический минимум: in-place и out-of-place, Big O notation с формированием навыка оценки «на глаз» с учетом неявных данных.

Что почитать:

  • Алгоритмика

  • «Грокаем алгоритмы. Иллюстрированное пособие для программистов и любопытствующих», Бхаргава А.

  • JavaScript: структуры данных и алгоритмы. Часть 1

  • Алгоритмы и структуры данных на JavaScript

как chatgpt видит сложность алгоритмов
как chatgpt видит сложность алгоритмов

Типы и структуры данных

Прежде чем писать свои типы данных, нужно разобраться с возможностями, ограничениями, хранением и представлением встроенных. В JS семь примитивов: string, integer, boolean, undefined, symbol, bigint, Null, object и function. Их надо исследовать от и до, к ним же коллекции и глубокое осознание разницы передачи аргументов в функцию по значению и по ссылке, преобразование типов.

Что почитать:

  • MDN

  • Статья про преобразование типов в JS.

  • Типы данных

  • Глубокий JS. В память о типах и данных

  • Типы данных в JavaScript. Инструкция для начинающих

Стек вызовов, callback-функции и асинхронность

В JS функция — это объект. Любую функцию можно пробросить в другую в качестве аргумента, что часто и густо используют для асинхронного выполнения операций. Век сегодня без асинхронности не существует, так что тему колбеков пропускать ни в коем случае нельзя. Хотя бы то, что громадный кусок асинхронного API Node.js работает на коллбэках, уже должно стать аргументом в пользу глубокого погружения в тему.

Что почитать: 

  • Колбэк-функция — MDN

  • Коллбэк в JavaScript… Что за зверь?

  • Ты наконец-то поймешь асинхронность в JS

  • Асинхронность в JavaScript

Области видимости, IIFE, модули и пространства имен

Области видимости (скоупы) лучше разбирать на куче маленьких практических задач, а потом на кучке поменьше, но уже более сложных. На аналогиях видимость переменных объясняют как физическую возможность увидеть нечто из некоторой точки. Концепция вроде бы простая — находящееся в здании не видно из-за стены, но на практике попытки обращения к переменным вне области видимости и неудачные разграничения скоупов случаются и в практике опытных разрабов.

Области видимости (Scope)

Области видимости в JavaScript играют ключевую роль в управлении доступом к переменным и функциям. Существует два типа областей видимости: глобальная и функциональная.

  1. Глобальная область видимости:

  • Переменные, объявленные вне какой-либо функции, находятся в глобальной области видимости и доступны из любой части кода в том же файле или даже в других файлах, если они подключены.

  • Пример:

var globalVariable = 'I am global';
function printGlobal() {
  console.log(globalVariable);
}
printGlobal(); // Output: I am global
  1. Функциональная область видимости:

  • Переменные и функции, объявленные внутри функции, доступны только внутри этой функции. Это предотвращает конфликты имен и помогает изолировать код.

  • Пример:

function outerFunction() {
  var localVariable = 'I am local';
  function innerFunction() {
    console.log(localVariable);
  }
  innerFunction(); // Output: I am local
}
var localVariable = 'I am out of function';
outerFunction(); // Output: I am local

Области видимости и замыкания (Closures)

  • Замыкания — это функции, которые имеют доступ к переменным своей родительской функции, даже после возврата родительской функции. Это мощный инструмент для работы с данными в JavaScript.

  • Пример замыкания:

function createCounter() {
  var count = 0;
  return function() {
    return count++;
  };
}
var counter1 = createCounter();
var counter2 = createCounter();
console.log(counter1()); // Output: 0
console.log(counter2()); // Output: 0
console.log(counter1()); // Output: 1
console.log(counter2()); // Output: 1

IIFE (Immediately Invoked Function Expression)

IIFE — это функция, которая вызывается сразу после ее создания. Это полезно для инкапсуляции кода и создания приватных переменных. Пример IIFE:

(function() {
  var privateVariable = 10;

  function privateFunction() {
    console.log(privateVariable);
  }
  window.publicFunction = function() {
    console.log(privateVariable);
    privateFunction();
  };
  privateFunction();
})();
// publicFunction доступна для использования
publicFunction();

Модули

Модули позволяют разделять код на независимые блоки, которые могут быть импортированы и экспортированы. В JavaScript для этого используются различные подходы:

  1. CommonJS (Node.js):

var module = require('module');
console.log(module);

2. ES6 модули:

import { example } from './example.js';
console.log(example);

Пространства имен (Namespaces)

Пространства имен помогают организовать код и предотвращать конфликты имен. Они могут быть реализованы с использованием объектов:

var myNamespace = {
  variable: 'Hello from namespace',
  function: function() {
    console.log(this.variable);
  }
};
myNamespace.function(); // Output: Hello from namespace

Что почитать: 

Компактная статья про области видимости на Доке.

You Don't Know JS. Scope & Closures

По-пикабушному простое появление темы замыканий с примерами.

Разница между оператором и выражением

Выражение — возвращает значение, оператор — производит действие. Операторы могут быть частью выражения, но не наоборот. В JS классический набор операторов: присваивания, сравнения, логические, арифметические, строковые и пр.

Пример:

Выражение: x = y + z

В этом выражении 2 оператора: Оператор сложения (+) и оператор присваивания (=).

Что почитать: Краткий справочник по операторам и выражениям на MDN.

Очередь сообщений и цикл событий

В контексте цикла событий (Event Loop) очередь сообщений (The Message Queue) в JavaScript является областью ожидания для функций. Получается, что каждое инициируемое в DOM или пользователем событие и колбеки попадают в общую очередь. Оттуда Event Loop их вытаскивает по мере опустошения стека вызовов, о котором на момент разбора этой темы хорошо бы знать всё и даже больше.

Что почитать: Конспект по микро- и макрозадачам в ДОКЕ.

Рендеринг во всех ипостасях: DOM-дерево и дерево макетов в памяти, перекомпоновка/макеты, композиты и перерисовка

В очень упрощенном виде процесс рендеринга происходит так:

  • Строится DOM (Document Object Model) — объектное представление.

  • Происходит анализ таблицы стилей для расчета визуального представления элементов.

  • Браузер просчитывает лэйауты с учетом стилей и отношений.

  • Страница отрисовывается на экране.

Формально так всё и происходит, но отвечать на собесе на должность выше стажерской лучше детальнее и точнее с технической точки зрения. К тому же без понимания процесса рендеринга тяжело будет запланировать порядок загрузки и вообще любые асинхронные операции.

Не стоит забывать и о фреймворке — jQuery. А точнее без знаний и понимания работы в нем сейчас не обойтись.

Что почитать:

Статья про работу с DOM (англ.).

jQuery – Введение для начинающих

jQuery для начинающих

Прототипное наследование

Наследование в JS работает не совсем так, как в Python или в C++. В отличие от канонического inherit классы в JS не наследуют от других классов, но объекты могут наследовать напрямую друг от друга через прототипы. В двух словах эту концепцию точно описать не получится, да и без практики понять принцип и удобство этой фишки крайне тяжело. Я советую немного почитать и много попробовать строить цепочки прототипов на учебных задачах.

Что почитать: Наследование и цепочки прототипов в формате краткого справочника на MDN.

Фабрики и классы

Класс — это структурированный шаблон, по которому создаются объекты с общими свойствами и набором методов. Фабрика — это сущность, которая возвращает объекты, при этом не являясь шаблоном в его базовом понимании. Сложно? Вот потому этому редко учат на курсах — долго объяснять. На практике применимы оба варианта, но традиционно из-за реализации this и потери контекста фабричные функции выбирают чаще.

Дуглас Крокфорд как-то назвал ООП без классов подарком человечеству от JavaScript. Так или нет — вопрос правильного использования и уместности. В том же React, например, всё строго на классах, но это скорее исключение.

Что почитать: Статья про шаблоны проектирования в «Библиотеке программиста».

Map, reduce, filter и стрелочные функции

В языке JS круто реализована работа с массивами, но популярная ошибка новичка — пользоваться forEach, где надо и не надо. Читать вездесущие переборы — пытка, не надо так делать. Тем более что методы map(), reduce() и filter() в JavaScript не так уж сложны для понимания и даже интуитивны:

  • map() создает массив с пропущенными через колбэк данными исходного;

  • reduce() сворачивает структуру, например, через объединение строк, сумму числовых значений и т. п.;

  • filter() возвращает массив, отфильтрованный через переданный коллбэк, если ни один элемент не пройдет «фейс-контроль», то метод создает пустой массив.

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

Массивы в JS имеют очень много всяких различных полезных методов, таких как join, find, shift и unshift, push и pop, и т.д. Поэтому важно иметь под рукой перечни доступных методов (обычно это большие справочники, которые просто полезны для разработчика любого уровня и в которые даже опытным разрабам имеет смысл иногда заглядывать, например).

Что почитать: Статья из библиотеки программиста с примерами по мапам, редьюсам и фильтрам в контексте упрощения кода.

Рекурсия

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

Циклы и условия, напротив, являются императивными конструкциями, которые позволяют выполнять повторяющиеся действия или ветвления в зависимости от заданных условий. Циклы, такие как for, while и do-while, позволяют выполнять блок кода до тех пор, пока не будет выполнено определённое условие. Например, цикл for часто используется для итерации по массивам или счётчикам. Условия, представленные операторами if, else и switch, позволяют выполнять различные блоки кода в зависимости от выполнения или невыполнения заданных условий. Эти конструкции являются основой для управления потоком выполнения программы и обеспечивают гибкость в написании кода.

Таким образом, рекурсия, циклы и условия дополняют друг друга, предоставляя мощные инструменты для разработки программного обеспечения.

Что почитать:

Справочная статья по рекурсии на ДОКЕ.

Перевод книги «Выразительный Javascript» в pdf

Онлайн-курс CS50: Introduction to Computer Science

JavaScript: The Good Parts” by Douglas Crockford

Паттерны проектирования и чистая архитектура

Паттерны проектирования лучше знать, чем не знать. Скорее всего, эти знания на старте не пригодятся, зато само их наличие в паре с уместным применением повлияет на скорость роста грейда в положительную сторону. Это как с SOLID и прочими премудростями, которые нерадивые гуру быстрых курсов по войти-в-айти рекомендуют игнорировать. Зря.

Что почитать: справочник по паттернам с примерами в ДОКЕ,

«Чистая архитектура. Искусство разработки программного обеспечения» Мартин Роберт.

Основные принципы программирования: интроспекция и рефлексия. Особенности рефлексии в JavaScript

Интроспекция позволяет изучать атрибуты объекта во время выполнения программы, а рефлексия — манипулировать ими. В статически типизированных языках управлять объектами во время компиляции нельзя, а в JS — можно. Код с рефлексией хуже читается, зато дает гибкость и возможности для метапрограммирования, которых у того же C или Java «из коробки» нет.

Что почитать: Развернутую статью в «Библиотеке программиста» про принципы программирования.

Вывод: перечисленного хватит, чтобы стать настоящим разработчиком?

Фактически каждый, кто пишет код, уже разработчик. Перечисленное — это каркас, на котором проще строить общее понимание сути программирования, учиться, создавать что-то новое. Сейчас на фоне спроса на импортозамещение нужны как раз те, кто может создавать, кто понимает в алгоритмы и эффективное решение задач бизнеса через код.

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

В заключение хочу добавить несколько полезных ссылок, которые всегда могут пригодиться:

  1. Онлайн-компиляторы (например, https://www.programiz.com/javascript/online-compiler/) - всегда помогут проверить работоспособность малых участков кода. Позволяют быстро проверить участок кода, без перезагрузки страницы/пересборки всего кода (иногда эти процессы занимают очень длительное время).

  2. Тестеры регулярных выражений (например, https://regex101.com/). Регулярные выражения очень сильно помогают, когда необходимо проверить текст на соответствие паттерну. Тестеры сразу позволяют увидеть корректен ли построенный шаблон, а также зачастую содержат описание возможных операторов шаблона и примеры построения, что позволяет легко и быстро построить нужный паттерн (например, для валидации корректного ввода email).

Источник: https://habr.com/ru/companies/intec_balance/articles/876088/


Интересные статьи

Интересные статьи

Рынок российских CRM-систем активно развивается и насчитывает около 50 программных продуктов. Для отраслевых ниш и сегментов среднего и малого бизнеса существуют коробочные решения, для крупных корпор...
Представьте: горячий металл, мощные машины, сотни работников — наше производство постоянно подвержено различным рискам. И как мы превратили эти вызовы в возможности? Этот рассказ будет о том, как мы в...
Добавляем функционал быстрых ответов на любом тарифе Битрикс24Как добавить одну из самых полезных функций для чатов открытых линий для любого коммерческого тарифа? Все очень просто, нужно лишь..... ...
Цикл событий (event loop) — ключ к асинхронному программированию на JavaScript. Сам по себе язык однопоточный, но использование этого механизма позволяет создать дополнительные потоки, чтобы код работ...
Всем привет. Текст состоит из двух частей:1. Небольшая шпаргалка по параметрам настроек по умолчанию;2. Текст о том, почему вообще существование такой шпаргалки может кому-то понадобится.