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. Чистый код
Написание чистого, понятного и поддерживаемого кода — навык, которым должен овладеть каждый разработчик.
Читайте также:
- Технологический стек для создания веб-приложений
- Продвинутая версия Hello World для A-Frame
- Web Speech API в JavaScript: от текста к речи
Читайте нас в Telegram, VK и Дзен
Перевод статьи Codingwinner: 33 Concepts Every JavaScript Developer Should Know