JavaScript — синтаксис и типы данных

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

Как запустить код в консоли браузера?

Код JavaScript можно запускать в консоли браузера. Для этого нужно:

Нажать правой кнопкой мыши на любой странице, можно даже на этой и выбрать исследовать элемент. Также может быть скрыто в подменю Инструменты разработчика -> Инспектировать. Или сразу Инспектировать

    Контекстное меню Яндекс Браузер

    В общем, вам нужно получить такое меню и открыть в нем вкладку Консоль (Console)

    Консоль Инструментов разработчика

    После этого можно писать код JS прямо в консоль

    Вывод консоли разработчика

    Нажатие enter отправляет команду в консоль для выполнения. Для того чтобы перенести курсор на новую строчку, нужно нажать shift + enter. undefined после отправки в консоль — норма, не обращайте внимания). Чтобы вывести значение переменной, просто напишите ее имя. Браузер подскажет ее название и значение. Чтобы поменять значение переменной, просто присвойте ей другое значение:

    Как выполнять JavaScript код в файле html?

    Удобнее выполнять код в html файле. Создайте такой html документ в любом текстовом редакторе:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <script>
        console.log(5 + "5")          // "55"          (число → строка)
        console.log("5" * 3)          // 15            (строка → число)
        console.log("5" == 5)         // true
        console.log("0" == false)     // true
        console.log([] == 0)          // true          ← вот тут уже начинается жесть
        console.log("" == 0)          // true
        console.log(" " == 0)         // true          ← пробел тоже превратился в 0
        console.log([] == ![])        // true          ← мозг плавится
    </script>
    <body>
        
    </body>
    </html>

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

    Переменные — куда класть данные

    let name= "Гоша";          // можно менять значение
    let age= 27;
    let isStudent = true;
    let nullVar= null;        // специально пусто
    let undefinedVar;            // undefined — когда переменная объявлена, но ничего не положили
    
    const Pi = 3.14159;        // нельзя перезаписать
    const buttonColor = "#ff6b6b";
    
    // Старый (но всё ещё живой) способ — почти не используй в 2025–2026
    var oldStyle = "привет из 2005";

    Главное правило:

    • const — если значение не будет меняться
    • let — если будет меняться
    • var — только если очень хочется поностальгировать (или поддерживаешь IE11)

    Типы данных (то, что JS прячет от тебя)

    Что писатьКак JS это называетПримеры
    Числоnumber42, -3.14, 1e6 (миллион)
    Текстstring«привет», ‘как дела’
    Логическоеbooleantrue / false
    Ничегоnullспециально пусто
    Не определеноundefinedзабыли положить значение
    Большое числоbigint1234567890123456789012345
    СписокArray (объект)[1, «два», true]
    ОбъектObject{ name: «Вася», age: 28 }
    Функцияfunctionfunction() {} или () => {}

    Почему JavaScript «прячет» типы данных?

    JavaScript — это язык с динамической и слабой типизацией. Именно эта комбинация и создаёт ощущение, что «типы где-то спрятаны».

    Что значит «динамическая типизация»

    Вы не обязаны заранее говорить, какого типа будет переменная:

    let x;           // пока вообще никакого типа
    x = 5;           // теперь number
    x = "привет";    // теперь string
    x = [1,2,3];     // теперь массив (объект)
    x = null;        // теперь null

    Всё это нормально. Переменная не привязана к типу жёстко — тип «живёт» в значении, а не в переменной.

    Что значит «слабая типизация»

    JavaScript очень старается помочь и почти всегда пытается привести типы сам, когда вы производите операции:

    console.log(5 + "5")          // "55"          (число → строка)
    console.log("5" * 3)          // 15            (строка → число)
    console.log("5" == 5)         // true
    console.log("0" == false)     // true
    console.log([] == 0)          // true          ← вот тут уже начинается жесть
    console.log("" == 0)          // true
    console.log(" " == 0)         // true          ← пробел тоже превратился в 0
    console.log([] == ![])        // true          ← мозг плавится

    Это всё происходит потому, что JS следует правилу:

    «Если можно как-то осмысленно привести типы — я это сделаю, даже если это выглядит дико»

    Таблица самых популярных сюрпризов

    ВыражениеРезультатПочему так?
    «5» == 5trueстрока приводится к числу
    «5» === 5falseстрогое — типы разные
    0 == falsetruefalse → 0
    «» == falsetrueпустая строка → 0 → false
    [] == 0trueмассив → «» → 0
    [1] == 1trueмассив с одним элементом → строка → число
    null == undefinedtrueспециальное исключение в языке
    null === undefinedfalseразные типы

    Почему это сделали именно так?

    Исторические причины (1995 год, 10 дней на создание языка):

    • Браузеры должны были быть максимально дружелюбными к «непрограммистам»
    • Люди писали маленькие скрипты прямо в HTML
    • Никто не хотел, чтобы сайт падал из-за ошибки типа
    • Было важно, чтобы 5 + » товаров» работало без лишних танцев

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

    Как жить с этим?

    // 1. Всегда используйте строгое сравнение
    if (возраст === 18) { ... }     // вместо ==
    
    // 2. Проверяйте тип явно, когда сомневаешься
    if (typeof значение === "string") { ... }
    
    // 3. Используйте Number(), String(), Boolean() когда нужно привести явно
    let число = Number(input.value);           // надёжнее чем просто +input.value
    
    // 4. Для значений по умолчанию лучше ?? (nullish coalescing)
    let имя = пользователь.имя ?? "Гость";     // только null и undefined
    
    // 5. Самый простой способ проверить «пусто»
    if (!значение) { ... }   // работает для "", 0, null, undefined, false

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

    Поэтому современные разработчики просто учатся жить с этим характером и используют ===, ??, typeof и TypeScript (когда проект становится большим).

    Самые частые операции JS

    // Математика
    let a = 10;
    let b = 3;
    console.log(a + b);   // 13
    console.log(a - b);   // 7
    console.log(a * b);   // 30
    console.log(a / b);   // 3.333...
    console.log(a % b);   // 1 (остаток от деления)
    
    // Сложение строк (конкатенация)
    let name = "Маша";
    console.log("Привет, " + name+ "!");           // старый способ
    console.log(`Привет, ${name}! Сегодня 2026 год.`);   // современный и красивый
    
    // Сравнение (очень важно!)
    console.log(5 == "5");     // true   (с приведением типов — опасно!)
    console.log(5 === "5");    // false  (строгое сравнение — используй почти всегда)
    console.log(0 == false);   // true   (вот за это JS многие ненавидят)
    console.log(0 === false);  // false
    
    // Логические операторы
    let age = 19;
    let student = true;
    let canDrink = age >= 18 && !student;   // И
    let canEnter = age >= 16 || student;   // ИЛИ
    let dislike = !canEnter;                // НЕ

    Условия JS — если… то… иначе…

    if (age >= 18) {
        console.log("Взрослый");
    } else if (age >= 14) {
        console.log("Подросток");
    } else {
        console.log("Малыш");
    }
    
    // Короткая запись (тернарный оператор)
    let status = age >= 18 ? "взрослый" : "ребёнок";
    console.log(status);
    
    // Ещё короче (логическое ИЛИ для значений по умолчанию)
    let userName = inputName || "Гость";   // если пусто → Гость

    не обязательно писать else if и else. if может существовать как самостоятельно, так и с одним из условий (else if, else).

    Обратите внимание! Если вы напишите конструкцию вида

    if (age >= 18) {
    console.log(«Взрослый»);
    } else if (age >= 14) {
    console.log(«Подросток»);
    }

    то часть условий не будет обработана. В данном случае — все возраста меньше 13.

    Функции — самые полезные кирпичики

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

    Самый простой способ объявить функцию (function declaration)

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

    function greet() {
        console.log("Hello, world!");
    }
    • Что здесь происходит?
      • function — ключевое слово, которое говорит JS: «Эй, сейчас будет функция!»
      • greet — имя функции. Должно быть как переменная: без пробелов, начинается с буквы (маленькой или большой), можно цифры и подчёркивания. Не используйте слова вроде function или if — они зарезервированы.
      • () — круглые скобки для параметров (о них ниже). Если ничего не нужно — оставь пустыми.
      • { } — фигурные скобки. Внутри пишете код, который выполнится, когда вызовешь функцию.

    Чтобы запустить:

    greet();   // Выводит "Hello, world!"

    Возможная непонятка: Если функция ничего не возвращает (как здесь), она по умолчанию вернёт undefined. Не пугайся, если увидишь это в консоли.

    Параметры и аргументы — как передавать данные в функцию

    Параметры — это переменные внутри функции, в которые вы передаете значения при вызове.

    function addNumbers(a, b) {
        console.log(a + b);
    }
    • a, b — параметры. Это как переменные, но они создаются только внутри функции.
    • Когда вызываешь: addNumbers(5, 3); — здесь 5 и 3 — аргументы (реальные значения).

    Что если аргументов меньше или больше?

    • Меньше: недостающие станут undefined. Например, addNumbers(5); — b будет undefined, и 5 + undefined = NaN (Not a Number — ещё одна непонятка JS, значит «не число»).
    • Больше: лишние просто игнорируются.

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

    function greet(name = "Guest") {
        console.log("Hello, " + name);
    }
    greet();       // Hello, Guest
    greet("Alex"); // Hello, Alex

    Возврат значения — return, чтобы функция что-то «отдала» назад

    Без return функция просто делает что-то и молчит. С return — она отдаёт результат.

    function multiply(x, y) {
        return x * y;
    }
    
    let result = multiply(4, 5);   // result = 20
    • return — ключевое слово. После него функция сразу заканчивается (даже если ниже код).
    • Можно без return — тогда вернёт undefined.

    Непонятка: return не печатает ничего сам. Чтобы увидеть — используйте console.log(result);.

    Другой способ: function expression (функция как переменная)

    Здесь функция без имени, но присваивается переменной.

    const subtract = function(a, b) {
        return a - b;
    };
    
    console.log(subtract(10, 2));   // 8
    • Зачем? Полезно, если хотите передать функцию как аргумент (callback — об этом позже).
    • Разница с declaration: expression не «поднимается» (hoisting).

    Что такое hoisting? JS «поднимает» declaration в начало кода. Значит, вы можете вызвать функцию до её объявления:

    greet();   // Работает!
    
    function greet() { ... }

    Но с expression — ошибка, если вызвать раньше.

    Стрелочные функции (arrow functions) — короткий и модный синтаксис

    С 2015 года — самый популярный способ. Особенно для коротких функций.

    const divide = (a, b) => {
        return a / b;
    };
    
    console.log(divide(10, 2));   // 5
    • () => { } — стрелка вместо function.
    • Если один параметр — скобки можно убрать: x => { return x * 2; }
    • Если тело короткое — без фигурных скобок и return: x => x * 2;
    • Если параметров нет: () => console.log(«Hi!»);

    Почему они крутые? Лаконичные, и… внимание на this!

    this — самая большая непонятка в функциях (и как её понять)

    this — это как «я» в предложении. Оно ссылается на «контекст» — объект, в котором функция вызвана. В простых функциях:

    function whoAmI() {
        console.log(this);
    }
    whoAmI();   // this = window (в браузере) или global (в Node.js)

    Но если функция внутри объекта:

    const person = {
        name: "Alice",
        sayName: function() {
            console.log(this.name);
        }
    };
    
    person.sayName();   // Alice (this = person)
    • this — это person, потому что функция вызвана как метод объекта.

    Проблема с обычными функциями: this может «теряться». Например, если передать функцию в callback:

    setTimeout(person.sayName, 1000);   // undefined! (this = window)

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

    const person = {
        name: "Alice",
        sayName: () => {
            console.log(this.name);   // this берётся снаружи, но если снаружи window — undefined
        }
    };

    В объектах стрелки не всегда подходят для методов! Лучше использовать обычные функции для методов, или bind:

    setTimeout(person.sayName.bind(person), 1000);   // Alice

    Коротко о this для новичков:

    • В методах объектов — this = объект.
    • В простых функциях — this = глобальный объект (лучше избегать).
    • В стрелках — this от родителя. Если запутался — используй переменные вместо this на старте.

    Область видимости (scope) — где живут переменные в функциях

    Переменные внутри функции — локальные (видны только внутри).

    function test() {
        let localVar = "I'm inside!";
        console.log(localVar);   // Работает
    }
    console.log(localVar);   // Ошибка! Не видно снаружи
    • Глобальные переменные (объявленные вне функций) видны везде.
    • let и const — блочные (видны только в { }). var — функциональные (видны во всей функции). Избегайте var.

    Краткая таблица: какой синтаксис когда использовать

    Тип функцииСинтаксис примерКогда использовать?
    Declarationfunction name() { }Для основных функций, которые вызываешь много раз.
    Expressionconst name = function() { };Когда присваиваешь переменной или передаёшь как аргумент.
    Arrowconst name = () => { };Для коротких функций, callbacks, где важен this.

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

    Пишите комментарии если есть вопросы!

    Комментарии

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *