Тренажёр по JavaScript

Источник: giphy.com
В этом тренажере вы найдете дополнительные задания для закрепления основных навыков написания кода на JavaScript, необходимых для придания интерактивности веб-страницам.
В случае возникновения затруднений, вы можете заглянуть в конец этого модуля, где расположены ответы к заданиям.
Обратите внимание! Задания в этом тренажере не оцениваются. Учебный тренажер в первую очередь даёт вам возможность попрактиковаться, а не тестирует вас.
Задание 1
Напишите программу, которая спрашивает у пользователя его имя и фамилию с помощью prompt и отвечает: Привет, {имя} {фамилия}! с помощью alert.
Задание 2
Напишите программу, которая переводит температуру по Цельсию в температуру по Фаренгейту. Она должна спросить у пользователя количество градусов по Цельсию с помощью prompt и ответить: {X} градусов по Цельсию равны {Y} градусам по Фаренгейту.

Формулы перевода шкал температур
Задание 3
Перепишите данную математическую формулу, используя JavaScript. Программа должна запрашивать с помощью prompt значение X и выдавать соответсвующее значение Y в качестве ответа. Обратите внимание на приоритет операций (важно правильно расставить скобки).

В качестве проверки: при X = 10 программа должна вывести Y = 12.5344.
Задание 4
Оператор typeof в JavaScript возвращает строку с типом данных переданного в него значения. Эта строка начинается с маленькой буквы. Например: typeof 123 вернёт строку 'number', а typeof undefined вернёт строку 'undefined'.
Все возможные значения typeof: 'undefined', 'object', 'boolean', 'number', 'bigint', 'string', 'symbol', 'function'.
ВНИМАНИЕ! Из-за особенностей JavaScript typeof null вернёт 'object'. Запомните это и учтите при выполнении задания.
Найдите в коде строки 'SOME' и напишите вместо них нужное название типа — так, чтобы при запуске кода alert написал 'true'.
Исходный код:
Задание 5
Поменяйте код так, чтобы каждая переменная была объявлена до того, как ей присвоено значение. Пользуйтесь правилом: везде, где возможно, в первую очередь используйте const, если нельзя const, то let. И никогда не используйте var.
Исходный код:
Задание 1
Напишите программу, которая запрашивает у пользователя три числа: Катет A, Катет B, и Гипотенуза C. Программа проверяет по теореме Пифагора эти стороны треугольника и пишет в консоль "Это прямоугольный треугольник!" или "Это не прямоугольный треугольник!". Используйте if/else для проверки условия.
Задание 2
Напишите программу, которая запрашивает у пользователя три числа и выводит максимальное из них, используйте if/else/else if. Попытайтесь не использовать &&.
Задание 3
Напишите программу, которая запрашивает у пользователя число N и отвечает "Число {N} четное!" или "Число {N} нечетное!"
Например: 3 → Число 3 нечетное!
Задание 1
Напишите программу, которая выводит в консоль сначала нечетные числа от 0 до 5, а потом четные числа от 5 до 10.
Задание 2
Напишите программу, которая много раз запрашивает у пользователя число, пока он не введет 0 — тогда выводится сумма этих чисел.
Задание 3
Напишите программу, которая говорит пользователю "Введите 10", пока он не введёт 10. Затем говорит "Введите 20", потом 40 и т.д. Если пользователь вводит другое число, нужно спросить его ещё раз, пока он не введёт нужное. Когда пользователь введёт больше 100, напишите "Спасибо!" и остановите программу.
Задание 1
Напишите функцию countDown(n), которая получает число {n} в качестве аргумента и печатает в консоль обратный отсчет, начиная с этого числа. Например, countDown(3) напечатает: 3 2 1.
Задание 2
Напишите функцию getPercents(percent, number), которая возвращает {percent} процентов от {number}.
Пояснение: например, getPercents(30, 200) должно вернуть 60.
Задание 3
Напишите функцию repeatWord(word, count), которая принимает слово и количество раз для его повторения. Например, если вызвать repeatWord('слово', 3) функция напечатает "слово1, слово2, слово3" на одной строке.
Задание 4
Напишите функцию createAdder(a), которая возвращает функцию addA, которая принимает b и возвращает a + b.
Исходный код:
Задание 5
Напишите функцию getMonth(n), которая принимает номер месяца и возвращает его название. Например, getMonth(12) ⇒ 'декабрь'. Используйте if/else.
Задание 1
Напишите функцию sayHello(name, surname, age, greeting), которая принимает в качестве аргументов имя, фамилию, возраст и приветствие. Каждый аргумент должен иметь дефолтное значение, функция должна быть стрелочной и не иметь ключевого слова return.
Например, при вызове sayHello('Дима') функция должна вернуть строку: "Привет, Дима Иванов, тебе 10 лет", а при вызове sayHello('Евгений', 'Петров', 25, 'Здравствуйте, ') функция должна вернуть строку: "Здравствуйте, Евгений Петров, тебе 25 лет". А при вызове без аргументов она должна вернуть: "Привет, Иван Иванов, тебе 10 лет".
Исходный код:
Задание 2
Это задание повторяет предыдущее, но для его решения необходимо использовать шаблонные строки.
Исходный код:
Задание 1
Напишите функцию match, которая принимает 2 строки и возвращает true, если эти строки равны без учета регистра. Например, match('hEllO', 'HELLo') должен вернуть true.
Задание 2
На сайте Reddit ссылки на разделы (сабреддиты) формируются следующим образом: https://reddit.com/r/название_раздела/. Напишите функцию, которая принимает ссылку на раздел и возвращает название раздела.
Задание 3
Напишите функцию reverseAndNegate(arr), которая принимает массив чисел и возвращает перевернутый отрицательный массив.
Например: [1, -2, 5, 4] ⇒ [-4, -5, 2, -1].
Задание 4
Напишите функцию, которая принимает массив чисел и сначала к каждому чётному числу прибавляет 4, у каждого нечётного отнимает 2, потом убирает из массива числа, делящиеся на 13 без остатка и возвращает сумму оставшихся чисел.
В качестве проверки: calculate([15, 2, 3, 5, 6]) должна вернуть 20.
Задание 5
Напишите функцию transformUpvotes(arr), которая принимает массив сокращенных записей количества лайков ['10k', '2.3k', '5k', '32', '28.4k'] и возвращает массив чисел [10000, 2300, 5000, 32, 28400].
Задание 1
Напишите функцию getInfo(persons), которая принимает массив объектов, описывающих человека, имеющих поля {name, age}, и возвращает объект со средним возрастом и именем самого старшего человека.
Задание 2
Напишите функцию, которая принимает массив массивов вида [['ключ1', 'значение1'], ['ключ2', 'значение2']] и возвращает объект вида: {ключ1: 'значение1', ключ2: 'значение2'}.
Задание 3
Напишите функцию countChars(str), которая принимает строку и возвращает количество букв в этой строке.
Например: countChars('Арарат') должен вернуть: { а: 3, р: 2, т: 1 }.
Задание 1
Перепишите функцию так, чтобы она писала 'Hello, {name}' в консоль только при первых трёх вызовах, начиная с 4-го ничего не делала. Используйте замыкания.
Исходный код:
Задание 2
Переменная, объявленная с помощью var, всплывает и видна на уровне функции, даже если объявлена внутри цикла for. Перепишите программу так, чтобы она печатала от 1 до 10 в консоль. Используйте замыкания.
Исходный код:
Задание 1
Напишите функцию countEverySecond(n), которая каждую секунду печатает в консоль цифру, начиная с 1 и заканчивая {n}.
Задание 2
Напишите функцию countEverySecond(n), которая каждую секунду печатает в консоль цифру, начиная с 1 и заканчивая {n}.
Пояснение к заданию: Если в предыдущем задании вы использовали setInterval, перепишите эту функцию с помощью setTimeout (или наоборот).
Задание 1
Напишите функцию random(min, max), которая принимает минимальное и максимальное значение и возвращает целое случайное число n, такое, что: min ≤ n ≤ max. Эта функция понадобится нам для следующих заданий.
Используйте Math.random(), умножение и сложение.
Исходный код:
Задание 2
Сверстайте 5 параграфов с текстом. С помощью JS меняйте цвет фона каждого параграфа на случайный каждую секунду. Создайте массив с названиями цветов ['blue', 'cyan', ...] и с помощью функции из предыдущего задания выбирайте случайный цвет из массива.
Исходный код:
Задание 3
Напишите функцию, которая принимает HTML в виде строки и возвращает HTML без элементов div (и всего, что внутри), все остальные элементы сохраняются. Используйте createElement, querySelectorAll и innerHTML.
Исходный код:
Задание 1
Создайте кнопку, которая при клике создает другую кнопку, которая, в свою очередь, создаёт другую кнопку, и т.д.
Пояснение: Используйте HTML, JS и CSS.
Задание 2
Создайте раскрывающийся блок (accordion). Сверху блок с заголовком, при нажатии на который снизу показывается блок с текстом, при повторном нажатии блок с текстом скрывается.
Исходный код:

