Здравствуйте, ребята!
Я разработчик полного цикла с более чем 5-летним опытом работы с JavaScript. Теперь эта любовь сильно ударила по мне, поэтому я пишу это со страстью и бесплатно раздаю всем начинающим и продолжающим разработчикам JavaScript.

Обзор

JavaScript (JS), мощный компьютерный язык, стал чрезвычайно популярным благодаря своей способности создавать динамические и интерактивные веб-страницы. Независимо от того, являетесь ли вы новичком или опытным разработчиком, это руководство призвано дать вам полное представление о JavaScript и его основных идеях.

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

JavaScript необходим для современной веб-разработки. Это дает разработчикам возможность создавать динамический контент, управлять взаимодействием с пользователем, работать с HTML и CSS и подключаться к серверам для асинхронного извлечения и доставки данных. Вы можете создавать интерактивные онлайн-приложения, одностраничные приложения (SPA), мобильные приложения и многое другое с помощью JavaScript.

Типы данных в JavaScript

В JavaScript есть множество встроенных типов данных. Хотя объекты составляют большую часть вещей в JavaScript, есть несколько исключений, известных как примитивные типы данных.
Они состоят из:

Число. Представляет числовые значения, включая значения с плавающей запятой и целые числа.
В одинарных ('') или двойных ("") кавычках строка представляет собой текстовые данные.
Boolean: логическое значение, которое может быть либо true, либо false.
Undefined: представляет объявленная переменная, которая
Symbol: обозначает, часто используется для создания свойств объекта, которые не предназначены для просмотра широкой публикой. Он представляет собой уникальный идентификатор.

Объявления и переменные

Переменные используются для хранения значений данных в JavaScript. Используя ключевые слова var, let или const, вы можете объявлять переменные. Ключевое слово var обычно используется для объявления переменных, но функции let и const для определения области блока были включены в более поздние версии JavaScript (ES6).

Циклы управления и поток

JavaScript предоставляет ряд операторов потока управления, позволяющих принимать решения и выборочно выполнять код. Условное ветвление часто включает использование оператора if…else, оператора switch и тернарного оператора (условие? выражение1: выражение2).

Вы можете перебирать фрагмент кода с помощью циклов. В JavaScript есть множество структур циклов, в том числе for, while, do…while и each.

Цепочка прототипов

Цепочка прототипов лежит в основе объектной модели JavaScript. Каждый объект в JavaScript связан с объектом-прототипом, образуя цепочку, которая позволяет объектам наследовать свойства и методы от своих прототипов. Мы изучим механику цепочки прототипов и то, как она обеспечивает наследование в JavaScript.

Создание прототипов: прототипы JavaScript можно создавать несколькими способами. Мы рассмотрим различные методы, включая функции-конструкторы, литералы объектов и метод Object.create(). Понимание этих методов даст вам гибкость в выборе наиболее подходящего подхода для ваших конкретных требований.

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

Динамическое изменение прототипов. Прототипная природа JavaScript позволяет динамически изменять прототипы во время выполнения. Мы рассмотрим, как добавлять, изменять или удалять свойства и методы из существующих прототипов. Этот динамический характер обеспечивает потрясающую гибкость и позволяет выполнять мощную настройку кода.

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

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

Прототипное наследование против классического наследования. Прототипное наследование в JavaScript отличается от классического наследования, встречающегося в таких языках, как Java или C++. Мы сравним и противопоставим два подхода, выделив преимущества и уникальные аспекты прототипного наследования. Понимание этих различий поможет вам полностью принять прототипную парадигму.

Прототипы в современном JavaScript. С появлением современных стандартов JavaScript и ECMAScript было введено несколько функций, упрощающих работу с прототипами. Мы коснемся новых концепций, таких как классы, ключевые слова extends и ключевые слова super, и обсудим, как они соотносятся с прототипами.

Функции JavaScript: строительные блоки динамической веб-разработки

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

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

Вызов функции: вызов или вызов функции запускает выполнение ее блока кода. JavaScript предоставляет несколько способов вызова функций. Наиболее распространенным подходом является традиционный вызов функции, когда вы используете имя функции, за которым следуют круглые скобки. Функции также можно вызывать как методы, используя парадигму объектно-ориентированного программирования. Кроме того, методы call() и apply() позволяют управлять контекстом выполнения функции.

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

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

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

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

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

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

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

Практический JavaScript

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

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

const findMode = function () { /**/ }
function findMode() { /**/ }
const findMode = () => { /**/ } //Arrow functions introduced in ES6

Давайте напишем функцию традиционным способом и реализуем логику:

function findMode(arr) {
  const mappings = {};
  // Here we are going to use forEach loop
  arr.forEach((item)=> {
      if(!mappings[item]) mappings[item] = 0;
      mappings[item] += 1;
  });
}

Давайте внимательно посмотрим на предоставленный фрагмент кода. У нас есть постоянная переменная, называемая «отображения», которая инициализируется как пустой объект. Важно отметить, что хотя «отображения» объявляются с помощью ключевого слова const, мы все равно можем изменять и добавлять к ним свойства и методы. Однако мы не можем изменить его тип или присвоить ему совершенно новое значение.

В следующей части кода мы перебираем массив чисел. Для каждого повторения числа в массиве мы увеличиваем значение, связанное с этим числом в объекте «отображения». Объект «сопоставления» служит таблицей поиска, где каждое число в массиве соответствует свойству в объекте.

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

Теперь мы добавим к этому коду однострочник, который решит нашу проблему.

function findMode(arr) {
  const mappings = {};
  // Here we are going to use forEach loop
  arr.forEach((item)=> {
      if(!mappings[item]) mappings[item] = 0;
      mappings[item] += 1;
  });
  return Object.keys(mappings).reduce((a, b) => mappings[a] > mappings[b] ? a : b);
}

Цель состоит в том, чтобы найти ключ (свойство) в объекте, который имеет наибольшее значение. Разберем пошагово:

  1. Object.keys(mappings): Эта часть извлекает массив ключей (свойств) из объекта mappings. Это дает нам массив всех ключей, присутствующих в объекте.
  2. reduce((a, b) => obj[a] > obj[b] ? a : b): Метод reduce вызывается для массива ключей. Целью reduce является сокращение массива до одного значения. В данном случае это помогает нам найти ключ с наибольшим значением в объекте mappings.
  3. (a, b) => obj[a] > obj[b] ? a : b: это функция обратного вызова, предоставляемая методу reduce. Он принимает два параметра, a и b, которые представляют два ключа, сравниваемых на каждой итерации. Он сравнивает значения, связанные с этими ключами (obj[a] и obj[b]) в объекте mappings. Если значение, связанное с a, больше, чем значение, связанное с b, возвращается a. В противном случае возвращается b.

Проще говоря, код перебирает все ключи в объекте mappings, сравнивает их значения и отслеживает ключ с наибольшим значением. После завершения цикла он возвращает ключ с наибольшим значением.

Как вы можете видеть, когда вы практически начинаете использовать язык программирования, может быть много вещей, таких как методы массива, концепции, такие как замыкания и т. д., которые вы можете изучить, только попытавшись создать программное обеспечение, небольшое приложение, такое как список задач или простой базовый калькулятор. Итак, попробуйте сделать простой калькулятор сложения, вычитания, умножения и деления на веб-странице HTML с некоторым базовым пользовательским интерфейсом, используя JavaScript и его мощные функции манипулирования DOM.

Следите за новостями, скоро мы много чего реализуем на JavaScript.

Счастливого программирования в 2023 году!