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

4

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

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

}


let max = numbers[0];

let min = numbers[0];

let sum = 0;

let evenCount = 0;

let oddCount = 0;

let primes = [];


// Основной цикл анализа

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

const num = numbers[i];


// Поиск максимума и минимума

if (num > max) max = num;

if (num < min) min = num;


// Сумма для среднего значения

sum += num;


// Четные/нечетные

if (num % 2 === 0) {

evenCount++;

} else {

oddCount++;

}


// Проверка на простое число

if (isPrime(num)) {

primes.push(num);

}

}

return {

max: max,

min: min,

average: sum / numbers.length,

evenCount: evenCount,

oddCount: oddCount,

primes: primes,

totalCount: numbers.length

};

}

// Вспомогательная функция для проверки простых чисел

function isPrime(num) {

if (num < 2) return false;

for (let i = 2; i <= Math.sqrt(num); i++) {

if (num % i === 0) return false;

}

return true;

}

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

console.log(analyzeArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]));

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

javascript

const products = [

{ name: "Телефон", price: 500, category: "electronics", stock: 15 },

{ name: "Книга", price: 20, category: "education", stock: 0 },

{ name: "Наушники", price: 100, category: "electronics", stock: 8 },

{ name: "Ручка", price: 5, category: "education", stock: 50 }

];

// 1. Товары не в наличии

const outOfStock = [];

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

if (products[i].stock === 0) {

outOfStock.push(products[i].name);

}

}

// 2. Общая стоимость электроники

let electronicsTotal = 0;

for (let product of products) {

if (product.category === "electronics") {

electronicsTotal += product.price * product.stock;

}

}

// 3. Товары с ценой > 50 и остатком < 10

const criticalProducts = [];

let index = 0;

while (index < products.length) {

const product = products[index];

if (product.price > 50 && product.stock < 10) {

criticalProducts.push({

name: product.name,

price: product.price,

stock: product.stock

});

}

index++;

}

console.log("Нет в наличии:", outOfStock);

console.log("Общая стоимость электроники:", electronicsTotal);

console.log("Критические товары:", criticalProducts);


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

Я могу создавать сложные условия с помощью if/else и switch

Понимаю разницу между циклами for, while и for…of

Умею использовать тернарный оператор для простых условий

Могу анализировать данные массивов с помощью циклов и условий

Понимаю, когда использовать break и continue в циклах

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

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

Глава 5: Функции: Ваш Инструментарий.

В предыдущих главах мы много говорили о том, как выполнять код последовательно, принимать решения и повторять действия. Но представьте, что нам нужно выполнить один и тот же набор действий в разных частях программы. Копировать и вставлять код – плохая практика. Это делает код громоздким, трудным для чтения и поддержки, и увеличивает риск ошибок.

Решение этой проблемы – функции.

Термин: Функция (Function) – это именованный блок кода, который выполняет определенную задачу. Вы можете “вызвать” функцию по ее имени, чтобы выполнить этот блок кода. Функции позволяют нам:

Повторно использовать код: Написать код один раз и использовать его многократно.

Разбивать большие задачи на мелкие: Делать программу более модульной и понятной.

Улучшать читаемость кода: Давать осмысленные имена блокам кода.

Упрощать тестирование и отладку: Легче тестировать и находить ошибки в небольших, изолированных функциях.

5.1. Создание функций: Function Declaration vs. Function Expression

Есть несколько способов определить (объявить) функцию в JavaScript. Два самых распространенных – это Function Declaration и Function Expression.

А) Function Declaration (Объявление функции)

Это стандартный способ объявления функции.