Задание 3
Напишите игру: в центре экрана появляется кнопка «Нажми меня». Когда юзер наводит на неё курсор, она сразу же перемещается на случайные координаты.
Исходный код:
Задание 4
Выведите на экран надпись «Ширина экрана {width} пикселей» и обновляйте её при изменении ширины экрана.
Исходный код:
Задание 1
Создайте иерархию классов животных, используйте ES5 (прототипы и функции-конструкторы). Создайте класс «Существо» с методом born() — родиться, от него наследуется «Животное», от которого наследуются «Человек», «Птица», «Рыба». От человека наследуется «Китаец». Придумайте для каждого класса методы и поля.
Задание 2
Перепишите иерархию из предыдущего задания, используя ES6-классы (extends, super).
Задание 1
Напишите функцию multiply(a, b), которая умножает a на b с помощью сложения и рекурсии.
Задание 2
Напишите функцию pow(a, b), которая возводит a в степень b с помощью умножения и рекурсии.
Задание 3
Числа Фибоначчи — последовательность чисел, в которой первые два числа равны 1 и 1, а каждое последующее число равно сумме двух предыдущих чисел.

Напишите функцию fib(n), которая возвращает n-ое число Фибонначи.
Задание 4
Напишите функцию len(str), которая принимает строку и рекурсивно считает её длину. Свойство str.length использовать нельзя.
Задание 5
Переверните строку с помощью рекурсии.
Задание 6
Факториал числа n (n!) — это произведение натуральных чисел от 1 до n. Напишите функцию fac(n).

