11 ключевых концепций JavaScript, которые должен знать каждый Senior 👨‍💻

Hoisting, TDZ, глубокое и поверхностное копирование, типизация и многое другое — в одном понятном гиде. Разложим основы по полочкам с примерами и фишками!

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

🚀 Темы, которые мы разберём:

  • Hoisting (всплытие)

  • Temporal Dead Zone (временная мёртвая зона)

  • Function Declaration vs Function Expression

  • Shallow Copy vs Deep Copy (поверхностное и глубокое копирование)

  • Object.assign

  • Slice vs Splice

  • forEach vs Map

  • Global Execution Context

  • Polyfilling (полифиллы)

  • Глубокое погружение в map()

  • Приведение типов (Type Coercion)


🪄 1. Всплытие (Hoisting)

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

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

console.log(a); // undefined
var a = 10;

var — всплывает и инициализируется undefined, в то время как let и const всплывают, но не инициализируются. Поэтому следующий код вызовет ошибку:

console.log(b); // ReferenceError
let b = 20;

Что касается функций, то здесь разница между function declaration и function expression особенно важна:

console.log(getNum()); // OK
function getNum() { return 42; }

console.log(getArrow()); // TypeError: getArrow is not a function
var getArrow = () => 42;

📸 Промпт для фото: "Инфографика о hoisting в JavaScript, с разделением переменных var/let/const и function/function expression"


🕳 2. Temporal Dead Zone (TDZ)

Временная мёртвая зона — это период, в котором переменная уже объявлена (через let или const), но ещё не инициализирована. В TDZ любая попытка обращения к переменной вызывает ReferenceError.

console.log(value); // ReferenceError
let value = 100;

Этот механизм защищает нас от ошибок и делает поведение кода более предсказуемым. TDZ распространяется также на функции, определённые как const и let.


🧩 3. Function Declaration vs Function Expression

Function Declaration

function greet() {
  console.log("Hello!");
}

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

Function Expression

const greet = function() {
  console.log("Hello!");
}

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


📦 4. Shallow Copy vs Deep Copy

Поверхностное копирование (Shallow Copy)

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

const obj1 = { name: "Olga", address: { city: "Kazan" } };
const obj2 = { ...obj1 };
obj2.address.city = "Ufa";
console.log(obj1.address.city); // "Ufa"

Глубокое копирование (Deep Copy)

Позволяет полностью скопировать объект, включая вложенные структуры:

const deepCopy = structuredClone(obj1);
deepCopy.address.city = "Sochi";

Альтернативы:

  • JSON.stringify/parse — не работает с функциями и undefined

  • structuredClone — современный метод

  • Пользовательская рекурсивная функция

📸 Промпт для фото: "Сравнение поверхностного и глубокого копирования с визуализацией вложенных объектов"


🔄 5. Object.assign()

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

const objA = { name: "Alice" };
const objB = { age: 30 };
const result = Object.assign({}, objA, objB);

Особенности:

  • Возвращает целевой объект

  • Копирует только собственные перечисляемые свойства

  • Перезаписывает одноимённые свойства

Альтернатива — spread-синтаксис: { ...objA, ...objB }


✂️ 6. Slice vs Splice

slice() и splice() — методы массивов, часто путаемые между собой:

  • slice(start, end) — возвращает новый массив, не изменяя оригинальный

  • splice(start, deleteCount, ...items) — изменяет массив на месте

const arr = [1, 2, 3, 4, 5];
console.log(arr.slice(1, 3)); // [2, 3]
console.log(arr.splice(1, 2, 9, 9)); // [2, 3], arr теперь [1, 9, 9, 4, 5]

🔁 7. forEach vs map

Оба метода перебирают массив, но есть нюансы:

Особенность

forEach

map

Возвращает новый массив

Можно выйти из цикла?

Используется для

Побочных эффектов

Преобразований

[1, 2, , 4].map(x => x || 0); // обрабатываем sparse-массив

Если вам нужно прекратить выполнение — используйте for, for...of, some или every.


🌍 8. Global Execution Context

Контекст выполнения — это окружение, в котором код выполняется. Бывает двух типов:

  1. Глобальный — создаётся первым, содержит глобальные переменные, функции и объект this.

  2. Функциональный — создаётся при вызове каждой функции.

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


🛠 9. Polyfilling

Полифиллы позволяют эмулировать поведение новых возможностей языка в старых браузерах.

Пример: полифилл для Array.prototype.includes:

if (!Array.prototype.includes) {
  Array.prototype.includes = function(el) {
    return this.indexOf(el) !== -1;
  };
}

Полифиллы особенно важны при разработке кроссбраузерных решений.


🗺 10. Map Deep Dive

Метод map() принимает три аргумента:

  • значение

  • индекс

  • исходный массив

const data = [1, 2, , 4];
const result = data.map((val, idx, arr) => val ? val * 2 : (arr[idx - 1] || 1));

Особенности:

  • Пропущенные элементы (empty slots) игнорируются

  • Новые элементы, добавленные во время выполнения, не обрабатываются

  • Удалённые до выполнения — пропускаются


⚖️ 11. Type Coercion (Приведение типов)

Неявное (implicit):

10 + "2"; // "102"
10 - "2"; // 8
true + 1; // 2
[] + 1;   // "1"
null + 1; // 1
undefined + 1; // NaN

Явное (explicit):

String(123);
Number("456");
Boolean(0); // false

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


📝 Заключение

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

Разобрав такие темы, как hoisting, TDZ, типы функций, копирование объектов, особенности map и forEach, а также приведение типов, вы выходите на уровень, где JavaScript перестаёт быть просто языком — он становится инструментом точной настройки логики.

Бесплатно
Кодик: Интерактивное обучение!
Изучай HTML, JavaScript, CSS, Python, PHP, SQL, Git
Проходи практические уроки!
Получи сертификат!
Вам может быть интересно

Не нашли нужной статьи?
Напишите нам и ее сделаем!

Бесплатно
Кодик: Интерактивное обучение!
Изучай HTML, JavaScript, CSS, Python, PHP, SQL, Git
Проходи практические уроки!
Получи сертификат!
Главная
Курсы
Блог
Меню