# closure

[JS](../..) ⟩ [value](..) ⟩ [function]() ⟩ closure

{% hint style="success" %}
A <mark style="color:purple;">**closure**</mark>&#x20;

* is the <mark style="color:yellow;">**combination**</mark> of a [](<> "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 [lexical-environment](../../concept/execution-context/lexical-environment "mention")).&#x20;
* gives you <mark style="color:yellow;">**access**</mark> to an <mark style="color:yellow;">**outer function**</mark>'s [scope](../../scope "mention") from an <mark style="color:yellow;">**inner function**</mark>.&#x20;
* is <mark style="color:yellow;">**created**</mark>**&#x20;**<mark style="color:orange;">**every time**</mark> a <mark style="color:yellow;">**function**</mark> is created, at function creation time.
{% endhint %}

{% tabs %}
{% tab title="🖥️ 影片" %}
:point\_right: [lexical-environment](../../concept/execution-context/lexical-environment "mention")

{% embed url="https://youtu.be/HuF-qYRnEAo" %}
see how a closure "closes over" outer lexical environments
{% endembed %}
{% endtab %}

{% tab title="⭐️ 重點" %}
{% hint style="info" %}
A <mark style="color:purple;">**closure**</mark> is a function that <mark style="color:yellow;">**remembers**</mark> its <mark style="color:yellow;">**outer variables**</mark> and can access them. in JavaScript, <mark style="color:yellow;">**all functions**</mark> are naturally <mark style="color:purple;">**closures**</mark> (with only one exception :point\_right:  ["new Function" syntax](https://javascript.info/new-function)). 📗 JS.info ⟩ [Closure](https://javascript.info/closure#step-4-returning-a-function)
{% endhint %}

{% hint style="warning" %}
it matters from which [scope](../../scope "mention") your [closure](closure "mention") closes in [variable](../../variable "mention")s.

:point\_right: [scopes-matter-with-closures](closure/scopes-matter-with-closures "mention"):exclamation:
{% endhint %}

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

{% hint style="info" %}
<mark style="color:purple;">**Closure**</mark> is observed <mark style="color:orange;">**when**</mark> a [](<> "mention") uses [variable](../../variable "mention")(s) from <mark style="color:yellow;">**outer**</mark> [scope](../../scope "mention")(s) even <mark style="color:orange;">**while**</mark>**&#x20;**<mark style="color:yellow;">**running in a scope**</mark> <mark style="color:orange;">**where**</mark> those variable(s) wouldn't be accessible. 📗 [You Don't Know JS Yet](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch7.md#observable-definition)
{% endhint %}
{% endtab %}

{% tab title="🔴 主題" %}
* [examples](closure/examples "mention")
  * :exclamation:[scopes-matter-with-closures](closure/scopes-matter-with-closures "mention")
  * :bulb:[private-prop](closure/private-prop "mention")
  * [closure-to-close-over-or-not](closure/examples/closure-to-close-over-or-not "mention")
  * [grades](closure/examples/grades "mention") - closure can be used as a function with private properties.
  * [closure-as-object](closure/examples/closure-as-object "mention") - closure can be used as an object.
* [lexical-environment](../../concept/execution-context/lexical-environment "mention") - stores all local variables.
* [environment](../../concept/execution-context/lexical-environment/environment "mention") - reference to surrounding lexical environment.
{% endtab %}

{% tab title="💈範例" %}
* replit：[closures](https://replit.com/@pegasusroe/closures#index.js)

```javascript
// • `clsr` closes over parameter `a`
//             ╭──clsr──╮
let sum = a => b => a + b ;

sum(3)(4),    // 7
sum(5)(-1),   // 4
```
{% endtab %}

{% tab title="👥 相關" %}
* a [closure](closure "mention") is usually a [nested](kind/nested "mention").
* a [callback](kind/callback "mention") is usually a [closure](closure "mention").
{% endtab %}

{% tab title="📗 參考" %}
* [ ] [ydkjs-scope-and-closures-v.2](../../../master/ref/book/you-dont-know-js-series-v.2/ydkjs-scope-and-closures-v.2 "mention") ⟩ [Ch. 7](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch7.md)
* [x] JS.info ⟩ [Variable scope, closure](https://javascript.info/closure)&#x20;
* [ ] itHome ⟩ [你不可不知的 JavaScript 二三事](https://ithelp.ithome.com.tw/users/20112483/ironman/2016) ⟩&#x20;
  * [ ] [#Day28：閉包 (Closures)](https://ithelp.ithome.com.tw/articles/10209465)
  * [ ] [#Day29：閉包 (Closures) 進階打怪實戰](https://ithelp.ithome.com.tw/articles/10209656)
{% endtab %}

{% tab title="📘 手冊" %}
* [ ] [Closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)
* [ ] [Pratical closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#practical_closures)
{% endtab %}

{% tab title="👥 相關" %}
* every [](<> "mention") (including [iife](expr/iife "mention")) is a <mark style="color:purple;">**closure**</mark>.
* [by-closure](kind/higher/decorator/memoize/by-closure "mention")
{% endtab %}
{% endtabs %}