Задание 1
Напишите функцию containsDigit(str), которая возвращает true, если {str} содержит хотя бы одну цифру. Используйте регулярные выражения.
Исходный код:
Задание 2
Напишите регулярное выражение, которое валидирует только четные числа. Создайте функцию isEven(n), принимающую Number {n} и возвращающую true, если n — четное.
Задание 3
Напишите функцию validatePhoneNumber(str), которая возвращает true, если str — это номер телефона в формате +7 (987) 654-32-10 или +7 (4212) 53-53-53.
Задание 4
Для подключения к базе данных используется адрес типа jdbc:mysql://sdasdasdasd:szdasdasd:dfsdfsdfsdf/sdfsdfsdf?user=root&password=12345. Напишите функцию, которая принимает этот адрес в виде строки и возвращает ту же строку, но со звёздочками вместо пароля. Пароль находится после password=.
Задание 5
Напишите функцию, принимающую строку и заменяющую все гласные на их индекс в строке.
Например: "Здравствуйте ребята" ⇒ "Здр3вств8йт11 р14б16т18!"
Задание 1
Напишите функцию serverMock(latency, cb), которая принимает необходимую задержку и callback.
Callback должен принимать массив products, содержащий объекты товаров. Каждый товар содержит поля price (случайное число от 300 до 10000) и name (случайное наименование из массива наименований).
Функция через {latency} миллисекунд вызывает cb со случайно сгенерированным массивом товаров длиной от 5 до 10.
Используйте функцию random(min, max), написанную ранее.
Задание 2
Используя функцию из предыдущего задания, создайте три «сервера».
- Первый принимает {номер продукта} и возвращает продукт, у которого есть поле {номер стеллажа на складе}.
- Второй сервер принимает {номер стеллажа на складе} и {номер продукта} и возвращает {номер коробки}.
- Третий сервер принимает {номер коробки} и возвращает вес продукта.
Напишите функцию, которая принимает номер продукта, последовательно обращается к этим «серверам» и возвращает вес коробки, в которой этот продукт находится. Каждый сервер должен иметь 400мс {latency}.
Задание 1
Напишите функцию checkLuck(chance), которая принимает chance в процентах и возвращает true с вероятностью {chance}%, а false — с вероятностью {100 - chance}%. То есть, если вызвать checkLuck(30) миллион раз, то примерно 300 тысяч раз она должна вернуть true. Функция понадобится для следующих задач. Вызовите функцию миллион раз, чтобы проверить её работоспособность.
Задание 2
Перепишите serverMock, используя Promise. С вероятностью 30% Promise должен упасть с ошибкой.
Напишите функцию serverMock(latency), которая принимает необходимую задержку и возвращает Promise с массивом products, содержащим объекты товаров. Каждый товар содержит поля price (случайное число от 300 до 10000) и name (случайное наименование из массива наименований). Через {latency} миллисекунд функция вызывает resolve() со случайно сгенерированным массивом товаров длиной от 5 до 10. Выведите в консоль массив товаров и ошибку, если она произошла.
Исходный код:
Задание 3
Напишите функцию promiseTimeout(ms, promise), которая принимает время таймаута в миллисекундах и промис и возвращает новый промис с ограничением времени на его resolve/reject.
То есть, если у нас есть некая функция fetchData(), получающая данные с сервера и возвращающая промис, а мы вызовем promiseTimeout(1000, fetchData()), но сервер будет отвечать дольше одной секунды, то мы должны получить reject('Timeout').
Используйте Promise.race().
Задание 4
Напишите функцию flipCoin() — подбросить монетку. Монетка летит от 50 до 200 миллисекунд. И с шансом 50% выпадает орёл (heads) или решка (tails). То есть функция возвращает promise со строкой 'heads' или 'tails'.
Используйте функции random(min, max) и checkLuck(chance) из предыдущих заданий.
Подбросьте 100000 монет одновременно и посчитайте, сколько раз выпала решка, а сколько — орёл. Используйте Promise.all().
Задание 5
Перепишите задачу с тремя «серверами», используя промисы. Каждый сервер должен с вероятностью 10% выдавать ошибку со своим названием, то есть делать reject(). Выведите эту ошибку в консоль, если она случится.
Переделав функцию из предыдущего задания, создайте три «сервера»:
- Первый принимает {номер продукта} и коллбек, возвращает в коллбек продукт, у которого есть поля: {номер стеллажа на складе} и {имя продукта}.
- Второй сервер принимает {номер стеллажа на складе} и {номер продукта} и возвращает {номер коробки}.
- Третий сервер принимает {номер стеллажа на складе} и {номер коробки}, возвращает {вес коробки}.
Напишите функцию, которая принимает номер продукта, обращается к этим «серверам» и пишет в консоль:
Коробка №{номер коробки} c {имя продукта} находится на стеллаже №{номер стеллажа на складе} и весит {вес коробки} кг.
Задание 1
Перепешите последнюю функцию задачи с тремя «серверами» с помощью async/await.
Исходный код:
Задание 2
Напишите функцию delay(ms), которую можно использовать в виде await delay(100) в асинхронных функциях, чтобы остановить выполнение на 100 мс. Посчитайте от 1 до 10 секунд в консоль, используя эту функцию и обычный цикл for.
Задание 1
Создайте функцию range(min, max), возвращающую Iterable объект от {min} до {max}.
Пояснение к заданию:
Задание 2
Создайте Iterable, бесконечно возвращающий числа Фибоначчи.
*Число Фибоначчи — последовательность чисел, которая начинается с 1, 1, 2, 3, 5. Каждое последующее число равно сумме двух предыдущих.
Задание 3
Перепишите прошлое задания, используя генератор function* getFib().
Задание 4
Напишите асинхронный бесконечный генератор подбрасывания монетки async function* flipCoins(). С 50% шансом он возвращает 'tails' или 'heads'. Монетка подбрасывается 200-400 мс.
Подбросьте монетку 10 раз используя for await.
С помощью performance.now(), который возвращает время прошедшее с 1970 года в миллисекундах, определите, сколько времени заняло подбросить 10 монеток.
Задание 1
Напишите функцию isValidJson(str), которая возвращает true, если str — валидный JSON.
Задание 2
Как известно, объект new Date() не сериализуется с помощью JSON.stringify(). Напишите функции serialize(arr) и deserialize(str).
serialize принимает массив элементов, среди которых могут быть объекты типа Date. Каждый такой объект превратите в timestamp и сериализуйте его с помощью JSON.stringify().
А deserialize(str) должен принимать строку полученную с помощью serialize() и возвращать массив объектов, среди которых снова должны появиться объекты типа Date.
Объекты типа Date возможны только на первом уровне вложенности (внутри массива).
Внимание: возможно перепутать timestamp и просто число, учтите это.
Задание 3
Перепишите функцию memo(fn) так, чтобы её можно было использовать для {fn} с 2+ аргументами. Сериализуйте аргументы для запоминания в JSON. Подумайте, какие есть ограничения и минусы у такого подхода.
Задание 1
Напишите функцию createCounter(n), которая создает объект с методами count(), увеличивающий {n} на 1, print(), печатающий {n} в консоль, и set(n), устанавливающий новый {n}.
Задание 2
Добавьте возможность цепного вызова методов counter:
Задание 3
Исправьте код так, чтобы this не терялось.
Исходный код:

