Читать книгу JavaScript: От Основ до Full-Stack Разработки (Александр Ольшевски) онлайн бесплатно на Bookz (4-ая страница книги)
JavaScript: От Основ до Full-Stack Разработки
JavaScript: От Основ до Full-Stack Разработки
Оценить:

4

Полная версия:

JavaScript: От Основ до Full-Stack Разработки

Задание 3: Обработчик корзины покупок

javascript

// 1. Создайте функцию addToCart(item, quantity = 1, cart = []), которая:

// - Добавляет товар в корзину

// - Если товар уже есть, увеличивает количество

// - Возвращает НОВЫЙ массив корзины (не изменяя исходный)

// 2. Создайте функцию calculateTotal(cart), которая:

// - Принимает массив товаров { price, quantity }

// - Считает общую стоимость

// - Применяет скидку 5% если сумма > 1000

// - Использует rest parameters и for...of

Задание 4: Утилиты для работы с DOM

javascript

// 1. Создайте функцию createElement(tag, classes = [], text = ''), которая:

// - Создает HTML-элемент указанного тега

// - Добавляет CSS-классы из массива

// - Устанавливает текстовое содержимое

// - Возвращает готовый элемент

// 2. Создайте функцию debounce(callback, delay), которая:

// - "Откладывает" вызов функции callback

// - При повторном вызове сбрасывает таймер

// - Использует замыкание для хранения timeoutId

Ответы и решения

Решение задания 1:

javascript

// Валидатор email

function validateEmail(email) {

if (typeof email !== 'string') return false;

const parts = email.split('@');

return parts.length === 2 && parts[1].length >= 2;

}

// Валидатор пароля

function validatePassword(password, minLength = 8) {

const errors = [];


if (password.length < minLength) {

errors.push(`Пароль должен быть не менее ${minLength} символов`);

}


if (!/\d/.test(password)) {

errors.push('Пароль должен содержать хотя бы одну цифру');

}


return {

isValid: errors.length === 0,

errors: errors

};

}

// Примеры использования:

console.log(validateEmail('user@example.com')); // true

console.log(validatePassword('secret123')); // { isValid: true, errors: [] }


Решение задания 2:

javascript

function createUserCard(userData) {

const {

name = 'Аноним',

email = '',

avatar = '/default-avatar.png',

isOnline = false

} = userData;


return `

${name}

`;

}

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

const user = { name: 'Иван', email: 'ivan@test.ru', isOnline: true };

console.log(createUserCard(user));


Решение задания 3:

javascript

// Добавление в корзину

function addToCart(item, quantity = 1, cart = []) {

const newCart = [...cart]; // Создаем копию

const existingItem = newCart.find(cartItem => cartItem.id === item.id);


if (existingItem) {

existingItem.quantity += quantity;

} else {

newCart.push({ ...item, quantity });

}


return newCart;

}

// Расчет суммы

function calculateTotal(...items) {

let subtotal = 0;


for (let item of items) {

subtotal += item.price * item.quantity;

}


const discount = subtotal > 1000 ? subtotal * 0.05 : 0;


return {

subtotal: subtotal,

discount: discount,

total: subtotal - discount

};

}

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

const cart = addToCart({ id: 1, name: 'Книга', price: 500 }, 2);

const total = calculateTotal(...cart);

console.log(total);


Решение задания 4:

javascript

// Создание DOM-элемента

function createElement(tag, classes = [], text = '') {

const element = document.createElement(tag);


if (classes.length > 0) {

element.classList.add(...classes);

}


if (text) {

element.textContent = text;

}


return element;

}

// Дебаунс

function debounce(callback, delay) {

let timeoutId;


return function(...args) {

clearTimeout(timeoutId);

timeoutId = setTimeout(() => {

callback.apply(this, args);

}, delay);

};

}

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

const searchInput = document.getElementById('search');

const debouncedSearch = debounce((query) => {

console.log('Ищем:', query);

}, 300);

searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));


Чек-лист самопроверки:

Я могу создавать чистые функции без побочных эффектов

Понимаю разницу между параметрами и аргументами

