JS Basics

Что такое замыкание (Closure)?

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

function counter() {
  let count = 0;
  return () => ++count;
}
 
const inc = counter();
inc(); // 1
inc(); // 2
// count недоступен снаружи, но функция его помнит

Практические применения:

  • Инкапсуляция приватного состояния.
  • Фабричные функции с параметрами.
  • Мемоизация и каррирование.

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

Каждый объект в JS имеет скрытую ссылку [[Prototype]] на другой объект. При обращении к свойству JS ищет его сначала в самом объекте, затем поднимается по цепочке прототипов.

const animal = { eat() { return 'eating'; } };
const dog = Object.create(animal);
dog.bark = () => 'woof';
 
dog.bark(); // 'woof'  — собственный метод
dog.eat();  // 'eating' — унаследован от animal
 
dog.__proto__ === animal; // true
// class — синтаксический сахар над прототипами
class Animal {
  eat() { return 'eating'; }
}
class Dog extends Animal {
  bark() { return 'woof'; }
}
 
const d = new Dog();
d.eat();  // 'eating' — через цепочку прототипов

Object.getPrototypeOf(obj) — правильный способ получить прототип вместо __proto__.


Функции и массивы — это объекты?

Да. Функции и массивы — специализированные объекты, наследующие от Object.prototype.

// Функция — объект
const fn = () => {};
fn.myProp = 'hello';
fn.myProp;            // 'hello'
fn instanceof Object; // true
typeof fn;            // 'function' — это лишь подтип, не отдельный тип
 
// Массив — объект
const arr = [1, 2, 3];
arr instanceof Object; // true
typeof arr;            // 'object'
Array.isArray(arr);    // true
ЗначениеtypeofНа самом деле
function(){}'function'Объект (подтип Function)
[]'object'Объект (подтип Array)
null'object'Не объект (баг JS)

Как проверить, что переменная содержит функцию?

const fn = () => {};
 
// ✅ Лучший способ — typeof
typeof fn === 'function'; // true
typeof null === 'function'; // false — не обманет
 
// instanceof — ненадёжен в разных контекстах (iframe)
fn instanceof Function; // true
 
// Максимально точно — Object.prototype.toString
Object.prototype.toString.call(fn); // '[object Function]'

На практике всегда используют typeof — он лаконичен и корректно обрабатывает null.


Как проверить, что значение — массив?

const arr = [1, 2, 3];
 
// ✅ Лучший способ — Array.isArray
Array.isArray(arr);   // true
Array.isArray({});    // false
Array.isArray(null);  // false
 
// Устаревшие / ненадёжные способы
arr instanceof Array; // true — ломается в iframe
typeof arr;           // 'object' — не отличает от {}

Array.isArray — единственный надёжный способ в любом контексте.

См. также

  • curry — каррирование через замыкания
  • memoize — мемоизация на замыкании