[Расширенная фаза 1-1] Понимание контекста выполнения и стека выполнения в JavaScript

внешний интерфейс JavaScript

Обновление: Спасибо за вашу поддержку. Недавно я бросил сводку данных для всех, чтобы прочитать систему. В будущем будет больше контента и больше оптимизации.Нажмите здесь, чтобы просмотреть

------ Далее идет текст ------

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

Если вы считаете, что эта серия хороша, пожалуйста, ставьте лайк, комментируйте и пересылайте. Ваша поддержка — самая большая мотивация для меня продолжать.


Контекст выполнения — это абстракция среды, в которой анализируется и выполняется текущий код JavaScript.

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

Всего существует три типа контекстов выполнения

  • глобальный контекст выполнения: есть только один, глобальный объект в браузере — это объект окна,thisуказывает на этот глобальный объект.

  • контекст выполнения функции: Их бесконечное количество, которые будут создаваться только при вызове функции, а новый контекст выполнения будет создаваться каждый раз при вызове функции.

  • Контекст выполнения функции Eval: относится к работе наevalКод в функциях, используется редко и не рекомендуется.

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

Стек выполнения, также называемый стеком вызовов, имеет структуру LIFO (последним поступил — первым обслужен), в которой хранятся все контексты выполнения, созданные во время выполнения кода.

Когда код JS запускается в первый раз,ГлобальныйКонтекст выполнения помещается в текущий стек выполнения. Всякий раз, когда происходит вызов функции, движок создаетновая функцияВыполнить контекст и поместить его на вершину текущего стека выполнения.

Согласно правилам LIFO стека выполнения, когда функция на вершине стека завершается, соответствующая ей функцияфункцияКонтекст выполнения будет извлечен из стека выполнения, а элемент управления контекстом будет перемещен в текущий стек выполнения.Следующийконтекст исполнения.

var a = 'Hello World!';

function first() {  
  console.log('Inside first function');  
  second();  
  console.log('Again inside first function');  
}

function second() {  
  console.log('Inside second function');  
}

first();  
console.log('Inside Global Execution Context');

// Inside first function
// Inside second function
// Again inside first function
// Inside Global Execution Context

Создание контекста выполнения

Контекст выполнения создается в два этапа:1) этап создания; 2) Этап исполнения

создать сцену

  • 1. Подтвердитьthisзначение, также известное какThis Binding.

  • 2,Лексическая средаКомпоненты созданы.

  • 3.Переменная средаКомпоненты созданы.

Может быть более интуитивно понятно смотреть непосредственно на псевдокод

ExecutionContext = {  
  ThisBinding = <this value>,     // 确定this 
  LexicalEnvironment = { ... },   // 词法环境
  VariableEnvironment = { ... },  // 变量环境
}
This Binding
  • ГлобальныйВ контексте исполненияthisЗначение указывает на глобальный объект в браузереthisзначение указывает наwindow объект, находясь вnodejsуказывая на этот файлmoduleобъект.

  • функцияВ контексте исполненияthisЗначение зависит от того, как была вызвана функция. В частности: привязка по умолчанию, неявная привязка, явная привязка (жесткая привязка),newПривязка, функция стрелки, конкретное содержание будет подробно объяснено в разделе [этот всесторонний анализ].

Лексическое окружение

Два лексических окружениякомпонент

  • 1,Экологические записи: Фактическое место, где хранятся объявления переменных и функций.

  • 2,Ссылка на внешнюю среду: имеет доступ к своему внешнему лексическому окружению

Два лексических окруженияТипы

  • 1,глобальная среда: это лексическая среда без внешней среды, внешняя среда которой упоминается какnull. иметь глобальный объект (объект окна) и связанные с ним методы и свойства (например, методы массива) и любые определяемые пользователем глобальные переменные,thisЗначение указывает на этот глобальный объект.

  • 2,функциональная среда: Пользовательские переменные в функции хранятся вЭкологические записи, включаяargumentsобъект. Ссылка на внешнюю среду может быть глобальной средой или внешней функциональной средой, содержащей внутреннюю функцию.

Может быть более интуитивно понятно смотреть непосредственно на псевдокод

GlobalExectionContext = {  // 全局执行上下文
  LexicalEnvironment: {    	  // 词法环境
    EnvironmentRecord: {   		// 环境记录
      Type: "Object",      		   // 全局环境
      // 标识符绑定在这里 
      outer: <null>  	   		   // 对外部环境的引用
  }  
}

FunctionExectionContext = { // 函数执行上下文
  LexicalEnvironment: {  	  // 词法环境
    EnvironmentRecord: {  		// 环境记录
      Type: "Declarative",  	   // 函数环境
      // 标识符绑定在这里 			  // 对外部环境的引用
      outer: <Global or outer function environment reference>  
  }  
}
переменная среда

Окружение переменных также является лексическим окружением, поэтому оно обладает всеми свойствами лексического окружения, определенными выше.

В ES6,Лексическийокружающая среда иПеременнаяСреда отличается тем, что первая используется для хранения объявлений функций и переменных (letа такжеconst)привязка, которая используется только для храненияПеременная(var)** обязательная.

Знакомство с примерами

let a = 20;  
const b = 30;  
var c;

function multiply(e, f) {  
 var g = 20;  
 return e * f * g;  
}

c = multiply(20, 30);

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

GlobalExectionContext = {

  ThisBinding: <Global Object>,

  LexicalEnvironment: {  
    EnvironmentRecord: {  
      Type: "Object",  
      // 标识符绑定在这里  
      a: < uninitialized >,  
      b: < uninitialized >,  
      multiply: < func >  
    }  
    outer: <null>  
  },

  VariableEnvironment: {  
    EnvironmentRecord: {  
      Type: "Object",  
      // 标识符绑定在这里  
      c: undefined,  
    }  
    outer: <null>  
  }  
}

FunctionExectionContext = {  
   
  ThisBinding: <Global Object>,

  LexicalEnvironment: {  
    EnvironmentRecord: {  
      Type: "Declarative",  
      // 标识符绑定在这里  
      Arguments: {0: 20, 1: 30, length: 2},  
    },  
    outer: <GlobalLexicalEnvironment>  
  },

  VariableEnvironment: {  
    EnvironmentRecord: {  
      Type: "Declarative",  
      // 标识符绑定在这里  
      g: undefined  
    },  
    outer: <GlobalLexicalEnvironment>  
  }  
}

переменное продвижениеПричина: на этапе создания объявление функции сохраняется в среде, а для переменной устанавливается значениеundefined(существуетvarслучае) или оставаться неинициализированным (вletа такжеconstна случай, если). Вот почему можно получить доступ до объявленияvarопределенная переменная (хотя онаundefined), но при доступе до объявленияletа такжеconstОпределенная переменная подскажет причину ошибки ссылки. Это называется переменным подъемом.

этап выполнения

На этом этапе завершается назначение всех переменных и, наконец, выполняется код.

Если механизм Javascript не может найти фактическое местоположение, указанное в исходном кодеletзначение переменной, то ей будет присвоеноundefinedстоимость.

Ссылаться на

Понимание контекста выполнения Javascript и стека выполнения