Умею использовать значения по умолчанию

Могу работать с rest parameters и spread оператором

Понимаю области видимости и замыкания

Могу создавать функции-утилиты для реальных задач


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

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

Глава 6: Структуры Данных: Как Организовать Информацию.

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

Термин: Структура данных (Data Structure) — это способ организации, управления и хранения данных, который позволяет эффективно выполнять операции над ними.

Наиболее фундаментальными структурами данных в JavaScript являются массивы (Arrays) и объекты (Objects).

6.1. Массивы (Arrays): Работа с коллекциями

Термин: Массив (Array) — это упорядоченная коллекция элементов. Каждый элемент в массиве имеет свой индекс – числовое значение, определяющее его позицию в массиве. Индексация в JavaScript, как и во многих других языках программирования, начинается с нуля (0).

Создание массива:

Массивы создаются с помощью квадратных скобок []. Элементы внутри скобок разделяются запятыми.

javascript

// Пустой массив

let emptyArray = [];

// Массив строк

let fruits = ["яблоко", "банан", "апельсин"];

// Массив чисел

let numbers = [1, 2, 3, 4, 5];

// Массив смешанных типов (хотя обычно стараются делать массивы однотипными для читаемости)

let mixedArray = ["текст", 10, true, null];

Доступ к элементам массива:

Доступ к элементу осуществляется по его индексу, используя квадратные скобки.

javascript

let fruits = ["яблоко", "банан", "апельсин"];

console.log(fruits[0]); // Выведет: яблоко (первый элемент)

console.log(fruits[1]); // Выведет: банан (второй элемент)

console.log(fruits[2]); // Выведет: апельсин (третий элемент)

// Можно получить длину массива

console.log(fruits.length); // Выведет: 3

// Доступ к последнему элементу:

console.log(fruits[fruits.length - 1]); // Выведет: апельсин

Изменение элементов массива:

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

javascript

let colors = ["красный", "зеленый", "синий"];

colors[1] = "желтый"; // Заменяем "зеленый" на "желтый"

console.log(colors); // Выведет: ["красный", "желтый", "синий"]

Добавление и удаление элементов (основные методы):

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

push(element): Добавляет один или несколько элементов в конец массива. Возвращает новую длину массива.javascriptlet numbers = [1, 2];

numbers.push(3); // numbers теперь: [1, 2, 3]

numbers.push(4, 5); // numbers теперь: [1, 2, 3, 4, 5]

let newLength = numbers.push(6);

console.log(numbers); // [1, 2, 3, 4, 5, 6]

console.log(newLength); // 6

pop(): Удаляет последний элемент из массива и возвращает его.javascriptlet fruits = ["яблоко", "банан", "апельсин"];

let lastFruit = fruits.pop();

console.log(fruits); // ["яблоко", "банан"]

console.log(lastFruit); // "апельсин"

unshift(element): Добавляет один или несколько элементов в начало массива. Возвращает новую длину массива.javascriptlet numbers = [2, 3];

numbers.unshift(1); // numbers теперь: [1, 2, 3]

numbers.unshift(0, -1); // numbers теперь: [-1, 0, 1, 2, 3]

let newLength = numbers.unshift(-2);

console.log(numbers); // [-2, -1, 0, 1, 2, 3]

console.log(newLength); // 6

shift(): Удаляет первый элемент из массива и возвращает его.javascriptlet fruits = ["яблоко", "банан", "апельсин"];

let firstFruit = fruits.shift();

console.log(fruits); // ["банан", "апельсин"]

console.log(firstFruit); // "яблоко"

Методы для работы с частью массива:

splice(startIndex, deleteCount, item1, item2, ...): Очень мощный метод, который может удалять, добавлять или заменять элементы в массиве.startIndex: Индекс, с которого начинать изменения.

deleteCount: Количество элементов для удаления (0 — если нужно только добавить).

item1, item2, ...: Элементы для добавления (если они есть).

Возвращает массив удаленных элементов (если они были).

javascriptlet numbers = [1, 2, 3, 4, 5];

