JavaScript

Бизюк Андрей

ВГТУ

2024-12-03

Введение в JavaScript

Описание

JavaScript - это высокоуровневый, интерпретируемый язык программирования, который применяется для создания интерактивных веб-страниц. В этом разделе мы рассмотрим основы JavaScript и его ключевые характеристики:

Роль JavaScript в веб-разработке

  • JavaScript является одним из трех основных языков веб-разработки, вместе с HTML (Hypertext Markup Language) и CSS (Cascading Style Sheets).
  • Он выполняется на стороне клиента, в браузере пользователя, и обеспечивает интерактивность и динамичность веб-страниц.

JavaScript играет ключевую роль в веб-разработке и взаимодействии с веб-страницами. Вот основные роли JavaScript в веб-разработке:

  1. Интерактивность: JavaScript позволяет делать веб-страницы интерактивными. Это означает, что пользователи могут взаимодействовать с содержанием страницы, выполнять действия и получать мгновенные отклики. Примеры включают клики на кнопки, отправку форм, изменение содержания страницы без перезагрузки и многое другое.

  2. Валидация форм: JavaScript используется для валидации данных, введенных пользователями в формы на веб-страницах. Это помогает предотвращать отправку неправильных данных на сервер и обеспечивать более удобный опыт пользователей.

  3. Асинхронные запросы: JavaScript позволяет выполнять асинхронные HTTP-запросы к серверу (AJAX - Asynchronous JavaScript and XML). Это позволяет обновлять части страницы без полной перезагрузки, загружать данные с сервера без прерывания работы пользователя и создавать более быстрые и отзывчивые веб-приложения.

  4. Манипуляция DOM: DOM (Document Object Model) представляет структуру HTML-документа в виде объектов, с которыми JavaScript может взаимодействовать. JavaScript может изменять содержимое и структуру страницы, добавлять, удалять или изменять элементы, а также обрабатывать события, происходящие на странице.

  5. Куки и локальное хранилище: JavaScript позволяет управлять куки (cookie) и локальным хранилищем (localStorage и sessionStorage) на стороне клиента. Это используется для сохранения информации между сеансами пользователя и локального хранения данных.

  6. Анимации: JavaScript может использоваться для создания анимаций и переходов на веб-страницах, что делает страницы более привлекательными и информативными.

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

  8. События и обработчики: JavaScript позволяет обрабатывать события, такие как клики, наведение мыши, нажатия клавиш и другие пользовательские действия. Вы можете назначать обработчики событий для реагирования на эти события и выполнять определенные действия.

  9. Динамическое обновление данных: JavaScript может загружать данные с сервера и обновлять их на странице без перезагрузки. Это особенно полезно для приложений, где данные постоянно меняются.

История JavaScript

  1. Ранние годы (1995-1997):
    • JavaScript был создан Бренданом Айком (Brendan Eich) в 1995 году, когда он работал в компании Netscape Communications.
    • Он изначально назывался LiveScript, но позже был переименован в JavaScript (вопреки распространенному мнению, он не имеет непосредственного отношения к языку программирования Java).
  2. JavaScript и Netscape:
    • JavaScript был впервые внедрен в браузер Netscape Navigator 2.0 в 1995 году. Это позволило веб-разработчикам создавать динамические элементы и интерактивные компоненты на веб-страницах.
  3. Борьба за стандартизацию (конец 1990-х):
    • В это время Microsoft ввел свой вариант JavaScript, названный JScript, в Internet Explorer.
    • Это привело к конкуренции между разработчиками браузеров и стандартами языка.
    • Для устранения этой конфликтности Netscape передала спецификацию языка в организацию ECMA International (European Computer Manufacturers Association).
  4. ECMAScript и стандартизация (1997):
    • В 1997 году была опубликована первая версия стандарта ECMAScript, который стал основой для развития языка JavaScript.
    • ECMAScript определяет синтаксис и основные функции языка.
  5. Дальнейшее развитие (2000-н.в.):
    • С течением времени JavaScript становился все более мощным и широко используемым языком в веб-разработке.
    • Постепенно внедрялись новые возможности, такие как поддержка AJAX (асинхронных запросов) и создание множества фреймворков и библиотек для облегчения разработки.
  6. Современное состояние (2020-н.в.):
    • JavaScript остается одним из самых важных языков программирования, используемых в веб-разработке.
    • ECMAScript продолжает развиваться, и новые версии стандарта вносят улучшения и новые функции, делая язык более мощным и удобным для разработчиков.
    • JavaScript используется не только на клиентской стороне (браузере), но и на серверной стороне, благодаря платформам, таким как Node.js.

Классификация языка

JavaScript можно классифицировать по разным критериям. Вот несколько важных аспектов классификации:

  1. Тип языка:
    • Динамически типизированный: JavaScript не требует явного указания типов переменных; типы определяются автоматически во время выполнения.
    • Слабо типизированный: JavaScript позволяет выполнять множество неявных преобразований типов, что может привести к некоторым особенностям в работе с данными.
  2. Парадигмы программирования:
    • JavaScript поддерживает несколько парадигм программирования, включая процедурное, объектно-ориентированное и функциональное программирование.
  3. Место выполнения:
    • JavaScript выполняется на стороне клиента, в браузере пользователя, а также на стороне сервера с использованием платформы Node.js.
  4. Стандарты и версии:
    • JavaScript основывается на стандарте ECMAScript, и разные версии этого стандарта добавляют новые функции и улучшения. Например, ECMAScript 6 (ES6) внесло множество новых возможностей, таких как стрелочные функции, классы и другие.
  5. Использование:
    • JavaScript широко используется для создания интерактивных веб-страниц и веб-приложений. Он также может быть применен для разработки серверных приложений и настольных приложений с использованием фреймворков и библиотек.
  6. Способы выполнения:
    • JavaScript может быть встроен непосредственно в HTML-документы с использованием тега <script>, загружен внешними скриптами, выполнен в консоли браузера, а также на сервере при использовании Node.js.
  7. Экосистема и фреймворки:
    • JavaScript имеет обширную экосистему библиотек и фреймворков, таких как React, Angular, Vue.js для разработки клиентской части, и Express, Koa, Nest.js для серверной разработки.
  8. Браузерная совместимость:
    • JavaScript может быть выполнен в большинстве современных браузерах, и существуют методы обеспечения совместимости с различными версиями браузеров.

Синтаксис JavaScript

Введение

  • JavaScript имеет синтаксис, подобный другим языкам программирования, таким как Java и C. Однако он также имеет свои уникальные черты.
  • JavaScript чувствителен к регистру (case-sensitive), что означает, что переменные myVar и myvar считаются разными.
  1. Первая программа на JavaScript:

    • Пример простой программы на JavaScript, выводящей сообщение в консоль:
    console.log("Привет, мир!");
  2. Интеграция в HTML:

    • JavaScript-код можно встроить непосредственно в HTML-документы с использованием тега <script>.
    <script>
      // JavaScript-код здесь
      console.log("Привет, мир!");
    </script>

Комментарии

  • Однострочные комментарии начинаются с двойной косой черты //. Например:

    // Это однострочный комментарий
  • Многострочные комментарии заключаются в /* и */ и могут включать несколько строк:

    /*
    Это
    многострочный
    комментарий
    */

Переменные

