Первая и вторая части статьи.

23. Коллекции и генераторы

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

// Массив
const colors = ["red", "green", "blue"];
// Множество
const uniqueColors = new Set(colors);
// Генератор
function* generateNumbers() {
yield 1;
yield 2;
yield 3;
}
const numbersGenerator = generateNumbers();
console.log([…uniqueColors]); // ["red", "green", "blue"]
console.log([…numbersGenerator]); // [1, 2, 3]

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

24. Промисы

Допустим, вы усвоили понятие обратного вызова, но что произойдет, если в коде будут обратные вызовы внутри обратных вызовов внутри обратных вызовов и так далее? Такая рекурсивная структура обратных вызовов называется «адом обратных вызовов», и промисы помогут решить эту проблему. 

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

Согласно developer.Mozilla, «промис — это объект, представляющий возможное завершение или неудачу асинхронной операции. Это возвращаемый объект, к которому вы прикрепляете обратные вызовы вместо того, чтобы передавать их в функцию». 

Промисы решают проблему «ада обратных вызовов», который представляет собой не что иное, как рекурсивную структуру обратных вызовов (обратные вызовы внутри обратных вызовов внутри обратных вызовов и так далее).

Промис может находиться в одном из трех состояний:

  • выполненном (fulfilled): когда операция успешно завершена;
  • отклоненном (rejected): когда операция оказалась неудачной;
  • в состоянии ожидания (pending): начальное состояние, не выполненное и не отклоненное.

Пример: посмотрим, как создать промис в JavaScript.

const promise = new Promise((resolve, reject) => {
isNameExist = true;
if (isNameExist) {
resolve("User name exist")
} else {
reject("error")
}
})
promise.then(result => console.log(result)).catch(() => {
console.log(‘error!')
})

Вывод:

User name exist
Promise {<resolved>: undefined}

Обсудим приведенный выше код с примером промиса, предполагающего асинхронное выполнение операции ‘isNameExist’. В этом промисе есть объектные аргументы в виде двух функций resolve и reject. Если операция успешна (что означает: ‘isNameExist’ равно ‘true’), то она будет разрешена, и выводится сообщение «User name exist» («Имя пользователя существует»). В противном случае операция окажется неудачной и отклоненной, и будет выведен результат «error!» («ошибка!»). Можно легко выполнить цепочку операций с промисами, где первая операция будет выполнена, а ее результат передан второй операции, и так будет продолжаться далее по цепочке.

25. Синтаксис async/await

Остановитесь и подождите, пока что-то не будет решено. Async/await — просто синтаксический сахар на основе промисов, и, как и промисы, он также обеспечивает способ более синхронного выполнения асинхронных операций. Таким образом, в JavaScript асинхронные операции могут обрабатываться в различных вариантах:

  • ES5 -> обратный вызов;
  • ES6 -> промис;
  • ES7 -> async & await.

Можете использовать async/await для выполнения запроса Rest API, когда нужно, чтобы данные полностью загрузились, прежде чем вывести их в представление. Для специалистов по Nodejs и программистов, работающих в браузерах, async/await — значительное синтаксическое улучшение. Оно помогает разработчику реализовать функциональное программирование на JavaScript, а также повышает читаемость кода.

Пример:

const showPosts = async () => {
const response = await fetch(*https://jsonplacenolder.typicode.com/posts');
const posts = await response.json();
console.1og(posts) ;
}
showPosts();

Вывод:

Чтобы уведомить JS об использовании промисов, нужно обернуть «await» внутри функции «async». В приведенном выше примере необходимо было дождаться двух вещей: ответа и сообщения. Прежде чем преобразовывать ответ в формат JSON, следует убедиться, что ответ уже получен. Иначе можно преобразовать ответ, которого еще нет, что, скорее всего, приведет к ошибке.

26. Структуры данных

JavaScript прогрессирует с каждым днем. С быстрым развитием таких фреймворков и платформ, как React, Angular, Vue, NodeJS, Electron, React Native, использование JavaScript в крупномасштабных приложениях стало вполне обычным делом.

27. Затратная операция и нотация Big O

«Что такое нотация Big O?» — довольно распространенный вопрос на собеседовании для разработчиков. Если коротко, то нотация Big O — математическое выражение временных затрат на выполнение алгоритма, зависящее от длины входных данных (обычно речь идет о наихудшем сценарии).

28. Алгоритмы

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

29. Наследование, полиморфизм и повторное использование кода

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

В JavaScript используется наследование на основе прототипов, когда объекты могут наследовать свойства и методы от других объектов через цепочку прототипов Prototype Chain.

// Прототип
function Animal(name) {
this.name = name;
}
Animal.prototype.sound = function () {
console.log("Some generic sound");
};
// Наследование
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.sound = function () {
console.log("Bark!");
};
const myDog = new Dog("Buddy", "Labrador");
myDog.sound(); // Bark!

Понимание наследования на основе прототипов имеет решающее значение для создания эффективных и многократно используемых структур кода в JavaScript.

30. Шаблоны проектирования

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

31. Частичное применение, каррирование, композиция и конвейеризация функций

Композиция функций — это механизм объединения нескольких простых функций для создания более сложной.

32. Чистый код

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

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

Читайте нас в Telegram, VK и Дзен


Перевод статьи Codingwinner: 33 Concepts Every JavaScript Developer Should Know

Предыдущая статьяВопросы на собеседованиях для опытных профессионалов Java в 2024 году