// Удалить 2 элемента, начиная с индекса 2

let removed = numbers.splice(2, 2);

console.log(numbers); // [1, 2, 5] (удалены 3 и 4)

console.log(removed); // [3, 4]

// Вставить элементы, не удаляя ничего, начиная с индекса 1

numbers.splice(1, 0, "a", "b");

console.log(numbers); // [1, "a", "b", 2, 5]

// Заменить 1 элемент, начиная с индекса 3, на новый элемент

numbers.splice(3, 1, "X");

console.log(numbers); // [1, "a", "b", "X", 5]

slice(startIndex, endIndex): Создает новый массив, содержащий копию части исходного массива. Не изменяет исходный массив.startIndex: Индекс, с которого начинать копирование.

endIndex (необязательный): Индекс, ДО которого включать элементы. Если не указан, копирует до конца массива.

javascriptlet letters = ["a", "b", "c", "d", "e"];

// Скопировать элементы с индекса 1 до индекса 4 (не включая 4)

let subset1 = letters.slice(1, 4);

console.log(subset1); // ["b", "c", "d"]

console.log(letters); // ["a", "b", "c", "d", "e"] (исходный массив не изменился)

// Скопировать элементы с индекса 2 до конца

let subset2 = letters.slice(2);

console.log(subset2); // ["c", "d", "e"]

// Использование отрицательных индексов (отсчет с конца)

let lastTwo = letters.slice(-2); // Два последних элемента

console.log(lastTwo); // ["d", "e"]

Другие полезные методы массивов:

concat(array1, array2, ...): Объединяет два или более массивов в новый массив.javascriptlet arr1 = [1, 2];

let arr2 = [3, 4];

let combined = arr1.concat(arr2, [5, 6]);

console.log(combined); // [1, 2, 3, 4, 5, 6]

console.log(arr1); // [1, 2] (исходный массив не изменился)

Синтаксис с spread-оператором (...) (let combined = [...arr1, ...arr2];) часто предпочтительнее для объединения массивов, так как он более современный и гибкий.

join(separator): Объединяет все элементы массива в одну строку, используя указанный separator. Если separator не указан, используется запятая.javascriptlet words = ["Hello", "world", "!"];

let sentence = words.join(" "); // Объединяем через пробел

console.log(sentence); // "Hello world !"

let numbersString = [1, 2, 3].join("-");

console.log(numbersString); // "1-2-3"

includes(element): Проверяет, есть ли элемент в массиве. Возвращает true или false.javascriptlet numbers = [1, 2, 3, 4];

console.log(numbers.includes(3)); // true

console.log(numbers.includes(5)); // false

indexOf(element): Возвращает индекс первого вхождения элемента в массив. Если элемент не найден, возвращает -1.javascriptlet fruits = ["apple", "banana", "apple", "orange"];

console.log(fruits.indexOf("banana")); // 1

console.log(fruits.indexOf("apple")); // 0 (индекс первого вхождения)

console.log(fruits.indexOf("grape")); // -1

reverse(): Инвертирует порядок элементов в массиве на месте (изменяет исходный массив) и возвращает ссылку на измененный массив.javascriptlet letters = ["a", "b", "c"];

letters.reverse();

console.log(letters); // ["c", "b", "a"]

Итерация по массивам (уже видели for...of, но есть и другие способы):

С помощью for цикла:javascriptlet animals = ["cat", "dog", "elephant"];

for (let i = 0; i < animals.length; i++) {

console.log(`Animal at index ${i}: ${animals[i]}`);

}

forEach(callbackFunction): Выполняет функцию callbackFunction один раз для каждого элемента массива. callbackFunction получает три аргумента: element, index, array.javascriptlet fruits = ["apple", "banana", "cherry"];

fruits.forEach(function(fruit, index, arr) {

console.log(`Fruit at index ${index}: ${fruit}`);

// console.log(arr); // Можно получить доступ к самому массиву

});

// С использованием стрелочной функции:

fruits.forEach((fruit, index) => {

console.log(`Fruit #${index + 1}: ${fruit}`);

});