Переменные - это основной элемент программирования, в том числе и в JavaScript. Они используются для хранения данных и значений, которые могут быть использованы в вашем коде. В JavaScript, существуют три способа объявления переменных: var, let, и const. Давайте рассмотрим каждый из них:

  1. var:

    • var было стандартным способом объявления переменных в JavaScript до появления let и const.
    • Переменные, объявленные с использованием var, имеют область видимости в пределах функции (если они объявлены внутри функции) или имеют глобальную область видимости (если объявлены за пределами функции).
    • Они могут быть переобъявлены и переопределены.

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

    var x = 5;
    var name = "John";
  2. let:

    • let было введено в ECMAScript 6 (ES6) и стало рекомендуемым способом объявления переменных.
    • Переменные, объявленные с использованием let, имеют блочную область видимости, что означает, что они видимы только в блоке кода, в котором они были объявлены.
    • Они могут быть переопределены, но не переобъявлены в том же блоке.

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

    let age = 30;
    let country = "USA";
  3. const:

    • const также было введено в ES6 и используется для объявления переменных с постоянным (константным) значением.
    • Переменные, объявленные с использованием const, должны быть инициализированы при объявлении и не могут быть переопределены или переобъявлены.

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

    const pi = 3.14159;
    const daysInWeek = 7;

При выборе, какую форму объявления переменных использовать, рекомендуется предпочитать let и const, так как они предоставляют более строгие правила области видимости и могут помочь избежать некоторых ошибок в коде. Важно выбирать подходящий тип переменной в зависимости от того, будет ли значение переменной изменяться или оставаться постоянным.

Типы данных

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

  1. Числа (Numbers):
    • Числовой тип данных используется для хранения чисел, как целых, так и с плавающей точкой.

    • Примеры:

      let age = 30;
      let pi = 3.14159;
  2. Строки (Strings):
    • Строки представляют текстовую информацию и могут быть заключены в одинарные или двойные кавычки.

    • Примеры:

      let name = "John";
      let message = 'Привет, мир!';
  3. Булевы значения (Booleans):
    • Булевы значения представляют истину (true) или ложь (false).

    • Они часто используются в условных операторах.

    • Примеры:

      let isAdult = true;
      let isStudent = false;
  4. Массивы (Arrays):
    • Массивы используются для хранения упорядоченных списков значений.

    • Они могут содержать элементы разных типов данных.

    • Примеры:

      let fruits = ["яблоко", "банан", "апельсин"];
      let mixedArray = [42, "строка", true];
  5. Объекты (Objects):
    • Объекты используются для группировки ключей (свойств) и значений.

    • Они представляют сложные структуры данных и используются для описания объектов в реальном мире.

    • Пример:

      let person = {
        name: "Иван",
        age: 25,
        isStudent: false
      };
  6. Null и Undefined:
    • null представляет отсутствие значения.

    • undefined указывает на то, что переменная объявлена, но ей не присвоено значение.

    • Примеры:

      let emptyValue = null;
      let notDefined;
  7. Символы (Symbols):
    • Символы представляют уникальные и неизменяемые значения и используются в определенных контекстах, таких как создание уникальных ключей для свойств объектов.
  8. Функции (Functions):
    • Функции являются типом данных, позволяющим определять и вызывать повторно используемый код.
    • Они также могут быть сохранены в переменных и передаваться в качестве аргументов.
  9. Объекты даты (Date Objects):
    • Для работы с датами и временем используются объекты Date.
  10. Регулярные выражения (Regular Expressions):
    • Регулярные выражения представляют шаблоны для поиска и сопоставления текста.

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

Операторы

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

  1. Арифметические операторы:

    • +: Сложение
    • -: Вычитание
    • *: Умножение
    • /: Деление
    • %: Остаток от деления (модуль)
    • **: Возведение в степень (ES6)

    Примеры:

    let x = 10;
    let y = 5;
    
    let сумма = x + y;
    let разница = x - y;
    let произведение = x * y;
    let частное = x / y;
    let остаток = x % y;
    let степень = x ** y;
  2. Операторы присваивания:

    • =: Присваивание значения переменной.

    Пример:

    let x = 10;
  3. Инкремент и декремент:

    • ++: Инкремент (увеличение на 1)
    • --: Декремент (уменьшение на 1)

    Пример:

    let a = 5;
    a++; // a станет равным 6
    a--; // a станет равным 5
  4. Операторы сравнения:

    • ==: Равенство (с преобразованием типов, например, "5" == 5 вернет true)
    • ===: Строгое равенство (без преобразования типов)
    • !=: Неравенство (с преобразованием типов)
    • !==: Строгое неравенство
    • >: Больше
    • <: Меньше
    • >=: Больше или равно
    • <=: Меньше или равно

    Пример:

    let x = 5;
    let y = "5";
    
    let равно = x == y; // true (с преобразованием типов)
    let строгое_равно = x === y; // false (без преобразования типов)
  5. Логические операторы:

    • &&: Логическое “и” (возвращает true, если оба операнда true)
    • ||: Логическое “или” (возвращает true, если хотя бы один операнд true)
    • !: Логическое “не” (инвертирует значение)

    Пример:

    let условие1 = true;
    let условие2 = false;
    
    let результат1 = условие1 && условие2; // false
    let результат2 = условие1 || условие2; // true
    let результат3 = !условие1; // false
  6. Тернарный оператор:

    • условие ? значение_если_истина : значение_если_ложь

    Пример:

    let возраст = 18;
    let статус = (возраст >= 18) ? "Совершеннолетний" : "Несовершеннолетний";
  7. Операторы строк:

    • +: Конкатенация (объединение) строк
    • +=: Добавление к строке

    Пример:

    let строка1 = "Привет, "; 
    let строка2 = "мир!"; 
    let результат = строка1 + строка2; // "Привет, мир!"

Условные операторы

Условные операторы в JavaScript позволяют выполнять разные блоки кода в зависимости от условий. Они часто используются для принятия решений и управления ходом выполнения программы. Вот основные условные операторы в JavaScript:

  1. if: Оператор if позволяет выполнить блок кода, если указанное условие истинно.

    Пример:

    let возраст = 18;
    
    if (возраст >= 18) {
      console.log("Вы совершеннолетний");
    }
  2. else: Оператор else используется в паре с if и выполняет блок кода, если условие в if ложно.

    Пример:

    let возраст = 16;
    
    if (возраст >= 18) {
      console.log("Вы совершеннолетний");
    } else {
      console.log("Вы несовершеннолетний");
    }
  3. else if: Оператор else if позволяет проверить дополнительное условие, если предыдущие условия были ложными.

    Пример:

    let возраст = 16;
    
    if (возраст < 13) {
      console.log("Ребенок");
    } else if (возраст >= 13 && возраст < 20) {
      console.log("Подросток");
    } else {
      console.log("Взрослый");
    }
  4. Тернарный оператор (Conditional (Ternary) Operator): Тернарный оператор позволяет сократить условное выражение до одной строки.

    Пример:

    let возраст = 18;
    let статус = (возраст >= 18) ? "Совершеннолетний" : "Несовершеннолетний";
    console.log(статус);
  5. switch: Оператор switch позволяет сравнивать выражение со списком вариантов и выполнять блок кода, соответствующий совпадающему варианту.

    Пример:

    let день_недели = "Понедельник";
    
    switch (день_недели) {
      case "Понедельник":
      case "Вторник":
      case "Среда":
      case "Четверг":
      case "Пятница":
        console.log("Рабочий день");
        break;
      case "Суббота":
      case "Воскресенье":
        console.log("Выходной");
        break;
      default:
        console.log("Неверный день недели");
    }

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

Циклы