Синтаксис: function имяФункции(параметр1, параметр2, …) { // тело функции (код) }

function – ключевое слово, которое указывает, что мы объявляем функцию.

имяФункции – уникальное имя, по которому мы будем вызывать функцию. Следуйте правилам именования переменных (обычно CamelCase, например, calculateSum).

параметр1, параметр2, … – это параметры функции. Они действуют как временные переменные, которые получают значения, передаваемые в функцию при ее вызове. Параметры необязательны; функция может не принимать никаких аргументов.

{ // тело функции } – блок кода, который будет выполнен при вызове функции.

Пример 5.1.1: Функция приветствия

javascript

function greetUser() {

console.log("Приветствую тебя!");

}

// Вызов функции:

greetUser(); // Выведет: Приветствую тебя!

greetUser(); // Можно вызвать несколько раз

Пример 5.1.2: Функция с параметрами

javascript

function greetUserByName(name) { // name – параметр

console.log(`Приветствую, ${name}!`);

}

greetUserByName("Алиса"); // Выведет: Приветствую, Алиса!

greetUserByName("Боб"); // Выведет: Приветствую, Боб!

Когда мы вызываем greetUserByName("Алиса"), строка "Алиса" передается как аргумент в функцию, и внутри функции переменная name получает значение "Алиса".

Поднятие (Hoisting): Одна из особенностей Function Declaration в JavaScript – это “поднятие”. Это означает, что функция, объявленная таким образом, доступна для вызова до того, как она фактически объявлена в коде.

javascript

sayHello(); // Это сработает!

function sayHello() {

console.log("Привет!");

}

JavaScript “поднимает” объявление функции sayHello в начало области видимости. Это удобно, но иногда может сбивать с толку начинающих, поэтому стоит помнить об этом.

Б) Function Expression (Выражение функции)

При таком подходе функция определяется как часть выражения (обычно присваивается переменной).

Синтаксис: let имяПеременной = function(параметр1, …) { // тело функции };

javascript

let greetSomeone = function(name) {

console.log(`Приветствую, ${name}!`);

};

// Вызов функции:

greetSomeone("Чарли"); // Выведет: Приветствую, Чарли!

Основные отличия от Function Declaration:

Поднятие: Функции, определенные как Function Expression, не поднимаются так же, как Function Declaration. Если вы попытаетесь вызвать такую функцию до ее объявления, вы получите ошибку TypeError.javascript// sayGoodbye(); // Ошибка! TypeError: sayGoodbye is not a function

let sayGoodbye = function(name) {

console.log(`До свидания, ${name}!`);

};

sayGoodbye("Дэвид"); // Теперь сработает

Анонимные функции: Function Expression может быть анонимной (без имени), как в примере greetSomeone. Это часто используется при передаче функций в качестве аргументов другим функциям (например, в обработчиках событий или при использовании методов массивов).

5.2. Стрелочные функции (Arrow Functions)

С появлением стандарта ES6 (ECMAScript 2015) были введены стрелочные функции – более краткий и удобный синтаксис для записи функций, особенно для простых случаев.

Синтаксис (основные варианты):

С одним параметром (или без параметров) и одним выражением в теле: Скобки вокруг параметра и фигурные скобки {} опускаются. Результат выражения возвращается автоматически.javascript// Было:

// let greetUserByName = function(name) {

// return `Приветствую, ${name}!`;

// };

// Стало (стрелочная функция):

let greetUserByName = name => `Приветствую, ${name}!`; // скобки вокруг name опущены

console.log(greetUserByName("Ева")); // Выведет: Приветствую, Ева!

// Без параметров:

// let showMessage = function() { return "Сообщение!"; };

let showMessage = () => "Сообщение!"; // Скобки для параметров обязательны, если их нет

console.log(showMessage()); // Выведет: Сообщение!

С несколькими параметрами или несколькими выражениями в теле: Параметры заключаются в скобки, а тело функции – в фигурные скобки {}. В этом случае нужно явно использовать return, если вы хотите вернуть значение.javascript// Было:

// let calculateSum = function(a, b) {

// let sum = a + b;

// return sum;

// };

// Стало (стрелочная функция):

let calculateSum = (a, b) => { // скобки для параметров обязательны

let sum = a + b;

return sum; // return нужен, так как тело функции больше одного выражения

};

console.log(calculateSum(5, 3)); // Выведет: 8

Важные особенности стрелочных функций:

Краткость: Особенно удобны для простых функций.

Отсутствие this: Стрелочные функции не имеют своего собственного контекста this. Они “захватывают” this из окружающей (лексической) области видимости. Это одно из самых важных отличий и делает их очень полезными в определенных ситуациях (например, при работе с методами объектов или внутри обработчиков событий). Мы подробно разберем this позже.

Не подходят для: Методов объектов (если вы хотите, чтобы this ссылался на сам объект), конструкторов (функций, вызываемых с new).

5.3. Параметры и аргументы функций

Мы уже мельком коснулись параметров и аргументов. Давайте разберемся подробнее.

Параметры (Parameters): Имена переменных, перечисленные в определении функции. Они действуют как “приемники” для входящих данных.

Аргументы (Arguments): Фактические значения, которые передаются в функцию при ее вызове.

javascript

function multiply(num1, num2) { // num1 и num2 – ПАРАМЕТРЫ

let result = num1 * num2;

console.log(`Результат умножения ${num1} на ${num2} равен ${result}`);

}

multiply(5, 3); // 5 и 3 – АРГУМЕНТЫ. num1 станет 5, num2 станет 3.

multiply(10, 2); // 10 и 2 – АРГУМЕНТЫ. num1 станет 10, num2 станет 2.

Что происходит, если аргументов меньше или больше, чем параметров?

Недостаточно аргументов: Если вы передали меньше аргументов, чем параметров, недостающие параметры получат значение undefined.javascriptfunction greet(firstName, lastName) {

console.log(`Привет, ${firstName} ${lastName}`);

}

greet("Алиса"); // Выведет: Привет, Алиса undefined

Чтобы избежать этого, можно использовать значения параметров по умолчанию (ES6).javascriptfunction greetWithDefault(firstName, lastName = "Гость") { // lastName по умолчанию "Гость"

console.log(`Привет, ${firstName} ${lastName}`);

}

greetWithDefault("Алиса"); // Привет, Алиса Гость

greetWithDefault("Боб", "Смит"); // Привет, Боб Смит

Слишком много аргументов: Если вы передали больше аргументов, чем параметров, “лишние” аргументы просто игнорируются (если вы не используете специальные техники, такие как arguments или rest-параметры).javascriptfunction addTwoNumbers(a, b) {

console.log(a + b);

}

addTwoNumbers(2, 3, 100); // Выведет: 5 (аргумент 100 проигнорирован)

Термин: Аргументы по умолчанию (Default Parameters) – возможность задать значения для параметров функции, которые будут использоваться, если при вызове функции соответствующие аргументы не были переданы.

Термин: Rest-параметры (Rest Parameters) … (ES6) – Позволяют представить неизвестное количество аргументов как массив. Это более гибкая альтернатива старому объекту arguments.

javascript

function sumAll(…numbers) { // numbers будет массивом всех переданных аргументов

let total = 0;

for (let num of numbers) {

total += num;

}

return total;

}

console.log(sumAll(1, 2, 3)); // Выведет: 6

console.log(sumAll(10, 20, 30, 40)); // Выведет: 100

console.log(sumAll()); // Выведет: 0

Rest-параметры должны быть последними в списке параметров.

5.4. Возвращаемые значения (return)

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

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

Если в функции нет return, или return используется без значения, функция неявно возвращает undefined.

Пример 5.4.1: Функция, возвращающая результат

javascript

function calculateArea(width, height) {

if (width <= 0 || height <= 0) {

console.error("Ширина и высота должны быть положительными числами.");

return undefined; // Явно возвращаем undefined в случае ошибки

}

let area = width * height;

return area; // Возвращаем вычисленное значение

}

let rectangle1Area = calculateArea(10, 5); // 50 будет присвоено rectangle1Area

console.log("Площадь 1:", rectangle1Area); // Площадь 1: 50

let rectangle2Area = calculateArea(8, 4);

console.log("Площадь 2:", rectangle2Area); // Площадь 2: 32

let invalidArea = calculateArea(-2, 5); // Выведет ошибку в консоль

console.log("Некорректная площадь:", invalidArea); // Некорректная площадь: undefined

Пример 5.4.2: Функция, не возвращающая значения (неявно возвращает undefined)

javascript

function displayMessage(msg) {

console.log("Сообщение: " + msg);

// Нет return

}

let result = displayMessage("Привет!"); // result будет undefined

console.log("Результат вызова функции:", result); // Результат вызова функции: undefined

5.5. Область видимости (Scope)

Мы уже касались области видимости let и const (блочная) и var (функциональная). Давайте углубимся.

Термин: Область видимости (Scope) – это набор правил, определяющий, где в вашем коде доступны переменные и функции.

JavaScript имеет две основные области видимости:

Глобальная область видимости (Global Scope): Переменные, объявленные вне каких-либо функций или блоков, находятся в глобальной области видимости. Они доступны из любой части вашего кода. В браузере глобальный объект – это window.

Локальная область видимости (Local Scope):Функциональная область видимости: Переменные, объявленные с помощью var внутри функции, доступны только внутри этой функции.

Блочная область видимости: Переменные, объявленные с помощью let и const внутри блока кода (например, {…} внутри if, for, или просто отдельный блок), доступны только внутри этого блока.

Пример 5.5.1: Демонстрация областей видимости

javascript

// Глобальная переменная

let globalVar = "Я глобальный";

function myFunction() {

// Локальная переменная для myFunction

let localVar = "Я локальный для myFunction";

console.log(globalVar); // Доступ к глобальной переменной

console.log(localVar); // Доступ к локальной переменной

if (true) {

// Блочная переменная

let blockVar = "Я внутри блока if";

console.log(blockVar); // Доступ к блочной переменной

console.log(localVar); // Доступ к локальной переменной функции

}

// console.log(blockVar); // Ошибка! blockVar не виден вне блока if

}

myFunction();

console.log(globalVar); // Доступ к глобальной переменной

// console.log(localVar); // Ошибка! localVar не виден вне myFunction

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

Термин: Замыкание (Closure) – более продвинутая концепция, связанная с областями видимости. Это функция, которая “помнит” переменные из той области видимости, в которой она была создана, даже если эта область видимости уже не активна. Мы подробно разберем замыкания позже, но важно понимать, что функции имеют доступ к переменным из внешних областей видимости.

Практическое задание:

Задание 1: Валидатор данных формы

javascript

// 1. Создайте функцию validateEmail(email), которая проверяет:

// – Наличие символа @

// – Длину доменной части не менее 2 символов

// – Возвращает true/false

// 2. Создайте функцию validatePassword(password, minLength = 8), которая:

// – Проверяет длину пароля

// – Проверяет наличие хотя бы одной цифры

// – Возвращает объект { isValid: boolean, errors: [] }

Задание 2: Генератор контента для интерфейса

javascript

// 1. Создайте функцию createUserCard(userData), которая принимает объект с данными:

// { name, email, avatar, isOnline }

// 2. Функция должна ВОЗВРАЩАТЬ HTML-строку для карточки пользователя:

// – Если isOnline = true, добавить класс 'online'

// – Если avatar отсутствует, использовать аватар по умолчанию

// – Использовать значения по умолчанию для отсутствующих полей

Задание 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] = "желтый"; // Заменяем "зеленый" на "желтый"

bannerbanner