> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/web/js/concept/execution-context/lexical-environment.md).

# lexical environment

[JS](/web/js.md) ⟩ [concept](/web/browser/concepts.md) ⟩ [execution context](/web/js/concept/execution-context.md) ⟩ lexical environment

{% hint style="success" %}
In JavaScript, <mark style="color:red;">**every**</mark> running [function](/web/js/val/func.md), code [block](/web/js/grammar/statement/other/block.md) <mark style="color:blue;">`{...}`</mark>, and the <mark style="color:yellow;">**script as a whole**</mark> have an <mark style="color:yellow;">**internal associated object**</mark> known as the "<mark style="color:purple;">**lexical environment**</mark>", it consists of <mark style="color:yellow;">**two parts**</mark>:

* [environment record](/web/js/concept/execution-context/lexical-environment/environment-record.md) – an object that stores&#x20;
  * all <mark style="color:yellow;">**local**</mark> [variable](/web/js/variable.md)(s) as its [<mark style="color:orange;">**properties**</mark>](/web/js/val/obj/prop.md).
  * <mark style="color:yellow;">**other information**</mark> like the value of [this](/web/js/concept/execution-context/this.md).&#x20;
* A [**reference**](/web/js/concept/execution-context/lexical-environment/environment.md) to the <mark style="color:yellow;">**outer**</mark>**&#x20;**<mark style="color:purple;">**lexical environment**</mark> (associated with the outer code).&#x20;