Циклы в JavaScript позволяют выполнять повторяющиеся операции или блоки кода. Они полезны, когда вам нужно многократно выполнить одни и те же действия. Вот основные виды циклов в JavaScript:

  1. Цикл for: Цикл for предоставляет мощный способ для выполнения повторяющихся действий. Он состоит из трех частей: инициализации, условия и обновления.

    Пример:

    for (let i = 0; i < 5; i++) {
      console.log(i); // Выводит числа от 0 до 4
    }
  2. Цикл while: Цикл while выполняет блок кода, пока указанное условие истинно.

    Пример:

    let i = 0;
    while (i < 5) {
      console.log(i); // Выводит числа от 0 до 4
      i++;
    }
  3. Цикл do...while: Цикл do...while похож на while, но сначала выполняет блок кода, а затем проверяет условие.

    Пример:

    let i = 0;
    do {
      console.log(i); // Выводит числа от 0 до 4
      i++;
    } while (i < 5);
  4. Цикл for...of: Цикл for...of используется для перебора элементов в итерируемых объектах, таких как массивы.

    Пример:

    let числа = [1, 2, 3, 4, 5];
    for (let число of числа) {
      console.log(число); // Выводит числа от 1 до 5
    }
  5. Цикл for...in: Цикл for...in используется для перебора свойств объекта.

    Пример:

    let person = { имя: "Иван", возраст: 30, работа: "разработчик" };
    for (let ключ in person) {
      console.log(ключ + ": " + person[ключ]);
    }
  6. Цикл forEach (для массивов): Метод forEach предоставляет удобный способ перебора элементов массива и выполнения функции обратного вызова для каждого элемента.

    Пример:

    let числа = [1, 2, 3, 4, 5];
    числа.forEach(function(число) {
      console.log(число);
    });

Циклы позволяют автоматизировать выполнение операций, которые должны выполняться многократно, и сделать ваш код более эффективным и компактным.

Функции

Функции являются основным строительным блоком JavaScript и позволяют организовать код в многократно используемые блоки, что делает код более читаемым и поддерживаемым. Вот как объявлять и использовать функции в JavaScript:

Объявление функции

Для объявления функции в JavaScript используется ключевое слово function, за которым следует имя функции, список параметров (если они есть), и блок кода, который определяет, что функция выполняет. Вот общий синтаксис объявления функции:

function имя_функции(параметр1, параметр2, ...) {
  // Блок кода, выполняемый функцией
  // ...
}

Вот подробное объяснение каждой части объявления функции:

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

  • имя_функции: Имя функции, которое вы придумываете. Имя функции должно быть допустимой идентификаторной строкой. Это уникальное имя, по которому вы будете вызывать функцию.

  • (параметр1, параметр2, ...): Это список параметров, которые функция принимает. Параметры - это переменные, которые используются внутри функции. Они являются входными данными, которые функция может использовать при выполнении.

  • {}: Это блок кода функции, заключенный в фигурные скобки {}. В этом блоке кода определяются действия, которые функция выполняет при вызове.

Пример объявления и вызова функции:

function приветствие(имя) {
  console.log("Привет, " + имя + "!");
}

// Вызов функции с аргументом "Иван"
приветствие("Иван"); // Выведет "Привет, Иван!"

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

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

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

имя_функции(аргумент1, аргумент2, ...);

Где: - имя_функции - это имя функции, которую вы хотите вызвать. - аргумент1, аргумент2, ... - это значения, которые передаются функции как аргументы (если функция ожидает аргументы).

Примеры вызова функции:

function приветствие(имя) {
  console.log("Привет, " + имя + "!");
}

приветствие("Иван"); // Вызов функции с аргументом "Иван"
приветствие("Мария"); // Вызов функции с аргументом "Мария"

В этом примере функция приветствие вызывается дважды с разными аргументами, и она выводит приветственное сообщение с именем, переданным как аргумент.

Обратите внимание, что если функция не ожидает аргументов, вы все равно должны использовать пустые круглые скобки:

function поздравление() {
  console.log("Поздравляем!");
}

поздравление(); // Вызов функции без аргументов

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

Возврат значения

Возврат значения из функции в JavaScript выполняется с помощью оператора return. Этот оператор позволяет функции вернуть какое-либо значение обратно в вызывающую часть программы. Вот как он используется:

function имя_функции(параметр1, параметр2, ...) {
  // Блок кода, выполняемый функцией
  // ...
  return значение;
}

Где: - имя_функции - имя функции. - параметр1, параметр2, ... - параметры функции (если они есть). - значение - значение, которое функция возвращает.

Пример функции с оператором return:

function добавить(a, b) {
  return a + b;
}

let результат = добавить(3, 5); // результат равен 8

В этом примере функция добавить принимает два аргумента a и b, выполняет операцию сложения и возвращает результат с использованием оператора return.

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

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

function удвоить(число) {
  return число * 2;
}

let результат1 = удвоить(4); // результат1 равен 8

let результат2 = удвоить(10); // результат2 равен 20

console.log(результат1, результат2);

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

Анонимные функции

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

Вот как объявляются анонимные функции:

let имя_переменной = function(параметр1, параметр2, ...) {
  // Тело функции
  // ...
};

Где: - имя_переменной - это имя переменной, в которую сохраняется анонимная функция. Эта переменная становится ссылкой на функцию. - параметр1, параметр2, ... - это параметры функции (если они есть). - // Тело функции - это блок кода, который определяет операции, выполняемые функцией.

Пример анонимной функции, сохраненной в переменной:

let умножить = function(a, b) {
  return a * b;
};

let результат = умножить(4, 6); // результат равен 24

Анонимные функции также могут быть использованы как аргументы в других функциях. Это особенно полезно при работе с функциональным программированием и функциями высшего порядка.

Пример использования анонимной функции как аргумента:

let числа = [1, 2, 3, 4, 5];

// Используем метод массива forEach с анонимной функцией
числа.forEach(function(число) {
  console.log(число);
});

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

Стрелочные функции

Стрелочные функции (Arrow Functions) - это синтаксическое усовершенствование, введенное в ECMAScript 6 (ES6), которое предоставляет более краткий способ определения функций в JavaScript. Они особенно полезны для создания анонимных функций и обеспечивают короткий и читаемый синтаксис. Вот как объявляются и используются стрелочные функции:

Синтаксис стрелочной функции:

(параметры) => выражение

Где: - параметры - это список параметров функции, заключенных в круглые скобки, как в обычных функциях. - выражение - это выражение, которое возвращает значение функции. Если тело функции содержит только одно выражение, то {} можно опустить, и значение будет автоматически возвращено.

Примеры стрелочных функций:

// Стрелочная функция без параметров
let привет = () => {
  console.log("Привет, мир!");
};

// Стрелочная функция с одним параметром
let удвоить = x => x * 2;

// Стрелочная функция с несколькими параметрами
let сложить = (a, b) => a + b;

// Стрелочная функция с одним выражением (без явного return)
let квадрат = x => x * x;

// Использование стрелочной функции внутри метода массива
let числа = [1, 2, 3, 4, 5];
числа.forEach(число => console.log(число));

Основные особенности стрелочных функций:

  1. Если функция принимает только один параметр, вы можете опустить круглые скобки вокруг параметра, как в примере удвоить.

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

  3. Стрелочные функции сохраняют значение this из окружающего контекста, что может быть полезным при работе с колбэками и обработчиками событий.

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

Область видимости функций