Задание 4
Снова исправьте код так, чтобы this не терялось. Вспомните про стрелочные функции.
Исходный код:
Задание 5
Еще раз перепишите функцию memo(fn) так, чтобы её можно было использовать для методов объекта (чтобы this в теле fn не терялся).
Пояснение: используйте call или apply.
Задание 1
Напишите функцию print(iterable), которая принимает Set или Map и печатает в консоль значения этих структур в виде "key: {key}, value: {value}", если это Map, и просто "value: {value}", если это Set.
Задание 2
Напишите функцию uniqueChars(str), которая принимает строку и возвращает количество уникальных символов в строке.
Задание 3
Напишите функцию onlyUniqueLength(arr), которая принимает массив строк и удаляет дублирующиеся по длине строки. То есть: onlyUniqueLength(['1', '2', '3', '44']) ⇒ ['1', '44'].
Остаться должна именно первая найденная строка каждой длины, порядок гарантирован.
Задание 4
Напишите функцию, которая принимает объект массивов и возвращает Map Set-ов.
Задание 5
И ещё раз перепишите memo(fn) так, чтобы аргументы и возвращаемое значение хранились в new Map(), а для сравнения аргументов вместо JSON.stringify использовалась функция hash, принимающая аргументы возвращающая нечто, что легко сравнить (например строки или числа). Кэшируйте все вызовы, переименуйте memo в withCache.
Сигнатура должна теперь выглядеть следующим образом: withCache(fn, hash).