Suggest an editImprove this articleRefine the answer for “Execution context components”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**An execution context consists of three components: the Variable Environment (holds `var` and `function` declarations), the Lexical Environment (holds `let` and `const` plus the reference to the outer environment, that is, the scope chain) and the This Binding (the value of `this`, which depends on how the function was called).** It is that reference to the outer lexical environment that makes closures possible. ```javascript Execution Context { LexicalEnvironment: { EnvironmentRecord: { let, const }, OuterEnvironmentReference }, VariableEnvironment: { EnvironmentRecord: { var, function }, OuterEnvironmentReference }, ThisBinding: <value of this> } ``` **Key point:** VE is `var` and `function`; LE is `let`/`const` plus the scope chain; This Binding is `this`.Shown above the full answer for quick recall.Answer (EN)Image**An execution context in JavaScript consists of three main components: internal structures the engine creates so that your code can run.** Every context, global or function, contains a Variable Environment, a Lexical Environment and a This Binding. ## Theory ### TL;DR - **Variable Environment (VE)**: declarations made with `var` and `function`. - **Lexical Environment (LE)**: declarations made with `let` and `const` plus the reference to the outer environment. - **This Binding**: the value of `this`, determined by how the function was called. - The chain of `OuterEnvironmentReference` links forms the scope chain and is what makes closures possible. - Both environments have their own Environment Record, so `var` and `let` live in different records of the same context. ### Quick example ```javascript let x = 10; function outer() { let y = 20; function inner() { let z = 30; console.log(x, y, z); // 10 20 30 } inner(); } outer(); ``` The Lexical Environment of `inner()` holds: - its own variable `z`; - a reference to the environment of `outer()` (where `y` lives); - and through it a reference to the global environment (where `x` lives). It is the **Lexical Environment** that makes **closures** possible. ### Variable Environment Stores the **variables and functions** declared with `var` and `function` (not `let`/`const`). - It is determined when the context is created. - It is used to **initialise** variables and functions. - It is reachable only inside the current context. Example: ```javascript function test() { var a = 10; function inner() {} } ``` Here `a` and `inner` are part of the **Variable Environment** of `test`. ### Lexical Environment Responsible for **variable lookup** and for closures. It stores: - variables declared with `let` and `const`; - references to outer environments (the outer lexical environment reference); - the function itself as a "lexical environment". You can picture it as a "chain of scopes" (the scope chain): if a name is not in the current record, the lookup moves one level up, and so on up to the global environment. ### This Binding Defines **which object** `this` **refers to** in this context. It depends on **how the function was called**: | Call style | Value of `this` | | --- | --- | | Globally (in the browser) | `window` | | Inside a function (strict mode) | `undefined` | | Inside an object method | the object itself | | Through `call`, `apply`, `bind` | the value passed manually | | Inside an arrow function | taken from the outer context | Example: ```javascript const obj = { name: "Tim", show() { console.log(this.name); } }; obj.show(); // this = obj, so "Tim" ``` ### The combined structure Every execution context looks roughly like this: ```javascript Execution Context { LexicalEnvironment: { EnvironmentRecord: { let, const }, OuterEnvironmentReference: <reference to the outer LE> }, VariableEnvironment: { EnvironmentRecord: { var, function }, OuterEnvironmentReference: <reference to the outer LE> }, ThisBinding: <value of this> } ``` ### A visual example ```javascript let a = 1; function outer() { var b = 2; function inner() { let c = 3; console.log(a, b, c); } inner(); } outer(); ``` When `inner()` is called: - A **new Execution Context** is created, containing: - **Variable Environment:** `[]` - **Lexical Environment:** `{ c: 3 }` - **This Binding:** `undefined` (strict mode) - It has an **Outer Environment Reference** pointing to `outer` and from there to the global environment, which is what makes `b` and `a` reachable. ### Common mistakes - **Thinking `let` and `const` live in the Variable Environment.** They go into the Lexical Environment; the VE only holds `var` and function declarations. - **Assuming `let` is not hoisted.** It is, but until its declaration line it sits in the temporal dead zone, and touching it throws a `ReferenceError`. - **Confusing the This Binding with the lexical environment.** An arrow function has no `this` of its own at all; it takes it from the outer context. - **Thinking the scope chain is built at call time.** The `OuterEnvironmentReference` is fixed by where the function is written in the code, not by where it was called from. - **Forgetting about strict mode.** Code in modules and classes is always strict, so `this` in a plain function call is `undefined`, not `window`.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.