Область видимости функций (или контекст выполнения) в JavaScript определяет, где и какие переменные могут быть использованы в вашем коде. JavaScript имеет два основных типа области видимости:

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

    Пример:

    let глобальная_переменная = 10;
    
    function функция1() {
      console.log(глобальная_переменная); // Можно использовать глобальную переменную
    }
  2. Локальная область видимости (Local Scope): Переменные, объявленные внутри функций или блоков кода, находятся в их локальной области видимости. Это означает, что такие переменные могут быть использованы только в пределах той функции или блока, в которых они были объявлены. Они недоступны за пределами этой функции или блока.

    Пример:

    function функция2() {
      let локальная_переменная = 20;
      console.log(локальная_переменная); // Можно использовать локальную переменную
    }

Лексическая область видимости

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

Пример лексической области видимости:

let глобальная_переменная = "Глобальная";

function внешняя_функция() {
  let локальная_переменная = "Локальная";

  function внутренняя_функция() {
    console.log(глобальная_переменная); // Доступ к глобальной переменной
    console.log(локальная_переменная); // Доступ к локальной переменной
  }

  внутренняя_функция();
}

внешняя_функция();

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

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

Следует отметить, что JavaScript использует лексическую область видимости, и это означает, что переменные, объявленные внутри блока кода (например, условные операторы или циклы), видны только в этом блоке и его подблоках. Это называется блочной областью видимости и было введено в стандарте ECMAScript 6 (ES6) с использованием ключевого слова let.

Замыкания

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

Вот пример, как создаются и используются замыкания:

function создатьСчетчик() {
  let счетчик = 0;

  function увеличить() {
    счетчик++;
    console.log(счетчик);
  }

  return увеличить;
}

let мойСчетчик = создатьСчетчик();
мойСчетчик(); // Выводит 1
мойСчетчик(); // Выводит 2

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

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

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

Рекурсия

Рекурсия - это концепция в программировании, когда функция вызывает саму себя для решения задачи. Рекурсия является мощным инструментом и часто используется для решения задач, которые могут быть разбиты на более мелкие подзадачи. В JavaScript, как и в других языках, рекурсия реализуется следующим образом:

  1. Определите базовый случай (base case): Это случай, в котором рекурсивная функция завершает свою работу и возвращает результат, без вызова самой себя. Без базового случая рекурсия может стать бесконечной.

  2. Определите рекурсивный случай (recursive case): Это случай, в котором рекурсивная функция вызывает саму себя с другими аргументами для решения подзадачи.

Пример рекурсивной функции для вычисления факториала числа:

function факториал(n) {
  // Базовый случай: если n равно 0, возвращаем 1
  if (n === 0) {
    return 1;
  }
  // Рекурсивный случай: вызываем факториал с меньшим значением n
  else {
    return n * факториал(n - 1);
  }
}

let результат = факториал(5); // результат равен 120

В этом примере базовый случай - это когда n равно 0, и функция возвращает 1. В рекурсивном случае, функция вызывает саму себя с аргументом n - 1, чтобы постепенно уменьшать значение n до достижения базового случая.

Рекурсия может быть мощным способом решения задач, но её следует использовать осторожно. Неправильно написанная рекурсия может вызвать переполнение стека вызовов (stack overflow), и, поэтому, важно иметь хороший базовый случай и убедиться, что рекурсивные вызовы сходятся к базовому случаю.

Массивы

Массивы (Arrays) в JavaScript представляют собой структуры данных, предназначенные для хранения и управления списками значений. Они позволяют хранить несколько значений в одной переменной. Вот как создавать и работать с массивами:

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

Для создания массива в JavaScript используются квадратные скобки []. В массиве можно хранить различные типы данных, включая числа, строки, объекты и другие массивы. Вот несколько способов создания массива:

  1. Пустой массив:

    Вы можете создать пустой массив, который будет содержать ноль элементов, следующим образом:

    let пустойМассив = [];
  2. Массив с элементами:

    Чтобы создать массив с элементами, разделите элементы запятыми внутри квадратных скобок:

    let числа = [1, 2, 3, 4, 5];
    let фрукты = ["яблоко", "банан", "апельсин"];
    let разнотипные = [42, "строка", true, null, { имя: "Иван" }];
  3. Создание массива с помощью конструктора:

    JavaScript также предоставляет конструктор Array для создания массивов. Вы можете создать массив с помощью new Array() и передать в него начальные элементы:

    let числа = new Array(1, 2, 3, 4, 5);
    let фрукты = new Array("яблоко", "банан", "апельсин");

    Однако использование квадратных скобок более распространено и читаемо.

  4. Пустой массив заданной длины:

    Можно создать пустой массив заданной длины, используя конструктор Array и указав количество элементов:

    let пустойМассив = new Array(3); // Создаст массив с 3 пустыми слотами

    В этом случае массив будет иметь длину 3, но его элементы будут undefined. Это может быть полезно, если вы планируете заполнять массив позже.

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

Для доступа к элементам массива в JavaScript используются индексы. Индексы начинаются с 0 для первого элемента. Вот как можно получить доступ к элементам массива:

  1. Используя квадратные скобки и индекс:

    Вы можете получить элемент массива, указав его индекс в квадратных скобках. Например:

    let числа = [1, 2, 3, 4, 5];
    
    console.log(числа[0]); // Выведет первый элемент (1)
    console.log(числа[2]); // Выведет третий элемент (3)
  2. Используя переменную или выражение в качестве индекса:

    Индекс может быть переменной или выражением. Например:

    let числа = [1, 2, 3, 4, 5];
    let индекс = 2;
    
    console.log(числа[индекс]); // Выведет третий элемент (3)
    
    let x = 1;
    console.log(числа[x]); // Выведет второй элемент (2)
  3. Используя отрицательные индексы:

    Массивы в JavaScript поддерживают отрицательные индексы, которые начинаются с конца массива. Например:

    let числа = [1, 2, 3, 4, 5];
    
    console.log(числа[-1]); // Выведет последний элемент (5)
    console.log(числа[-3]); // Выведет третий элемент с конца (3)

    Однако отрицательные индексы не поддерживаются во всех языках программирования, и их использование может быть путающим.

  4. Используя методы массива:

    Методы массива, такие как indexOf, find, filter и другие, позволяют искать элементы по их значению или выполнить различные операции над элементами.

Примечание: Если индекс, который вы указали, находится вне диапазона допустимых индексов массива, то будет возвращено undefined. Будьте осторожны и проверяйте, что индекс находится в пределах длины массива, чтобы избежать ошибок.

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

Изменение элементов

Чтобы изменить элементы в массиве JavaScript, вы можете обратиться к элементу по его индексу и присвоить новое значение. Вот как это делается:

let числа = [1, 2, 3, 4, 5];

// Изменить первый элемент (индекс 0)
числа[0] = 10; // Теперь массив будет [10, 2, 3, 4, 5]

// Изменить третий элемент (индекс 2)
числа[2] = 30; // Теперь массив будет [10, 2, 30, 4, 5]

Вы можете присваивать новые значения элементам массива, используя индексы. Обратите внимание, что индексы начинаются с 0 для первого элемента, как в большинстве языков программирования.

Вы также можете изменять элементы массива, используя переменные или выражения:

let числа = [1, 2, 3, 4, 5];
let индекс = 2;

// Изменить элемент с использованием переменной для индекса
числа[индекс] = 30; // Теперь массив будет [1, 2, 30, 4, 5]