📗 JS.info ⟩ [Lexical Environment](https://javascript.info/closure#lexical-environment)
{% endhint %}

{% tabs %}
{% tab title="🖥️ 影片" %}
{% embed url="<https://youtu.be/HuF-qYRnEAo>" %}

* replit：[lexical environment - Counter()](https://replit.com/@pegasusroe/lexical-environment-Counter#index.js)

```javascript
// make counter
function Counter() {

    let count = 0;

    return function() {
        return ++count;
    };
}

// a counter instance
let counter = Counter();

counter(),    // 1
counter(),    // 2
```

{% endtab %}

{% tab title="🔴 主題" %}

* :small\_orange\_diamond:[environment record](/web/js/concept/execution-context/lexical-environment/environment-record.md) - stores local variables/this ...
* :small\_orange\_diamond:[\[\[Environment\]\]](/web/js/concept/execution-context/lexical-environment/environment.md) - reference to lexical environment where a function was made.
* :exclamation:[lexical environment optimizaton](/web/js/concept/execution-context/lexical-environment/optimize.md)
* :scales:[lexical environment vs. scope](/web/js/scope/lexical-environment-vs.-scope.md)
* :star:[closure](/web/js/val/func/closure.md) - function that can access its outer lexical environment.
* :exclamation:[modify current scope at runtime❗️](/web/js/concept/env/js-engine/mode/sloppy-mode/modify-current-scope-at-runtime.md) - (actually) modify current lexical environment.
  {% endtab %}

{% tab title="🗺️ 圖解" %} <img src="https://2527454625-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MfvEFZnSBhKT6fJmus0%2Fuploads%2FRiPk2hPzkYjgnTvI3diN%2Flexical.environment.svg?alt=media&amp;token=4aa199a3-a217-4f06-9941-bd01be4e0e92" alt="lexical environment" class="gitbook-drawing">
{% endtab %}

{% tab title="⭐️ 重點" %}
{% hint style="info" %}
A "[variable](/web/js/variable.md)" is just a [property](/web/js/val/obj/prop.md) of the [environment record](/web/js/concept/execution-context/lexical-environment/environment-record.md).&#x20;
{% endhint %}

{% hint style="success" %}
A [closure](/web/js/val/func/closure.md) is the <mark style="color:yellow;">**combination**</mark> of a [function](/web/js/val/func.md) <mark style="color:yellow;">**bundled together**</mark> (enclosed) with <mark style="color:yellow;">**references**</mark> to its <mark style="color:yellow;">**surrounding state**</mark> (the <mark style="color:purple;">**lexical environment**</mark>).&#x20;

📘 [MDN: Closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)
{% endhint %}

{% hint style="info" %}
[compilation](/web/js/compile.md) creates a <mark style="color:yellow;">**map**</mark> of all the [lexical scope](/web/js/scope/lexical-scope.md)s ... you can think of this plan as inserted code for use at [runtime](/web/js/compile/runtime.md), which <mark style="color:yellow;">**defines**</mark> <mark style="color:orange;">**all the scopes**</mark> (aka, "<mark style="color:purple;">**lexical environments**</mark>") and <mark style="color:yellow;">**registers**</mark> all the [identifier](/web/js/grammar/token/id.md)s ([variable](/web/js/variable.md)s) for each scope. :green\_book: [You Don't Know JS](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch1.md#lexical-scope)
{% endhint %}

{% hint style="warning" %}
Usually, a <mark style="color:purple;">**lexical environments**</mark> is <mark style="color:yellow;">**removed**</mark> from memory with all the variables <mark style="color:orange;">**after**</mark> the <mark style="color:yellow;">**function call**</mark> finishes.
{% endhint %}

{% hint style="info" %}
The [scope](/web/js/scope.md) of a <mark style="color:yellow;">**code block**</mark> can reach all its <mark style="color:yellow;">**parent's**</mark> [lexical environment](/web/js/concept/execution-context/lexical-environment.md) so it can use its parent’s [variable](/web/js/variable.md)(s). In this way, we have a [scope chain](/web/js/scope/chain.md), chain of all parent’s [scope](/web/js/scope.md).

{% endhint %}
{% endtab %}

{% tab title="👥 相關" %}

* :scales:[lexical environment vs. scope](/web/js/scope/lexical-environment-vs.-scope.md)
* :scales:[scope chain](/web/js/scope/chain.md) is similar to <mark style="color:purple;">**lexical environments**</mark>.
* :star:<mark style="color:purple;">**lexical environment**</mark> is part of [execution context](/web/js/concept/execution-context.md).
* :exclamation:["this" determined on call site❗️](/web/js/concept/execution-context/this/this-determined-on-call-site.md)
* :star:[closure](/web/js/val/func/closure.md) closes over its outer <mark style="color:purple;">**lexical environment**</mark>.
* :star:[declaration](/web/js/grammar/declare.md) determines [scope](/web/js/scope.md)(s) at compile-time.
  * :exclamation:[var](/web/js/variable/declare/var.md) (a statement)
  * :u6307:[const](/web/js/variable/declare/const.md) / [let](/web/js/variable/declare/let.md) (declarations)
* :exclamation:a [for](/web/js/grammar/statement/loop/for/for.md) loop creates a lot of <mark style="color:purple;">**lexical environments**</mark> - see：「 [🖥️ 影片](/web/js/grammar/statement/loop/for/for.md#ying-pian) 」
* :question:[parameter](/web/js/val/func/param.md) / [argument](/web/js/val/func/argument.md) - where are they positioned in the <mark style="color:purple;">**lexical environments**</mark>?
  {% endtab %}

{% tab title="📗 參考" %}

* [ ] JS.info ⟩ [Lexical Environment](https://javascript.info/closure#lexical-environment) ⭐️
* [ ] Anil ⟩ [Scope, Lexical Environment and Scope Chain in JavaScript](https://medium.com/@anilakgunes/scope-lexical-environment-and-scope-chain-in-javascript-559aadb7dca8) ⭐️
* [ ] [YDKJS: Scope & Closures (v.2)](/web/master/ref/book/you-dont-know-js-series-v.2/ydkjs-scope-and-closures-v.2.md) ⟩ Ch. 1
  {% endtab %}

{% tab title="📘 手冊" %}

* [Closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)
* [JS spec](/web/master/ref/js-spec.md) ⟩&#x20;
  * [Lexical Environment](https://262.ecma-international.org/6.0/#sec-lexical-environments)
  * [VariableEnvironment](https://tc39.es/ecma262/#table-additional-state-components-for-ecmascript-code-execution-contexts)
    {% endtab %}

{% tab title="🗣 討論" %}

* [Lexical environment and function scope](https://stackoverflow.com/questions/12599965/lexical-environment-and-function-scope)
* [What is the difference and relationship between execution context and lexical environment?](https://stackoverflow.com/questions/35759544/what-is-the-difference-and-relationship-between-execution-context-and-lexical-en)
* [Where are arguments positioned in the lexical environment?](https://stackoverflow.com/questions/61208843/where-are-arguments-positioned-in-the-lexical-environment) ⭐️
  {% endtab %}

{% tab title="❓" %}
{% hint style="warning" %}
Q：[lexical environment](/web/js/concept/execution-context/lexical-environment.md) === [scope](/web/js/scope.md):question:
{% endhint %}

{% hint style="info" %}
A：my understanding is that&#x20;

* ([global](/web/js/scope/global.md)/[module](/web/js/scope/module.md)/[function](/web/js/scope/function.md)/[block](/web/js/grammar/statement/other/block/block.md)) [scope](/web/js/scope.md) is <mark style="color:yellow;">**determined**</mark> at [compile-time](/web/js/compile/compile-time.md).
* [lexical environment](/web/js/concept/execution-context/lexical-environment.md) is <mark style="color:yellow;">**created**</mark> at [runtime](/web/js/compile/runtime.md), <mark style="color:red;">**every time**</mark>**&#x20;**<mark style="color:yellow;">**a**</mark>**&#x20;**<mark style="color:orange;">**scope**</mark>**&#x20;**<mark style="color:yellow;">**is entered**</mark>:exclamation:
  {% endhint %}
  {% endtab %}
  {% endtabs %}
