JS. Начало #1. Данные

JS. Начало #1. Данные

Автор: Рябкова Анна, Манюшкина Дарья

Введение

Что такое данные в программировании?

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

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

Почему важно уметь работать с переменными?

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

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

Переменные

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

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

Атрибуты переменных:

  • Имя или адрес — обозначает конкретную ячейку памяти, в которой хранятся необходимые для работы приложения данные.
  • Значение — конкретные данные, которые содержатся в проименованной ячейке памяти.
  • Тип данных — определяет характер значений, принимаемых переменной, виды операций с ними и их представление в памяти компьютера.

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

Правила именования переменных

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

Основные правила:

  • Называйте переменную по правилам именования языка. В противном случае код будет выдавать ошибку. Обычно название переменной — это сочетание букв латинского алфавита, цифр и символа подчеркивания _.
  • Не используйте зарезервированные имена. Это имена, которые уже выполняют в языке конкретные функции (например, var, class, return). Использование зарезервированного имени приведёт к ошибке.
  • Имена переменных чувствительны к регистру: myVar и myvar — это разные переменные.

Рекомендации по стилю:

  • Названия переменных должны быть понятными и осмысленными, чтобы код оставался читаемым.
    a = 5;
    userAge = 25;
  • Не используйте транслит, сокращения и одну букву, если это не общепринятое сокращение (например, i, j, k для счетчиков циклов).
  • Имя переменной должно начинаться с буквы, символа _ или $. Начинать с цифры нельзя.
  • Соблюдайте единый стиль написания. В JavaScript принято использовать camelCase для именования переменных:
    myVariableName
    my_variable_name

Способы объявления переменных (let, const, var) и их различия

В JavaScript есть три способа объявления переменных: var, let и const.

  • var — устаревший способ. Используется для объявления переменных с глобальной или функциональной областью видимости. Переменные, объявленные через var, могут быть переопределены и повторно объявлены. Сейчас var практически не используется.

  • let — современный способ объявления переменной, которая может изменяться. Переменная let имеет блочную область видимости (доступна только в {}), может переопределяться, но не может быть повторно объявлена в той же области.

  • const — для переменных, которые не должны изменяться. Попытка присвоить новое значение приведёт к ошибке. Однако, если const содержит объект или массив, их внутренние данные могут изменяться.

Какой способ объявления использовать в разных ситуациях?

Декларация const сообщает, что переменная не будет переназначена, что упрощает понимание кода и облегчает его поддержку.
Пример:

const phoneNumber = "89999999999";

Избегайте использования var, так как он может привести к ошибкам с областью видимости.

var count = people.length;
var enoughFood = count > sandwiches.length;

if (enoughFood) {
    var count = sandwiches.length; // случайно переопределяем переменную count
    console.log(
        "We have " + count + " sandwiches for everyone. Plenty for all!"
    );
}

// наша переменная count больше не содержит актуальное значение
console.log(
    "We have " + count + " people and " + sandwiches.length + " sandwiches!"
);

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

Основные типы данных в JavaScript

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

Примитивные типы данных в JavaScript являются неизменяемыми (immutable), что означает, что их значения нельзя изменить после создания.


Почему примитив называется примитивом?

Примитивные значения называются примитивами, потому что они представляют наиболее простые (примитивные) единицы данных, которые:

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

Примитивные типы в JavaScript:

  • string (строка)
  • number (число)
  • bigint (большое целое число)
  • boolean (логический тип)
  • symbol (уникальный идентификатор)
  • null (отсутствие значения)
  • undefined (значение не задано)

Примитивное значение всегда возвращает копию при присвоении:

let a = 10;
let b = a; // Копируется значение, а не ссылка
b = 20;

console.log(a); // 10 (осталось неизменным)
console.log(b); // 20

1. Строки (String)