// Изменить элемент с использованием арифметического выражения для индекса
числа[индекс + 1] = 40; // Теперь массив будет [1, 2, 30, 40, 5]

Изменение элементов массива полезно при обновлении данных или при выполнении различных операций над элементами массива.

Добавление и удаление элементов

Для добавления и удаления элементов из массива в JavaScript существуют различные методы и операции. Вот некоторые из них:

Добавление элементов:

  1. Метод push:

    Метод push добавляет один или несколько элементов в конец массива и возвращает новую длину массива:

    let числа = [1, 2, 3];
    числа.push(4); // Добавит 4 в конец массива
    числа.push(5, 6); // Добавит 5 и 6 в конец массива
  2. Метод unshift:

    Метод unshift добавляет один или несколько элементов в начало массива и возвращает новую длину массива:

    let числа = [3, 4, 5];
    числа.unshift(2); // Добавит 2 в начало массива
    числа.unshift(1, 0); // Добавит 1 и 0 в начало массива
  3. Индекс вне диапазона:

    Просто присвойте значение по индексу, который находится за пределами текущей длины массива, чтобы добавить элемент:

    let числа = [1, 2, 3];
    числа[5] = 6; // Добавит 6 в массив и установит длину в 6

Удаление элементов:

  1. Метод pop:

    Метод pop удаляет последний элемент из массива и возвращает его значение:

    let числа = [1, 2, 3, 4, 5];
    let удаленный = числа.pop(); // Удалит 5 и вернет его значение
  2. Метод shift:

    Метод shift удаляет первый элемент из массива и возвращает его значение:

    let числа = [1, 2, 3, 4, 5];
    let удаленный = числа.shift(); // Удалит 1 и вернет его значение
  3. Метод splice:

    Метод splice позволяет удалять элементы из массива по индексу и добавлять новые элементы:

    let числа = [1, 2, 3, 4, 5];
    числа.splice(2, 1); // Удалит элемент с индексом 2 (3)
    числа.splice(1, 2, 6, 7); // Удалит элементы с индексами 1 и 2 (2, 4) и добавит 6 и 7
  4. Оператор delete:

    Оператор delete удаляет элемент по индексу и оставляет ячейку в массиве, но со значением undefined:

    let числа = [1, 2, 3, 4, 5];
    delete числа[2]; // Удалит элемент с индексом 2 (3), но оставит ячейку со значением undefined

Обратите внимание, что методы pop, shift, и splice изменяют исходный массив, а методы push и unshift возвращают новую длину массива после добавления элементов. Выберите метод, который соответствует вашим потребностям при работе с массивами.

Длина массива

В JavaScript, для получения длины массива (количества элементов) вы можете использовать свойство length. Вот как это делается:

let числа = [1, 2, 3, 4, 5];
let длина = числа.length; // Получить длину массива

console.log(длина); // Выведет 5, так как массив содержит 5 элементов

Свойство length возвращает целое число, равное количеству элементов в массиве. Обратите внимание, что оно указывает на индекс следующего пустого элемента, если в массиве есть пустые ячейки. Например:

let числа = [1, 2, 3];
числа[5] = 6;

console.log(числа.length); // Выведет 6, так как следующий пустой индекс после 3 равен 5

Благодаря свойству length, вы можете легко определить, сколько элементов содержит ваш массив и использовать это значение в циклах или для других операций над массивом.

Перебор массива

Перебор массива (итерация) является часто используемой операцией при работе с массивами в JavaScript. Вы можете перебирать элементы массива и выполнять различные операции с ними. Вот несколько способов для перебора элементов массива:

Цикл for:

let числа = [1, 2, 3, 4, 5];

for (let i = 0; i < числа.length; i++) {
  console.log(числа[i]);
}

Цикл for...of:

let числа = [1, 2, 3, 4, 5];

for (let число of числа) {
  console.log(число);
}

Метод forEach:

let числа = [1, 2, 3, 4, 5];

числа.forEach(function(число) {
  console.log(число);
});

Метод map:

let числа = [1, 2, 3, 4, 5];

let новыйМассив = числа.map(function(число) {
  return число * 2;
});

console.log(новыйМассив);

Метод filter:

let числа = [1, 2, 3, 4, 5];

let фильтрованныйМассив = числа.filter(function(число) {
  return число % 2 === 0;
});

console.log(фильтрованныйМассив);

Метод reduce:

let числа = [1, 2, 3, 4, 5];

let сумма = числа.reduce(function(аккумулятор, число) {
  return аккумулятор + число;
}, 0);

console.log(сумма);

Метод for...in (не рекомендуется для массивов):

let числа = [1, 2, 3, 4, 5];

for (let индекс in числа) {
  console.log(числа[индекс]);
}

В большинстве случаев, использование методов forEach, map, filter, и reduce является более удобным и читаемым способом для перебора массивов, особенно если вам нужно выполнить какие-то операции над элементами. Выберите наиболее подходящий метод в зависимости от вашей задачи и стиля кодирования.

Строки

В JavaScript строки (Strings) представляют собой последовательности символов, которые используются для представления текстовой информации. Строки могут содержать буквы, цифры, специальные символы и пробелы. Вот как работать со строками в JavaScript:

Создание строки

  1. Использование двойных кавычек:

    let строка = "Это строка, созданная с использованием двойных кавычек.";
  2. Использование одинарных кавычек:

    let строка = 'Это строка, созданная с использованием одинарных кавычек.';
  3. Использование обратных кавычек (шаблонные строки) для создания строк с интерполяцией:

    let имя = "Иван";
    let возраст = 30;
    let строка = `Меня зовут ${имя} и мне ${возраст} лет.`;

Длина строки

Для определения длины строки используйте свойство length:

let строка = "Это пример строки";
let длина = строка.length; // Получить длину строки

Доступ к символам

Символы в строке можно получить по их индексу, начиная с 0:

let строка = "Hello";
let первыйСимвол = строка[0]; // Получить первый символ "H"
let второйСимвол = строка[1]; // Получить второй символ "e"

Конкатенация строк

Строки можно объединять (конкатенировать) с использованием оператора +:

let строка1 = "Hello";
let строка2 = " World";
let результат = строка1 + строка2; // Результат: "Hello World"

Методы строк

JavaScript также предоставляет ряд методов для работы с строками, таких как:

  • charAt(index): Возвращает символ по указанному индексу.

  • substring(startIndex, endIndex): Возвращает подстроку, начиная с startIndex и заканчивая endIndex, не включая последний символ.

  • slice(startIndex, endIndex): Аналогичен substring, но может принимать отрицательные индексы, считая с конца строки.

  • toUpperCase(): Преобразует строку в верхний регистр.

  • toLowerCase(): Преобразует строку в нижний регистр.

  • trim(): Удаляет пробелы и пробельные символы с начала и конца строки.

  • split(delimiter): Разделяет строку на массив подстрок с помощью указанного разделителя.

  • indexOf(substring): Возвращает индекс первого вхождения подстроки в строку.

  • lastIndexOf(substring): Возвращает индекс последнего вхождения подстроки в строку.

  • replace(search, replace): Заменяет первое вхождение search на replace.

  • replace(/регулярное_выражение/g, replace): Заменяет все вхождения, соответствующие регулярному выражению.

  • startsWith(prefix): Проверяет, начинается ли строка с указанного префикса.

  • endsWith(suffix): Проверяет, заканчивается ли строка указанным суффиксом.

  • includes(substring): Проверяет, содержит ли строка указанную подстроку.

Примеры использования этих методов:

