← Назад к вопросам

Создается ли функция в scope

2.2 Middle🔥 251 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Функции и Scope в JavaScript

Да, функции создаются в scope (области видимости), и это поведение зависит от способа объявления функции. Функция всегда рождается в определённом scope и может обращаться к переменным из этого scope через замыкание (closure).

Function Declaration (объявление функции)

Function Declaration создаётся в текущем scope и поднимается (hoisting) в начало этого scope:

// Функцию можно вызвать ДО объявления
console.log(greet()); // 'Привет!' — работает!

function greet() {
  return 'Привет!';
}

Почему это работает? JavaScript выполняет две фазы:

  1. Фаза компиляции: функция создаётся и добавляется в scope
  2. Фаза выполнения: код выполняется строка за строкой
// Глобальный scope
function outer() {
  // Локальный scope функции outer
  function inner() {
    return 'inner';
  }
  
  return inner();
}

console.log(outer()); // 'inner'
console.log(inner()); // ReferenceError — inner не в глобальном scope!

Function Expression (выражение функции)

Function Expression создаёт функцию как значение переменной:

// Переменная поднимается, но значение undefined
console.log(typeof greet); // 'undefined'

const greet = function() {
  return 'Привет!';
};

console.log(greet()); // 'Привет!' — работает

Разница в hoisting:

// Function Declaration — поднимается целиком
sayHi(); // ✅ Работает, выводит 'Привет!'
function sayHi() { console.log('Привет!'); }

// Function Expression — поднимается только переменная
sayBye(); // ❌ TypeError: sayBye is not a function
var sayBye = function() { console.log('Пока!'); };

Функции и Closure (замыкание)

Функции создаются в scope и запоминают переменные из внешнего scope:

const message = 'Hello'; // Внешний scope

function greet() {
  // Функция создана в scope, где существует message
  return message + ' World';
}

console.log(greet()); // 'Hello World'

Более сложный пример с closure:

function createCounter() {
  let count = 0; // Переменная в scope функции createCounter
  
  function increment() {
    // increment создана в scope, где видна переменная count
    count++;
    return count;
  }
  
  return increment; // Возвращаем функцию
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
// Функция запомнила переменную count из своего scope!

Стрелочные функции (Arrow Functions)

Стрелочные функции также создаются в scope, но имеют особенность с this:

const user = {
  name: 'Иван',
  greet: function() {
    // Обычная функция создана в scope объекта
    console.log(this.name); // 'Иван'
  },
  greetArrow: () => {
    // Стрелочная функция создана в ГЛОБАЛЬНОМ scope
    console.log(this); // window (или undefined в strict mode)
  }
};

user.greet();      // 'Иван'
user.greetArrow(); // undefined

Блочный scope (Block Scope)

let и const создают переменные в блочном scope:

if (true) {
  let x = 1; // Создана в блочном scope if
  const y = 2; // Создана в блочном scope if
  var z = 3; // Создана в функциональном scope
}

console.log(typeof x); // 'undefined' — не в глобальном scope
console.log(typeof y); // 'undefined' — не в глобальном scope
console.log(z); // 3 — var поднялся в глобальный scope

Функции в блочном scope

if (true) {
  function test() {
    return 'Я в блочном scope';
  }
}

console.log(test()); // Может работать или не работать (зависит от браузера)
// В строгом режиме (strict mode) выдаст ошибку

'use strict';
if (true) {
  function test() {
    return 'Я в блочном scope';
  }
}

console.log(test()); // ReferenceError

Scope Chain (цепочка scope)

Функция создаётся в определённом scope, но может обращаться к переменным из родительских scope:

const global = 'глобальная';

function outer() {
  const outerVar = 'outer';
  
  function middle() {
    const middleVar = 'middle';
    
    function inner() {
      // inner видит: global, outerVar, middleVar, innerVar
      return global + outlerVar + middleVar;
    }
    
    return inner();
  }
  
  return middle();
}

Цепочка поиска переменных:

  1. Сначала в локальном scope функции
  2. Потом в родительском scope
  3. Потом в глобальном scope
  4. Ошибка ReferenceError, если не найдено

Ключевые моменты

  • Функции всегда создаются в scope — глобальном, локальном или блочном
  • Function Declaration поднимается полностью (hoisting)
  • Function Expression поднимается как переменная (значение = undefined)
  • Closure — функция запоминает переменные из своего scope
  • Scope chain — функция может обращаться к переменным родительских scope
  • Блочный scope (let, const) работает в фигурных скобках
  • Глобальный scope — самый внешний уровень видимости

Понимание того, как функции создаются в scope и как работает closure, критично для написания правильного и безопасного JavaScript кода.