> 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/scope.md).

# scope

🚧 under construction

[JS](/web/js.md) ⟩ scope

{% hint style="success" %}
( <mark style="color:yellow;">**visibility**</mark> of [variable](/web/js/variable.md))

the <mark style="color:yellow;">**current context of execution**</mark> in which [value](/web/js/val.md)s and [expression](/web/js/grammar/statement/expr.md)s are "<mark style="color:yellow;">**visible**</mark>" or <mark style="color:yellow;">**can be referenced**</mark>.
{% endhint %}

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

* <mark style="color:yellow;">**concepts about scopes**</mark>
  * [context vs. scope](/web/js/scope/context-vs.-scope.md)
  * [lexical environment vs. scope](/web/js/scope/lexical-environment-vs.-scope.md)
  * [scope chain](/web/js/scope/chain.md)
  * [lexical scope](/web/js/scope/lexical-scope.md) / [dynamic scope](/web/js/scope/dynamic.md) / [static vs. dynamic scoping](/web/js/scope/static-vs-dynamic.md)
  * [lexical environment](/web/js/concept/execution-context/lexical-environment.md) - stores local variables/functions/this.
* <mark style="color:yellow;">**kindes of scopes**</mark>
  * [top-level scope](/web/js/scope/top-level.md) - the scope of a JS file.
  * [global scope](/web/js/scope/global.md)： default scope for all code running <mark style="color:yellow;">**in**</mark>**&#x20;**<mark style="color:orange;">**script mode**</mark>.
  * [module scope](/web/js/scope/module.md)： scope for code running <mark style="color:yellow;">**in**</mark>**&#x20;**<mark style="color:orange;">**module mode**</mark>.
  * [function scope](/web/js/scope/function.md)： scope created with a [function](/web/js/val/func.md).
  * [block scope](/web/js/grammar/statement/other/block/block.md)：scope created with a pair of <mark style="color:yellow;">**curly braces**</mark>. \
    (where [let](/web/js/variable/declare/let.md) / [const](/web/js/variable/declare/const.md) can belong to)
* <mark style="color:red;">**special**</mark>**&#x20;**<mark style="color:yellow;">**scopes**</mark>
  * [function name scope](/web/js/scope/implied.md) - where name of function expression lives in.
  * [parameter scope](/web/js/scope/parameter-scope.md)
  * ["for-init" scope](/web/js/grammar/statement/loop/for/for/for-init-scope.md) - where the for loop initialization variables live in.
* [<mark style="color:yellow;">**hoisting**</mark>](/web/js/scope/hoist.md)
  * [function hoisting](/web/js/scope/hoist/function.md)
  * [var hoisting](/web/js/scope/hoist/variable/var.md)
  * [function expression not hoisted](/web/js/scope/hoist/variable/var/fe-not-hoisted.md)
* <mark style="color:yellow;">**other topics**</mark>
  * [modify current scope at runtime❗️](/web/js/concept/env/js-engine/mode/sloppy-mode/modify-current-scope-at-runtime.md)
  * [eval has its own scope in strict mode](/web/js/concept/env/js-engine/mode/strict-mode/eval-has-its-own-scope-in-strict-mode.md)
    {% endtab %}

{% tab title="⭐️ 重點" %}
{% hint style="warning" %} <mark style="color:purple;">**scopes**</mark> are&#x20;

* <mark style="color:yellow;">**determined**</mark> at [compile-time](/web/js/compile/compile-time.md).&#x20;
* <mark style="color:red;">**but**</mark> ([lexical environment](/web/js/concept/execution-context/lexical-environment.md)) <mark style="color:yellow;">**created**</mark> <mark style="color:red;">**at**</mark> [runtime](/web/js/compile/runtime.md), each time a <mark style="color:purple;">**scope**</mark> is entered.
* <mark style="color:red;">**but in**</mark> [sloppy mode](/web/js/concept/env/js-engine/mode/sloppy-mode.md), you can <mark style="color:red;">**modify**</mark> <mark style="color:purple;">**scope**</mark> (I think the term "scope" is not quite accurate, maybe [lexical environment](/web/js/concept/execution-context/lexical-environment.md):question:) <mark style="color:red;">**at**</mark> [runtime](/web/js/compile/runtime.md). \
  ( 👉 [modify current scope at runtime❗️](/web/js/concept/env/js-engine/mode/sloppy-mode/modify-current-scope-at-runtime.md):exclamation:)
  {% endhint %}

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

{% hint style="warning" %}
[context](/web/js/concept/context.md) <mark style="color:yellow;">**vs.**</mark> [scope](/web/js/scope.md)

* <mark style="color:purple;">**scope**</mark>：<mark style="color:yellow;">**visibility**</mark> of [variable](/web/js/variable.md).&#x20;
* <mark style="color:purple;">**context**</mark>：([this](/web/js/concept/execution-context/this.md)) <mark style="color:yellow;">**object**</mark> to which a [function](/web/js/val/func.md) refers.
  {% endhint %}