const текст = "Это пример строки";
console.log(текст.charAt(4)); // "п"
console.log(текст.substring(5, 12)); // "пример с"
console.log(текст.toUpperCase()); // "ЭТО ПРИМЕР СТРОКИ"
console.log(текст.indexOf("строка")); // 13
console.log(текст.startsWith("Это")); // true
console.log(текст.endsWith("строка")); // true

Сравнение строк

Строки можно сравнивать с использованием операторов сравнения, таких как ==, ===, <, >, <=, >=. Сравнение происходит на основе лексикографического (алфавитного) порядка.

let строка1 = "apple";
let строка2 = "banana";
let результат = строка1 < строка2; // Результат: true (потому что "apple" идет раньше чем "banana" в алфавитном порядке)

Строки играют важную роль в JavaScript и используются для работы с текстом, обработки входных данных и многих других задач.

Исключения и обработка ошибок

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

Вот как работать с исключениями и обработкой ошибок в JavaScript:

Выброс исключений (генерация ошибок)

  1. Использование оператора throw:

    Вы можете явно выбросить исключение с помощью оператора throw. Это может быть объект ошибки или строка:

    throw new Error("Это ошибка!");

    Или:

    throw "Это ошибка!";
  2. Использование объекта ошибки:

    Часто рекомендуется использовать объект Error или его подклассы, чтобы явно представить ошибку:

    throw new Error("Это ошибка!");

Обработка ошибок

  1. Инструкция try...catch:

    Инструкция try...catch используется для отлова и обработки ошибок. Код, который может вызвать ошибку, помещается в блок try, а обработчик ошибки в блок catch. Если ошибка происходит в блоке try, выполнение кода переходит в блок catch, где вы можете обработать ошибку:

    try {
      // Код, который может вызвать ошибку
    } catch (error) {
      // Обработка ошибки
      console.error(error.message);
    }
  2. Инструкция try...catch...finally:

    Вы также можете использовать блок finally после блока catch, который выполняется независимо от того, была ошибка или нет:

    try {
      // Код, который может вызвать ошибку
    } catch (error) {
      // Обработка ошибки
      console.error(error.message);
    } finally {
      // Выполнится всегда
    }
  3. Глобальный объект window.onerror:

    Вы также можете установить обработчик глобальных ошибок с помощью объекта window.onerror, который будет вызываться для всех неотловленных ошибок в вашем приложении.

    window.onerror = function(message, source, lineno, colno, error) {
      // Обработка глобальных ошибок
      console.error("Ошибка: " + message);
    };

Обработка ошибок важна для обеспечения более надежной работы вашего JavaScript-кода. Это позволяет избежать краха приложения из-за неожиданных ошибок и обеспечить более информативное сообщение об ошибке для разработчиков и пользователей.

DOM

Описание

DOM, или Document Object Model (Объектная Модель Документа), представляет собой структуру, которая представляет веб-страницу в виде древовидной иерархии объектов. Каждый элемент веб-страницы, такой как HTML-теги, атрибуты и текстовые узлы, представлен в DOM как объект. DOM позволяет программно взаимодействовать с веб-страницей, изменять ее содержимое и структуру, а также реагировать на события, такие как клики мышью и нажатия клавиш.

Вот некоторые ключевые концепции и возможности DOM:

Иерархия элементов

DOM представляет веб-страницу как древовидную иерархию элементов. Корнем этой иерархии является объект document, который представляет весь HTML-документ. Элементы страницы, такие как div, p, a, span, и другие, являются узлами этой иерархии.

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

Вы можете получать доступ к элементам в DOM с помощью JavaScript, используя методы, свойства и селекторы. Например:

  • document.getElementById("идентификатор"): Получить элемент по его идентификатору.
  • document.querySelector("селектор"): Получить первый элемент, соответствующий селектору CSS.
  • document.getElementsByClassName("класс"): Получить все элементы с указанным классом.
  • document.getElementsByTagName("тег"): Получить все элементы с указанным тегом.
  • element.querySelector("селектор"): Получить первый подэлемент указанного элемента.

Изменение содержимого и структуры

С помощью DOM вы можете добавлять, изменять и удалять элементы и их содержимое. Например:

  • document.createElement("тег"): Создать новый элемент.
  • element.appendChild(дочернийЭлемент): Добавить дочерний элемент в указанный элемент.
  • element.innerHTML = "новый текст": Установить HTML-содержимое элемента.
  • element.setAttribute("атрибут", "значение"): Установить значение атрибута элемента.

Обработка событий

DOM позволяет регистрировать обработчики событий для элементов. Вы можете реагировать на события, такие как клики, наведение курсора, нажатие клавиш и другие. Например:

  • element.addEventListener("click", функция): Регистрация обработчика события.

Навигация по DOM

DOM предоставляет методы для навигации по дереву элементов, такие как parentElement, childNodes, nextSibling, previousSibling и многие другие.

Изменение стилей

Вы можете изменять стили элементов, используя свойство style объекта элемента. Например:

element.style.color = "red";
element.style.backgroundColor = "yellow";

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

Обработка событий

Описание

Обработка событий в JavaScript позволяет реагировать на действия пользователя, такие как клики мышью, нажатия клавиш, перемещения курсора и другие события веб-страницы. События являются важной частью веб-разработки и позволяют делать интерактивные веб-приложения. Вот как обрабатывать события в JavaScript:

Добавление обработчиков событий

Для добавления обработчика события к элементу HTML вы можете использовать метод addEventListener. Этот метод принимает два аргумента: тип события и функцию-обработчик. Пример:

let кнопка = document.getElementById("myButton"); // Получение элемента кнопки
кнопка.addEventListener("click", function() {
  // Ваш код обработчика события
  alert("Кнопка была нажата!");
});

Удаление обработчиков событий

Чтобы удалить обработчик события, вы можете использовать метод removeEventListener. Этот метод также принимает тип события и функцию-обработчик. Однако для удаления обработчика необходимо передать ту же функцию-обработчик, которая была использована при добавлении.

кнопка.removeEventListener("click", вашОбработчик);

Объект события

Когда событие происходит, браузер создает объект события, который содержит информацию о событии. Обработчики событий могут получить доступ к этому объекту. Например, для получения координат клика мыши на странице:

кнопка.addEventListener("click", function(event) {
  console.log("X: " + event.clientX + " Y: " + event.clientY);
});

Всплытие и перехват событий

События в JavaScript могут всплывать (подниматься) от вложенных элементов к корню документа. Это может повлиять на порядок обработки событий. Вы можете использовать метод stopPropagation объекта события, чтобы предотвратить всплытие.

Использование атрибутов HTML

Вы также можете добавить обработчики событий напрямую в атрибутах HTML-элементов, таких как onclick, onmouseover, и так далее:

<button id="myButton" onclick="мояФункция()">Нажми меня</button>

Общие типы событий

Существует множество типов событий, таких как click, mousedown, mouseup, keydown, keyup, mouseover, mouseout и другие. Выбор правильного типа события зависит от того, какое действие вы хотите обработать.

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

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

let список = document.getElementById("список");
список.addEventListener("click", function(event) {
  if (event.target.tagName === "LI") {
    // Обработка клика по элементу списка
    console.log("Вы нажали на элемент: " + event.target.textContent);
  }
});

Обработка событий играет важную роль в разработке веб-приложений, и умение правильно использовать обработчики событий является неотъемлемой частью навыков веб-разработчика.

Асинхронное выполнение

Описание

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

Колбеки (Callback Functions)

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

