JavaScript
JavaScript — динамический язык, который в браузере управляет документом, событиями и сетевыми запросами. Его модель заметно отличается от Java: тип переменной определяется значением во время выполнения, функции являются объектами, а асинхронное продолжение обычно проходит через event loop.
Объявление
const userId = 42;
let status = "loading";
status = "ready";
// userId = 43; // нельзя переназначить constconst запрещает переназначение binding, но не делает объект immutable:
const settings = { theme: "light" };
settings.theme = "dark"; // допустимоvar имеет function scope и hoisting-поведение, которое проще случайно понять неправильно. Для нового кода обычно достаточно const и let.
Типы
Примитивы:
string;number;bigint;boolean;undefined;symbol;nullкак отдельное значение, хотяtypeof nullисторически возвращает"object".
Объекты включают arrays, functions, dates и обычные records.
typeof 10; // "number"
typeof "10"; // "string"
Array.isArray([]); // trueСравнение
=== сравнивает без неявного преобразования типов. == может преобразовать операнды:
0 == false; // true
0 === false; // falseДля предсказуемого кода использую strict equality.
Функции и closures
Функция запоминает lexical environment, где была создана:
function counter() {
let value = 0;
return () => ++value;
}
const next = counter();
next(); // 1
next(); // 2Closure позволяет хранить состояние, но также способен удерживать объекты в памяти дольше ожидаемого.
Event loop
JavaScript-код в браузерном main thread выполняет один текущий call stack. Асинхронная операция не «продолжает функцию сама»: после завершения её callback ставится в очередь.
Promise callbacks относятся к microtasks и выполняются после текущего stack, до следующей обычной task:
console.log("A");
setTimeout(() => console.log("B"), 0);
Promise.resolve().then(() => console.log("C"));
console.log("D");
// A, D, C, BДолгое синхронное вычисление блокирует обработку событий и отрисовку, даже если вокруг приложения много async функций.
Promise и async/await
async function loadItem(id) {
const response = await fetch(`/api/items/${id}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
}await приостанавливает конкретную async function, но не весь thread. Ошибка Promise превращается в исключение в точке await.
Подробнее: AJAX fetch.
Модули
// math.js
export function sum(left, right) {
return left + right;
}
// app.js
import { sum } from "./math.js";ES modules имеют собственную область видимости и статические imports, которые анализируются до исполнения.
Вопросы для собеседования
Чем undefined отличается от null?
undefined обычно означает отсутствие присвоенного значения. null — явно записанное отсутствие.
Что хранит closure?
Доступ к lexical environment, а не снимок отдельных значений.
Почему fetch с HTTP 500 не всегда попадает в catch?
Promise отклоняется при сетевой ошибке, но HTTP error остаётся нормальным response. Нужно проверить response.ok.
Делает ли async функцию параллельной?
Нет. Она возвращает Promise и позволяет неблокирующее ожидание, но CPU-код всё равно выполняется в thread, пока не вынесен в worker.