{% hint style="info" %}
[top-level scope](/web/js/scope/top-level.md) <mark style="color:yellow;">**vs.**</mark> [global scope](/web/js/scope/global.md)

* [top-level scope](/web/js/scope/top-level.md)： <mark style="color:yellow;">**relative**</mark> to each <mark style="color:yellow;">**JS file**</mark>.
* [global scope](/web/js/scope/global.md)： global absolutely.
  {% endhint %}

{% hint style="warning" %}
in [Node.js](/web/js/concept/env/node.js.md), each <mark style="color:yellow;">**JS file**</mark> is treated as a [module](/web/js/module.md).&#x20;
{% endhint %}

{% hint style="info" %} <mark style="color:yellow;">**inner**</mark> scopes **have access** to <mark style="color:yellow;">**outer**</mark> scopes, but <mark style="color:red;">**not**</mark>**&#x20;**<mark style="color:yellow;">**vice versa**</mark>.
{% endhint %}

{% hint style="info" %}
a [closure](/web/js/val/func/closure.md) (or [IIFE](/web/js/val/func/expr/iife.md)) can be used to create a <mark style="color:purple;">**scope**</mark> to <mark style="color:yellow;">**hide**</mark> [variable](/web/js/variable.md)s/ [function](/web/js/val/func.md)s.
{% endhint %}

{% hint style="danger" %}
if the <mark style="color:yellow;">**code**</mark> you need to <mark style="color:yellow;">**wrap**</mark> a [scope](/web/js/scope.md) <mark style="color:yellow;">**around**</mark> has [return](/web/js/grammar/statement/flow/jump/return.md), [this](/web/js/concept/execution-context/this.md), [break](/web/js/grammar/statement/flow/jump/break.md), or [continue](/web/js/grammar/statement/flow/jump/continue.md) in it, <mark style="color:red;">**don't**</mark>**&#x20;**<mark style="color:yellow;">**use**</mark> a [function](/web/js/val/func.md)/[IIFE](/web/js/val/func/expr/iife.md)(which has <mark style="color:yellow;">**its own**</mark> [function boundary](/web/js/val/func/boundary.md)), use a [block](/web/js/grammar/statement/other/block.md) instead❗️

📗 [You Don't Know JS Yet: Scopes & Closrues](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch6.md#function-boundaries)
{% endhint %}

{% hint style="warning" %}
雖說似乎有一個奇怪的 ["for-init" scope](/web/js/grammar/statement/loop/for/for/for-init-scope.md)，但裡面 [let](/web/js/variable/declare/let.md) 變數的表現其實更像是 [block-scoped](/web/js/grammar/statement/other/block/block.md)。:point\_right: [scopes matter with closures](/web/js/val/func/closure/scopes-matter-with-closures.md) ⟩ [scopes matter with closures](/web/js/val/func/closure/scopes-matter-with-closures.md#undefined-1)
{% endhint %}
{% endtab %}

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

* <mark style="color:purple;">**scopes**</mark> are <mark style="color:yellow;">**determined**</mark> at [compile-time](/web/js/compile/compile-time.md).
* <mark style="color:purple;">**scopes**</mark> are <mark style="color:yellow;">**created**</mark> at [runtime](/web/js/compile/runtime.md).
* in [strict mode](/web/js/concept/env/js-engine/mode/strict-mode.md), script in [eval](/web/js/scope/global/object/eval.md) has its own [scope](/web/js/scope.md).
* [closure](/web/js/val/func/closure.md) ...  🚧
* [lexical environment](/web/js/concept/execution-context/lexical-environment.md)
  {% endtab %}

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

* [ ] Kevin Chisholm ⟩ [What is the Difference Between Scope and Context in JavaScript?](https://blog.kevinchisholm.com/javascript/difference-between-scope-and-context/)
* [ ] [YDKJS: Scope & Closures (v.2)](/web/master/ref/book/you-dont-know-js-series-v.2/ydkjs-scope-and-closures-v.2.md)
* [ ] JS.info ⟩ [Variable scope, closure](https://javascript.info/closure)
* [ ] itHome ⟩ [你不可不知的 JavaScript 二三事](https://ithelp.ithome.com.tw/users/20112483/ironman/2016) ⟩&#x20;
  * [ ] [#Day5：變數作用域 (Scope) (1)](https://ithelp.ithome.com.tw/articles/10203387)
  * [ ] [#Day6：變數作用域 (Scope) (2)](https://ithelp.ithome.com.tw/articles/10203306)
  * [ ] [#Day9：圖解變數作用域 (Scope)](https://ithelp.ithome.com.tw/articles/10204622)
    {% endtab %}

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

* [ ] [Scope](https://developer.mozilla.org/en-US/docs/Glossary/Scope)
  {% endtab %}

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

* [What is the 'global' object in NodeJS](https://stackoverflow.com/a/43630222/5409815)
* [Lexical environment and function scope](https://stackoverflow.com/questions/12599965/lexical-environment-and-function-scope)
  {% endtab %}
  {% endtabs %}