Строки в JavaScript — это текстовые данные, заключенные в одинарные ('), двойные (") кавычки или шаблонные строки (`), которые используют обратные кавычки.

let greeting = "Hello, World!"; // строка в двойных кавычках
let name = "Alice"; // строка в одинарных кавычках
let message = `Hello, ${name}`; // шаблонная строка

console.log(greeting); // Вывод: Hello, World!
console.log(message); // Вывод: Hello, Alice

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

const name = "Алиса";
const age = 30;

//Обычная конкатенация
console.log("Меня зовут " + name + ", мне " + age + " лет.");

//Шаблонные строки
console.log(`Меня зовут ${name}, мне ${age} лет.`);

2. Числа (Number)

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

  • NaN (Not a Number) — означает, что значение не является числом.
  • Infinity (-Infinity) — положительная и отрицательная бесконечность.
let integer = 42; // целое число
let floatingPoint = 3.14; // дробное число
let notANumber = NaN; // значение NaN
let infinityValue = Infinity; // значение бесконечности

console.log(integer); // Вывод: 42
console.log(floatingPoint); // Вывод: 3.14
console.log(notANumber); // Вывод: NaN
console.log(infinityValue); // Вывод: Infinity

Обратите внимание: операция деления на ноль возвращает Infinity или -Infinity, а не вызывает ошибку.

console.log(1 / 0); // Вывод: Infinity
console.log(-1 / 0); // Вывод: -Infinity

🔢 Почему 0.1 + 0.2 !== 0.3 в JavaScript?

Если выполнить в JavaScript следующий код:

console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false

Можно заметить, что 0.1 + 0.2 не равно 0.3. Это происходит из-за особенностей представления чисел в формате IEEE 754.


🖥 IEEE 754 — стандарт представления чисел с плавающей запятой

JavaScript использует стандарт IEEE 754 (двойная точность, 64 бита) для представления чисел Number.

Число в этом формате записывается как:

(-1)^S _ M _ 2^E

Где:

  • Sзнак (0 — положительное, 1 — отрицательное),
  • Mмантисса (значащие биты числа),
  • Eпорядок (экспонента).

🔹 Проблема с 0.1 и 0.2

Числа 0.1 и 0.2 не могут быть точно представлены в двоичной системе.
Например, 0.1 в двоичной системе выглядит так:

0.0001100110011001100110011001100110011001100110011… (бесконечное повторение)

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

При сложении 0.1 и 0.2 происходит накопление ошибки:

console.log(0.1 + 0.2); // 0.30000000000000004

✅ Как избежать проблемы?

1️⃣ Округление до нужной точности:

console.log(Number((0.1 + 0.2).toFixed(10))); // 0.3

toFixed() возвращает строку, поэтому используем Number().

2️⃣ Проверка с учетом допустимой погрешности (EPSILON):

console.log(Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON); // true

Number.EPSILON — минимальная разница между представимыми числами.

3️⃣ Использование целых чисел для вычислений:

console.log((10 _ 0.1 + 10 _ 0.2) / 10); // 0.3

Умножаем на 10, выполняем сложение, затем делим обратно.

3. Логический тип (Boolean)

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

let isOnline = true; // Пользователь онлайн
let isActive = false; // Пользователь не активен

if (isOnline) {
    console.log("Пользователь онлайн");
} else {
    console.log("Пользователь не онлайн");
}

🔹 Логические значения также могут быть результатом выражений:

let a = 5;
let b = 10;

let result = a < b; // Результат будет true, так как 5 меньше 10
console.log(result); // Вывод: true

4. Символ (Symbol)

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

let symbol1 = Symbol("description");
let symbol2 = Symbol("description");

console.log(symbol1 === symbol2); // Вывод: false, так как каждый символ уникален

5. null и undefined

В JavaScript есть два типа данных, которые часто путают между собой — это null и undefined. Оба значения представляют отсутствие данных, но используются в разных контекстах.

  • null — это явное присваивание значения “ничто”. Это значение устанавливается, чтобы явно указать, что переменная не имеет значения.
let user = null; // Значение null указывает на отсутствие объекта
  • undefined — это значение, которое присваивается автоматически, если переменной не было задано значение или если она была объявлена, но не инициализирована.
let user;
console.log(user); // Вывод: undefined

6. BigInt

В стандартном JavaScript все числа представлены в формате IEEE 754 (64-битное число с плавающей запятой).
Это накладывает ограничения: максимальное безопасное целое число2^53 - 1 (9007199254740991), которое можно проверить с помощью:

console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991

Если попытаться выйти за этот диапазон, точность начинает теряться:

console.log(9007199254740991 + 1); // 9007199254740992 (ОК)
console.log(9007199254740991 + 2); // 9007199254740992 (Ошибка, потеря точности)

Чтобы решить эту проблему, в ES2020 был добавлен новый примитив BigInt, который позволяет работать с произвольно большими целыми числами без потери точности.

🔹 Создание BigInt

Число можно записать как BigInt, добавив суффикс n:

const bigNumber = 9007199254740991n;
console.log(bigNumber); // 9007199254740991n

Или создать с помощью конструктора:

const bigFromString = BigInt("9007199254740991000000000");
console.log(bigFromString); // 9007199254740991000000000n

🧮 Операции с BigInt

BigInt поддерживает основные арифметические операции:

const a = 100000000000000000000n;
const b = 2n;

console.log(a + b); // 100000000000000000002n
console.log(a - b); // 99999999999999999998n
console.log(a \* b); // 200000000000000000000n
console.log(a / b); // 50000000000000000000n (деление округляется вниз)

Важно: BigInt нельзя смешивать с Number:

console.log(10n + 5); // TypeError: Cannot mix BigInt and other types

Если нужно сложить BigInt и Number, необходимо привести их к одному типу:

console.log(10n + BigInt(5)); // 15n
console.log(Number(10n) + 5); // 15

📌 Где применяется BigInt?

  • Криптография (шифрование RSA)
  • Финансовые вычисления (работа с огромными числами)
  • Научные расчёты (астрономия, физика)
  • Блокчейн и криптовалюты (обработка больших чисел в хэшах)

7. Ссылочные типы данных (Object)

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

let person = { name: "John", age: 30 };
let anotherPerson = person; // anotherPerson ссылается на тот же объект, что и person

anotherPerson.age = 31;
console.log(person.age); // Вывод: 31, так как оба объекта ссылаются на один и тот же объект

8. Автобоксинг

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

Например, когда вы вызываете метод на строке или числе, JavaScript автоматически создает объект-обертку для примитивного значения.

let str = "Hello";
console.log(str.toUpperCase()); // Метод вызывается для строки, но происходит автобоксинг

let num = 123;
console.log(num.toString()); // Метод вызывается для числа, но происходит автобоксинг

🔹 При этом JavaScript автоматически оборачивает примитивы в соответствующие объекты (String, Number и т. д.) только на время выполнения метода, а затем возвращает их обратно в исходные примитивные значения.


Заключение

🔹 Типы данных — основа программирования на JavaScript. Они определяют, как информация хранится, передаётся и обрабатывается в коде.
🔹 Примитивные типы (string, number, boolean, null, undefined, symbol, bigint) неизменяемы и передаются по значению.
🔹 Ссылочные типы (объекты, массивы, функции) передаются по ссылке, что позволяет изменять их содержимое, но требует внимательного обращения.
🔹 Автобоксинг позволяет временно превращать примитивы в объекты, чтобы использовать методы.

Важно помнить:

  • Используйте const для неизменяемых значений, let — для изменяемых. var лучше не использовать.
  • 0.1 + 0.2 !== 0.3 из-за особенностей IEEE 754, это можно исправить с toFixed(), EPSILON или работой с целыми числами.
  • NaN не равен самому себе, проверяйте его с Number.isNaN().
  • BigInt нужен для работы с числами, выходящими за пределы Number.MAX_SAFE_INTEGER.
  • Объекты передаются по ссылке, и изменение одного может затронуть другой.

📌 Понимание типов данных поможет вам избежать ошибок, писать более чистый код и эффективно работать с информацией.
Экспериментируйте, пробуйте разные типы данных и применяйте их в реальных проектах! 🚀

Рябкова Анна, Манюшкина Дарья

Рябкова Анна, Манюшкина Дарья