function загрузитьДанные(успешно, неуспешно) {
  if (успешно) {
    // Обработка успешного запроса
    успешно(данные);
  } else {
    // Обработка ошибки
    неуспешно(ошибка);
  }
}

загрузитьДанные(
  function(данные) {
    console.log("Данные загружены успешно:", данные);
  },
  function(ошибка) {
    console.error("Произошла ошибка:", ошибка);
  }
);

Промисы (Promises)

Промисы - это современный способ управления асинхронным кодом. Промисы представляют собой объекты, которые предоставляют более читаемый и управляемый способ обработки асинхронных операций.

function загрузитьДанные() {
  return new Promise(function(resolve, reject) {
    if (успешно) {
      // Обработка успешного запроса
      resolve(данные);
    } else {
      // Обработка ошибки
      reject(ошибка);
    }
  });
}

загрузитьДанные()
  .then(function(данные) {
    console.log("Данные загружены успешно:", данные);
  })
  .catch(function(ошибка) {
    console.error("Произошла ошибка:", ошибка);
  });

Асинхронные функции (Async/Await)

Асинхронные функции - это синтаксический сахар, предоставленный ECMAScript 2017 (ES8), который упрощает работу с промисами. Они позволяют писать асинхронный код так, как будто он синхронный.

async function загрузитьДанные() {
  try {
    let данные = await fetch("url");
    console.log("Данные загружены успешно:", данные);
  } catch (ошибка) {
    console.error("Произошла ошибка:", ошибка);
  }
}

загрузитьДанные();

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

Объектно-ориентированность в JavaScript

Описание

JavaScript - это язык программирования, который поддерживает объектно-ориентированное программирование (ООП). В объектно-ориентированном программировании основной упор делается на объекты, которые являются экземплярами классов и имеют свойства и методы.

Объекты

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

Объекты - это одна из основных концепций в JavaScript. Они представляют собой составные структуры данных, которые могут содержать переменные (свойства) и функции (методы) для организации и работы с данными. Вот основные аспекты объектов в JavaScript:

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

  1. Литеральная нотация объекта: Самый простой способ создать объект - использовать литералы объекта, заключая свойства и их значения в фигурные скобки.

    let пользователь = {
      имя: "Иван",
      возраст: 30
    };
  2. Создание объекта с помощью конструктора: Можно создать объект с использованием конструктора Object().

    let пользователь = new Object();
    пользователь.имя = "Иван";
    пользователь.возраст = 30;

Свойства объектов

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

console.log(пользователь.имя); // "Иван"
console.log(пользователь["возраст"]); // 30

Методы объектов

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

let пользователь = {
  имя: "Иван",
  приветствие: function() {
    console.log("Привет, меня зовут " + this.имя);
  }
};

пользователь.приветствие(); // "Привет, меня зовут Иван"

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

Вы можете удалить свойство из объекта, используя оператор delete.

delete пользователь.возраст;

Перебор свойств

Свойства объектов можно перебирать с помощью цикла for...in или методов Object.keys(), Object.values() и Object.entries().

for (let свойство in пользователь) {
  console.log(свойство + ": " + пользователь[свойство]);
}

Вложенные объекты

Объекты могут содержать другие объекты в качестве свойств. Это позволяет создавать структуры данных с различными уровнями вложенности.

let компьютер = {
  марка: "Dell",
  экран: {
    размер: 15,
    разрешение: "1920x1080"
  }
};

Объекты как ссылочные типы

Объекты в JavaScript являются ссылочными типами данных, что означает, что когда вы присваиваете объект другой переменной или передаете его в функцию, вы передаете ссылку на объект, а не сам объект. Изменения объекта будут видны через все ссылки на него.

let объект1 = { имя: "Иван" };
let объект2 = объект1;
объект2.имя = "Мария";
console.log(объект1.имя); // "Мария"

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

Конструкторы

Конструкторы в JavaScript - это функции, которые используются для создания объектов определенного типа или класса. Они предоставляют шаблон для создания новых экземпляров объектов с определенными свойствами и методами. Конструкторы особенно полезны при реализации объектно-ориентированного программирования. Вот как создавать и использовать конструкторы:

Создание конструкторов

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

function Человек(имя, возраст) {
  this.имя = имя;
  this.возраст = возраст;
}

Создание объектов с использованием конструктора

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

let человек1 = new Человек("Иван", 30);
let человек2 = new Человек("Мария", 25);

Добавление методов в прототип:

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

Человек.prototype.приветствие = function() {
  console.log("Привет, меня зовут " + this.имя + " и мне " + this.возраст + " лет.");
};

человек1.приветствие(); // "Привет, меня зовут Иван и мне 30 лет."
человек2.приветствие(); // "Привет, меня зовут Мария и мне 25 лет."

Наследование:

Вы также можете создавать подклассы, наследующие свойства и методы от других конструкторов. Например, можно создать конструктор Студент, который наследует от Человек.

function Студент(имя, возраст, номерСтудента) {
  Человек.call(this, имя, возраст);
  this.номерСтудента = номерСтудента;
}

Использование Object.create:

Вы можете использовать Object.create для создания объектов, наследующих свойства и методы от другого объекта или прототипа.

let родитель = { свойство: "Значение" };
let наследник = Object.create(родитель);

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

Ключевое слово this

this в JavaScript - это ключевое слово, которое используется для ссылки на текущий контекст выполнения. Оно может принимать разные значения в зависимости от того, где и как используется. Вот более подробная информация о this:

  1. this в методах объектов: Когда метод вызывается на объекте, this ссылается на этот объект. Например:

    let пользователь = {
      имя: "Иван",
      приветствие: function() {
        console.log("Привет, меня зовут " + this.имя);
      }
    };
    пользователь.приветствие(); // "Привет, меня зовут Иван"
  2. this в глобальном контексте: В глобальном контексте, вне объектов и функций, this ссылается на глобальный объект. В браузере это обычно window, в среде Node.js - global.

    console.log(this === window); // true (в браузере)
  3. this в обычных функциях: Поведение this в обычных функциях зависит от способа вызова функции. В строгом режиме ("use strict") this в функциях без явно указанного контекста (например, как метод объекта) будет undefined. В противном случае, this будет ссылаться на глобальный объект.

    function говориПривет() {
      console.log("Привет, меня зовут " + this.имя);
    }
    
    let объект1 = { имя: "Иван", говориПривет: говориПривет };
    let объект2 = { имя: "Мария" };
    
    объект1.говориПривет(); // "Привет, меня зовут Иван"
    говориПривет.call(объект2); // "Привет, меня зовут Мария"
  4. this в стрелочных функциях: В стрелочных функциях this принимает значение из окружающего контекста. Он не имеет собственного контекста. Это отличает стрелочные функции от обычных.

    let объект = {
      имя: "Иван",
      говориПривет: () => {
        console.log("Привет, меня зовут " + this.имя);
      }
    };
    объект.говориПривет(); // "Привет, меня зовут undefined" (this ссылается на глобальный объект)
  5. this в конструкторах классов: Конструкторы классов используют this для инициализации свойств экземпляров класса. this ссылается на экземпляр класса, который создается при вызове конструктора.

    class Человек {
      constructor(имя) {
        this.имя = имя;
      }
    
      приветствие() {
        console.log("Привет, меня зовут " + this.имя);
      }
    }
    
    const человек = new Человек("Мария");
    человек.приветствие(); // "Привет, меня зовут Мария"

Прототипы

