меню

Контекст выполнения функции — это одно из фундаментальных понятий в JavaScript. Контекстом еще часто называют значение переменной this внутри функции. Также иногда путают понятия «контекст выполнения» и «область видимости» — это не одно и то же. Давайте разберемся с этими понятиями.

Каждый вызов функции имеет и область видимости, и переменную this, и контекст выполнения. Область видимости определяет доступ к переменным при вызове функции и является уникальной для каждого вызова. Значение переменной this — это ссылка на объект, который «вызывает» код в данный момент. Контекст выполнения содержит и область видимости, и аргументы функции, и переменную this.

Переменная this

Значение переменной this чаще всего определяется тем, как вызывается функция. Когда функция вызывается как метод объекта, переменная this приобретает значение ссылки на объект, который вызывает этот метод:

  
var user = {
    name: 'John Smith',
    getName: function() {
        console.log(this.name);
    }
};
user.getName();   // John Smith
 

Тот же принцип применяется при вызове функции с оператором new, чтобы создать экземпляр объекта. При вызове таким образом, в качестве значения this в рамках функции будет установлена ссылка на вновь созданный объект, например:

 
function test(){
    alert(this);
}
test();      // window
new test();  // test
 

Когда мы вызываем функцию как функцию (не как метод объекта), эта функция будет выполнена в глобальном контексте. Значением переменной this в данном случае будет ссылка на глобальный объект. Однако, если функция вызывается как функция в строгом режиме (strict mode) — значением this будет undefined.

Контекст выполнения

Код в JavaScript может быть одного из следующих типов:

  • eval-код — код, выполняющийся внутри функции eval();
  • код функции — код, выполняющийся в теле функции;
  • глобальный код — код, не выполняющийся в рамках какой-либо функции.

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

Рассмотрим пример:

  
var hello = 'Hello';

var user = function() { // контекст выполнения функции
    var name = 'John Smith';

    var getName = function() { // контекст выполнения функции
        return name;
    }

    var sayHello = function() { // контекст выполнения функции
        console.log(hello + ', ' + getName());
    }

    sayHello();
}
user(); 
 

В данном примере мы имеем один глобальный контекст выполнения и 3 контекста выполнения функции.

Каждый раз, когда создается новый контекст выполнения, он добавляется в верхнюю часть стека выполнения. Браузер всегда будет выполнять код в текущем контексте выполнения, который находится на вершине стека выполнения. После завершения, контекст будет удален из верхней части стека и управление вернется к контексту выполнения ниже.

Основные вещи, которые необходимо помнить и понимать о контексте выполнения:

  • Однопоточность — JavaScript работает в однопоточном режиме, т.е. только одна операция может быть выполнена в определенный момент времени.
  • Синхронное выполнение кода — код выполняется синхронно, т.е. следующая операция не выполняется до завершения предыдущей.
  • Один глобальный контекст выполнения.
  • Бесконечное количество контекстов выполнения функции.
  • Каждый вызов функции создает новый контекст выполнения, даже если функция рекурсивно вызывает сама себя.

В интерпретаторе JavaScript каждое создание контекста выполнения происходит в два этапа: этап создания (когда функция только вызвана, но код внутри нее еще не выполняется) и этап выполнения. На этапе создания интерпретатор сначала создает объект переменных (также называемый объект активации), который состоит из всех переменных, объявлений функций и аргументов, определенных внутри контекста выполнения. Затем инициализируется область видимости, и в последнюю очередь определяется значение переменной this. На этапе выполнения внутренним переменным присваивается значение, код интерпретируется и выполняется.

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

 
executionContextObj = {
    variableObject: { /* объект активации - состоит из параметров функции, внутренних переменных и объявлений функций */ },
    scopeChain: { /* цепочка областей видимости - объект активации + все объекты активации родительских контекстов выполнения */ },
    this: {}
}
  

Для каждого контекста выполнения существует своя цепочка областей видимости. Цепочка областей видимости контекста выполнения включает области видимости из предыдущих контекстов в стеке выполнения.

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

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


Возможно, вам будет интересно

JavaScript and JQuery 1.8.3 решение проблемы с функцией attr() на примере генератора пароля

Совсем недавно решил написать генератор пароля с возможностью просмотра генерированного пароля под звездочками. Для работы выбрал JQuery 1.8.3 и нативный JavaScript. При написании самого скрипта столкнулся с проблемой в JQuery 1.8.3 с функцией attr().

Каррирование в JavaScript

В этой статье вы простым языком поймете работу с каррированием в JavaScript и увидите рабочие примеры его применения

AJAX и JavaScript. Загрузка контента без перезагрузки страницы

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

Зачем нам нужен TypeScript?

В этой статье мы узнаем зачем нам нужен TypeScript, некоторые основные понятия, которые помогут нам начать работу, и несколько примеров JavaScript.

Оформление заявки

Документы на создание сайта

Изучите наше коммерческое предложение, заполните БРИФ и отправьте его на почту maxidebox@list.ru. Изучив все пожелания из БРИФ-а, обратным ответом оповестим Вас по стоимости разработке, ответим на вопросы.

КП на создание сайта Коммерческое предложение на созданеи сайта

Мы берем на себя ответственность за все стадии работы и полностью избавляем клиентов от забот и необходимости вникать в тонкости.

Скачать БРИФ (акета) на создание сайта Скачать БРИФ (акета) на создание сайта

Зополните у БРИФ-а все необходимые поля. Сделайте краткое описание к каждому из пунктов анкеты, привидите примеры в соответсвующий пунктах - это позволит лучше понять Ваши ожидания и требования к сайту