6.2. Объекты (Objects): Хранение данных в формате “ключ-значение”

Термин: Объект (Object) — это неупорядоченная коллекция свойств. Каждое свойство состоит из ключа (key) и значения (value), которые связаны парой двоеточия :. Ключи обычно являются строками (или символами), а значения могут быть любого типа данных (включая другие объекты или массивы).

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

Создание объекта:

Объекты создаются с помощью фигурных скобок {}.

javascript

// Пустой объект

let emptyObject = {};

// Объект "человек"

let person = {

name: "Алиса", // Свойство: ключ "name", значение "Алиса"

age: 30, // Свойство: ключ "age", значение 30

isStudent: false, // Свойство: ключ "isStudent", значение false

city: "Москва", // Свойство: ключ "city", значение "Москва"

hobbies: ["чтение", "путешествия"] // Свойство: значение - массив

};

// Объект "автомобиль"

let car = {

brand: "Toyota",

model: "Camry",

year: 2022,

// Свойство, значение которого - другой объект

engine: {

type: "Petrol",

volume: 2.5

},

// Свойство, значение которого - функция (метод объекта)

start: function() {

console.log("Двигатель запущен!");

}

};

Доступ к свойствам объекта:

Есть два основных способа:

Точечная нотация (Dot Notation): объект.ключ (наиболее распространенный и предпочтительный способ).javascriptconsole.log(person.name); // Выведет: Алиса

console.log(person.age); // Выведет: 30

console.log(car.brand); // Выведет: Toyota

console.log(car.engine.type); // Доступ к свойству вложенного объекта. Выведет: Petrol

Скобочная нотация (Bracket Notation): объект[ключ] (обязательна, если ключ — переменная или содержит специальные символы/пробелы).javascriptconsole.log(person["name"]); // Выведет: Алиса

console.log(person["city"]); // Выведет: Москва

// Пример, когда скобочная нотация обязательна:

let propertyName = "age";

console.log(person[propertyName]); // Работает! Получим 30.

// person.propertyName выдало бы ошибку или undefined,

// так как искалось бы свойство с ключом "propertyName".

// Если ключ содержит пробелы или спецсимволы, скобочная нотация необходима:

let anotherPerson = {

"first name": "Иван",

"last-name": "Петров"

};

console.log(anotherPerson["first name"]); // "Иван"

// console.log(anotherPerson.first name); // Ошибка!

Изменение и добавление свойств:

Свойства объекта можно изменять или добавлять новые, используя точечную или скобочную нотацию.

javascript

let user = { name: "Петр" };

// Изменение свойства

user.name = "Петр Иванов";

console.log(user.name); // Петр Иванов

// Добавление нового свойства

user.age = 25;

user["isAdmin"] = false; // Добавление через скобочную нотацию

console.log(user); // { name: "Петр Иванов", age: 25, isAdmin: false }

Удаление свойств:

Используется оператор delete.

javascript

let product = { id: 1, name: "Ноутбук", price: 1000 };

delete product.price;

console.log(product); // { id: 1, name: "Ноутбук" }

Методы объектов (функции внутри объектов):

Функции, которые являются свойствами объекта, называются методами.

javascript

let calculator = {

a: 10,

b: 5,

add: function() { // Метод add

return this.a + this.b; // this ссылается на объект calculator

},

subtract: function() { // Метод subtract

return this.a - this.b;

}

};

console.log(calculator.add()); // Выведет: 15

console.log(calculator.subtract()); // Выведет: 5

// Можно вызывать методы объекта:

calculator.result = calculator.add();

console.log(calculator.result); // 15

Термин: this — контекст выполнения. В методах объекта this обычно ссылается на сам объект, который вызывает этот метод. Понимание this — одна из ключевых (и иногда непростых) тем в JavaScript.

Перебор свойств объекта:

for...in цикл: Как мы уже видели, перебирает ключи объекта.javascriptlet book = {

title: "Война и мир",

author: "Лев Толстой",

year: 1869

};

for (let key in book) {

console.log(`${key}: ${book[key]}`);

}

// Вывод:

// title: Война и мир