Прототипы - это ключевая часть системы наследования в JavaScript и позволяют объектам наследовать свойства и методы от других объектов. В JavaScript каждый объект имеет ссылку на свой прототип, и если свойство или метод не найден в объекте, JavaScript будет искать его в прототипе объекта. Прототипы обеспечивают механизм наследования и делают код более эффективным и модульным. Вот ключевые аспекты использования прототипов:

Прототипы объектов

Каждый объект в JavaScript имеет прототип. Прототип - это ссылка на другой объект, который содержит свойства и методы, которые могут быть унаследованы объектом. Прототип объекта можно получить, обратившись к свойству prototype конструктора этого объекта.

let объект = {};
console.log(объект.__proto__); // Прототип объекта

Наследование

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

let родитель = { имя: "Иван" };
let дочь = { возраст: 5 };
дочь.__proto__ = родитель;

console.log(дочь.имя); // "Иван"

Собственные свойства и прототипные свойства

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

let объект = { имя: "Иван" };
console.log(объект.hasOwnProperty("имя")); // true (собственное свойство)
console.log(объект.hasOwnProperty("возраст")); // false (прототипное свойство)

Изменение прототипа

Прототип объекта можно изменить, чтобы он указывал на другой объект. Это можно сделать с помощью свойства __proto__ или с использованием метода Object.create().

let родитель = { имя: "Иван" };
let дочь = { возраст: 5 };
дочь.__proto__ = родитель;

// Изменение прототипа с использованием Object.create()
let новыйПрототип = { имя: "Мария" };
Object.setPrototypeOf(дочь, новыйПрототип);

console.log(дочь.имя); // "Мария"

Прототипы конструкторов

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

function Человек(имя) {
  this.имя = имя;
}

Человек.prototype.приветствие = function() {
  console.log("Привет, меня зовут " + this.имя);
};

let человек = new Человек("Иван");
человек.приветствие(); // "Привет, меня зовут Иван"

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

Инкапсуляция

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

Приватные переменные и методы

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

function Счетчик() {
  let счет = 0;

  this.увеличитьСчет = function() {
    счет++;
  };

  this.получитьСчет = function() {
    return счет;
  };
}

let счетчик = new Счетчик();
счетчик.увеличитьСчет();
console.log(счетчик.получитьСчет()); // Выведет "1"

Защита данных

Инкапсуляция позволяет создавать интерфейсы для работы с данными объекта, и таким образом, скрывать детали реализации. Вы можете определить методы, которые предоставляют доступ к данным объекта, а также контролировать их изменение.

function БанковскийСчет(начальныйБаланс) {
  let баланс = начальныйБаланс;

  this.получитьБаланс = function() {
    return баланс;
  };

  this.снять = function(сумма) {
    if (сумма <= баланс) {
      баланс -= сумма;
      return true;
    } else {
      return false;
    }
  };

  this.пополнить = function(сумма) {
    баланс += сумма;
  };
}

Публичный интерфейс

Инкапсуляция также позволяет определять публичный интерфейс объекта, который определяет, какие методы и свойства доступны извне объекта. Это помогает скрыть детали реализации и упростить работу с объектом.

let счет = new БанковскийСчет(1000);

console.log(счет.получитьБаланс()); // Выведет "1000"
счет.пополнить(500);
console.log(счет.получитьБаланс()); // Выведет "1500"

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

Полиморфизм

JavaScript поддерживает полиморфизм, что означает, что объекты могут иметь методы с одинаковыми именами, но различной реализацией.

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

  1. Полиморфизм посредством перегрузки методов (ад-хок полиморфизм): В JavaScript методы могут принимать разное количество аргументов и выполнять разные действия в зависимости от количества и типов аргументов.

    function сложить(x, y) {
      if (arguments.length === 2) {
        return x + y;
      } else if (arguments.length === 3) {
        return x + y + arguments[2];
      }
    }
  2. Полиморфизм посредством наследования (подтиповый полиморфизм): При использовании наследования и интерфейсов вы можете создавать подклассы с различными реализациями методов, но с общим интерфейсом. Это позволяет работать с объектами разных классов, как с объектами родительского класса.

    class Фигура {
      вычислитьПлощадь() {
        // Общая реализация метода
      }
    }
    
    class Круг extends Фигура {
      вычислитьПлощадь() {
        // Реализация для круга
      }
    }
    
    class Квадрат extends Фигура {
      вычислитьПлощадь() {
        // Реализация для квадрата
      }
    }
  3. Полиморфизм посредством интерфейсов и динамической диспетчеризации (полиморфизм времени выполнения): JavaScript поддерживает динамическую диспетчеризацию, что означает, что вызов метода будет определен во время выполнения, а не во время компиляции. Это позволяет объектам разных типов вызывать один и тот же метод с общим интерфейсом.

    class Животное {
      голос() {
        console.log("Животное издает звук");
      }
    }
    
    class Собака extends Животное {
      голос() {
        console.log("Собака лает");
      }
    }
    
    class Кошка extends Животное {
      голос() {
        console.log("Кошка мяукает");
      }
    }
    
    function сказатьЧто(g) {
      g.голос();
    }
    
    const животное = new Животное();
    const собака = new Собака();
    const кошка = new Кошка();
    
    сказатьЧто(животное); // Выведет "Животное издает звук"
    сказатьЧто(собака); // Выведет "Собака лает"
    сказатьЧто(кошка); // Выведет "Кошка мяукает"

Полиморфизм делает код более гибким, так как он позволяет взаимодействовать с различными объектами через общий интерфейс, и это особенно полезно, когда вы работаете с коллекциями объектов разных типов.

Классы

В JavaScript классы представляют собой шаблоны для создания объектов и являются основой объектно-ориентированного программирования (ООП). Они предоставляют удобный способ определения структуры и поведения объектов. С классами в JavaScript можно создавать экземпляры объектов с общими свойствами и методами. Вот как определять и использовать классы в JavaScript:

Объявление класса:

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

class Человек {
  constructor(имя, возраст) {
    this.имя = имя;
    this.возраст = возраст;
  }

  приветствие() {
    console.log(`Привет, меня зовут ${this.имя} и мне ${this.возраст} лет.`);
  }
}

Создание экземпляров класса:

Чтобы создать экземпляр класса, используйте ключевое слово new, за которым идет вызов конструктора класса. Это создает новый объект с заданными свойствами.

const человек1 = new Человек("Иван", 30);
const человек2 = new Человек("Мария", 25);

человек1.приветствие(); // "Привет, меня зовут Иван и мне 30 лет."
человек2.приветствие(); // "Привет, меня зовут Мария и мне 25 лет."

Конструктор класса:

Конструктор - это метод класса, который вызывается при создании нового экземпляра. Он инициализирует свойства объекта.

Методы класса:

Методы класса - это функции, определенные в классе. Они предоставляют поведение объектам, созданным на основе этого класса.

Наследование:

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

class Студент extends Человек {
  constructor(имя, возраст, номерСтудента) {
    super(имя, возраст);
    this.номерСтудента = номерСтудента;
  }

  учеба() {
    console.log(`${this.имя} учится под номером ${this.номерСтудента}.`);
  }
}

Инкапсуляция:

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

class Счет {
  #баланс = 0;

  получитьБаланс() {
    return this.#баланс;
  }

  пополнить(сумма) {
    this.#баланс += сумма;
  }

  снять(сумма) {
    if (сумма <= this.#баланс) {
      this.#баланс -= сумма;
      return true;
    } else {
      return false;
    }
  }
}

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