# lexical environment

[JS](../..) ⟩ [concept](../../../browser/concepts) ⟩ [execution context]() ⟩ lexical environment

{% hint style="success" %}
In JavaScript, <mark style="color:red;">**every**</mark> running [func](../../val/func "mention"), code [block](../../grammar/statement/other/block "mention") <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](lexical-environment/environment-record "mention") – an object that stores&#x20;
  * all <mark style="color:yellow;">**local**</mark> [variable](../../variable "mention")(s) as its [<mark style="color:orange;">**properties**</mark>](../../val/obj/prop).
  * <mark style="color:yellow;">**other information**</mark> like the value of [this](this "mention").&#x20;
* A [**reference**](lexical-environment/environment) 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](lexical-environment/environment-record "mention") - stores local variables/this ...
* :small\_orange\_diamond:[environment](lexical-environment/environment "mention") - reference to lexical environment where a function was made.
* :exclamation:[optimize](lexical-environment/optimize "mention")
* :scales:[lexical-environment-vs.-scope](../../scope/lexical-environment-vs.-scope "mention")
* :star:[closure](../../val/func/closure "mention") - function that can access its outer lexical environment.
* :exclamation:[modify-current-scope-at-runtime](../env/js-engine/mode/sloppy-mode/modify-current-scope-at-runtime "mention") - (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&#x26;token=4aa199a3-a217-4f06-9941-bd01be4e0e92" alt="lexical environment" class="gitbook-drawing">
{% endtab %}

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

{% hint style="success" %}
A [closure](../../val/func/closure "mention") is the <mark style="color:yellow;">**combination**</mark> of a [func](../../val/func "mention") <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" %}
[compile](../../compile "mention") creates a <mark style="color:yellow;">**map**</mark> of all the [lexical-scope](../../scope/lexical-scope "mention")s ... you can think of this plan as inserted code for use at [runtime](../../compile/runtime "mention"), 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 [id](../../grammar/token/id "mention")s ([variable](../../variable "mention")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](../../scope "mention") of a <mark style="color:yellow;">**code block**</mark> can reach all its <mark style="color:yellow;">**parent's**</mark> [lexical-environment](lexical-environment "mention") so it can use its parent’s [variable](../../variable "mention")(s). In this way, we have a [chain](../../scope/chain "mention"), chain of all parent’s [scope](../../scope "mention").


{% endhint %}
{% endtab %}

{% tab title="👥 相關" %}
* :scales:[lexical-environment-vs.-scope](../../scope/lexical-environment-vs.-scope "mention")
* :scales:[chain](../../scope/chain "mention") is similar to <mark style="color:purple;">**lexical environments**</mark>.
* :star:<mark style="color:purple;">**lexical environment**</mark> is part of [](<> "mention").
* :exclamation:[this-determined-on-call-site](this/this-determined-on-call-site "mention")
* :star:[closure](../../val/func/closure "mention") closes over its outer <mark style="color:purple;">**lexical environment**</mark>.
* :star:[declare](../../grammar/declare "mention") determines [scope](../../scope "mention")(s) at compile-time.
  * :exclamation:[var](../../variable/declare/var "mention") (a statement)
  * :u6307:[const](../../variable/declare/const "mention") / [let](../../variable/declare/let "mention") (declarations)
* :exclamation:a [for](../../grammar/statement/loop/for/for "mention") loop creates a lot of <mark style="color:purple;">**lexical environments**</mark> - see：「 [🖥️ 影片](../../../grammar/statement/loop/for/for#ying-pian) 」
* :question:[param](../../val/func/param "mention") / [argument](../../val/func/argument "mention") - 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-and-closures-v.2](../../../master/ref/book/you-dont-know-js-series-v.2/ydkjs-scope-and-closures-v.2 "mention") ⟩ Ch. 1
{% endtab %}

{% tab title="📘 手冊" %}
* [Closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)
* [js-spec](../../../master/ref/js-spec "mention") ⟩&#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](lexical-environment "mention") === [scope](../../scope "mention"):question:
{% endhint %}

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

* ([global](../../scope/global)/[module](../../scope/module)/[function](../../scope/function)/[block](../../grammar/statement/other/block/block)) [scope](../../scope "mention") is <mark style="color:yellow;">**determined**</mark> at [compile-time](../../compile/compile-time "mention").
* [lexical-environment](lexical-environment "mention") is <mark style="color:yellow;">**created**</mark> at [runtime](../../compile/runtime "mention"), <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 %}