// author: Лев Толстой

// year: 1869

Object.keys(obj): Возвращает массив ключей объекта. Далее можно использовать forEach или for...of.javascriptlet car = { brand: "BMW", model: "X5", year: 2023 };

let carKeys = Object.keys(car); // ["brand", "model", "year"]

console.log(carKeys);

carKeys.forEach(key => {

console.log(`${key}: ${car[key]}`);

});

Object.values(obj): Возвращает массив значений объекта.javascriptlet car = { brand: "BMW", model: "X5", year: 2023 };

let carValues = Object.values(car); // ["BMW", "X5", 2023]

console.log(carValues);

carValues.forEach(value => {

console.log(value);

});

Object.entries(obj): Возвращает массив пар [ключ, значение].javascriptlet car = { brand: "BMW", model: "X5", year: 2023 };

let carEntries = Object.entries(car);

// carEntries будет: [ ["brand", "BMW"], ["model", "X5"], ["year", 2023] ]

console.log(carEntries);

carEntries.forEach(entry => {

let key = entry[0];

let value = entry[1];

console.log(`${key}: ${value}`);

});

// С деструктуризацией (очень удобно!):

carEntries.forEach(([key, value]) => {

console.log(`${key} --> ${value}`);

});

6.3. Объект Math

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

Популярные свойства:

Math.PI: Число Пи (≈ 3.14159)

Math.E: Основание натурального логарифма (≈ 2.71828)

Популярные методы:

Math.round(x): Округляет число x до ближайшего целого.javascriptconsole.log(Math.round(4.7)); // 5

console.log(Math.round(4.4)); // 4

console.log(Math.round(4.5)); // 5

Math.floor(x): Округляет число x вниз до ближайшего целого.javascriptconsole.log(Math.floor(4.7)); // 4

console.log(Math.floor(4.4)); // 4

console.log(Math.floor(-4.4)); // -5 (округляет вниз, т.е. к меньшему числу)

Math.ceil(x): Округляет число x вверх до ближайшего целого.javascriptconsole.log(Math.ceil(4.7)); // 5

console.log(Math.ceil(4.4)); // 5

console.log(Math.ceil(-4.4)); // -4 (округляет вверх, т.е. к большему числу)

Math.abs(x): Возвращает абсолютное значение (модуль) числа x.javascriptconsole.log(Math.abs(-10)); // 10

console.log(Math.abs(10)); // 10

Math.sqrt(x): Возвращает квадратный корень из x.javascriptconsole.log(Math.sqrt(9)); // 3

console.log(Math.sqrt(2)); // 1.4142135623730951

Math.pow(base, exponent): Возвращает base в степени exponent.javascriptconsole.log(Math.pow(2, 3)); // 8 (2 в кубе)

console.log(Math.pow(5, 2)); // 25 (5 в квадрате)

Math.random(): Возвращает псевдослучайное число с плавающей точкой между 0 (включительно) и 1 (не включительно).javascriptconsole.log(Math.random()); // Например: 0.123456789...

console.log(Math.random()); // Другое случайное число

Генерация случайного целого числа в диапазоне: Часто нужно получить случайное целое число, например, от 0 до 9.javascript// Случайное целое от 0 до 9 (включительно)

let min = 0;

let max = 9;

let randomInt = Math.floor(Math.random() * (max - min + 1)) + min;

console.log(randomInt); // Будет число от 0 до 9

Math.random() * (max - min + 1): Создает случайное число от 0 до max - min + 1 (не включая верхнюю границу).

Math.floor(...): Округляет вниз, чтобы получить целое число.

+ min: Сдвигает диапазон, чтобы он начинался с min.

6.4. Объект Date

Термин: Объект Date — это встроенный объект JavaScript, который используется для работы с датами и временем. Он позволяет создавать, получать и устанавливать компоненты даты и времени (год, месяц, день, час, минута, секунда).

Создание объекта Date:

Без аргументов: Создает объект Date с текущей датой и временем.javascriptlet now = new Date();

console.log(now); // Выведет текущую дату и время в формате, зависящем от локали

bannerbanner