> 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/variable/declare/var/param-by-var.md).

# var can shadow parameter even in strict mode❗️

[JS](/web/js.md) ⟩ [variable](/web/js/variable.md) ⟩ [shadowing](/web/js/variable/shadow.md) ⟩ var can shadow parameter even in strict mode.

{% hint style="warning" %}
[parameter](/web/js/val/func/param.md)(s) <mark style="color:yellow;">**can be shadowed**</mark> by [var](/web/js/variable/declare/var.md):exclamation:
{% endhint %}

{% tabs %}
{% tab title="⭐️ 重點" %}
{% hint style="success" %}
:star: [function declaration](/web/js/val/func/declare.md) <mark style="color:yellow;">**instantiation**</mark>

When an [execution context](https://tc39.es/ecma262/#sec-execution-contexts) is established for evaluating an ECMAScript [function](/web/js/val/func.md)：

* a new [Function Environment Record](https://tc39.es/ecma262/#sec-function-environment-records) is created and bindings for each <mark style="color:yellow;">**formal parameter**</mark> are instantiated in that [Environment Record](https://tc39.es/ecma262/#sec-environment-records).&#x20;
* Each [declaration](/web/js/grammar/declare.md) in the <mark style="color:yellow;">**function body**</mark> is also instantiated.&#x20;
* If the function's <mark style="color:yellow;">**formal parameters**</mark> <mark style="color:red;">**do not**</mark>**&#x20;**<mark style="color:yellow;">**include**</mark> any <mark style="color:yellow;">**default value initializers**</mark> then the <mark style="color:orange;">**body declarations**</mark> are instantiated in the <mark style="color:red;">**same**</mark> [Environment Record](https://tc39.es/ecma262/#sec-environment-records) as the <mark style="color:orange;">**parameters**</mark> :exclamation:
* If <mark style="color:yellow;">**default value initializers**</mark>**&#x20;exist**, a <mark style="color:red;">**second**</mark> [Environment Record](https://tc39.es/ecma262/#sec-environment-records) is created for the <mark style="color:yellow;">**body declarations**</mark> :exclamation:
* Formal <mark style="color:yellow;">**parameters**</mark> and <mark style="color:yellow;">**functions**</mark> are initialized as <mark style="color:yellow;">**part**</mark> of [FunctionDeclarationInstantiation](https://tc39.es/ecma262/#sec-functiondeclarationinstantiation). All <mark style="color:yellow;">**other bindings**</mark> are initialized during <mark style="color:yellow;">**evaluation**</mark> of the <mark style="color:yellow;">**function body**</mark>.

📘 [JS spec](/web/master/ref/js-spec.md) ⟩ [FunctionDeclarationInstantiation](https://tc39.es/ecma262/#sec-functiondeclarationinstantiation)
{% endhint %}
{% endtab %}

{% tab title="💈範例" %}

* replit：[shadowing parameters](https://replit.com/@pegasusroe/shadowing-parameters#index.js)

```javascript
const { log } = console;

let count = 0;

// (*)
// ⭐ "initialization block" in a for-loop
// ---------------------------------------
//   ╭──init───╮
for ( let i = 0 ; i < 3 ; i++ ) {

    // ⭐ for-loop body (block scope) and the "initialization block"
    //    are in different scopes, so we can "shadow" the outer `i`
    //    with a local "let" without any problem.
    let i = 1;
    
    log(i);                    // 1, 1, 1
    if (++count > 3) break;    // prevent infinite loop
}

// ⭐ case 1: (alters parameter directly)
// ---------------------------------------
// • parameter `id` is closed over by `defaultID`.
//
//                ╭─── parameter list ───╮
function doUpdate(id, defaultID = () => id) {
    id = 5;                  // ✅ parameter `id` updated (see (**) below)
    log( defaultID() );
}

// (**)
doUpdate(3);                 // ✅ 5

// ⭐ case 2: (shadows parameter by local "var")
// ----------------------------------------------
//
//                    ╭─── parameter list ───╮
function doesntUpdate(id, defaultID = () => id) {

    // ----------------------0
    //  ❓ weird situation ❓
    // ----------------------0
    
    // ❗ 2.1: can't shadow parameters by "let" variables
    // ----------------------------------------------------------
    // let id = 5;
    //     ^^
    // ⛔ SyntaxError: Identifier 'id' has already been declared
    // ----------------------------------------------------------

    log( defaultID() );      // 3

    // ⭐ 2.2 use "var" instead:
    // -------------------------
    
    var id = 5;              // ❗ this do shadow parameter `id`
    log(id);                 // 5

    log( defaultID() );      // 3
    
    // ----------------------------------------------------------------
    // ⭐ are "parameter list" and "function body" in the same scope ❓
    // ----------------------------------------------------------------
    //
    //   • if so, `var id = 5` should be considered a "redeclaration",
    //     parameter `id` should be updated by the redeclaration, 
    //     but it's NOT, why ❓   (see: (***) below)
    //     (Q: is parameter `i` a "var" ?) 
    // 
    //   • if they're not in the same scope, why can't we shadow 
    //     the (outer) parameter `id` with a local "let", like we
    //     do in a "for-loop"❓  (see: (*) above)
    //
    // ----------------------------------------------------------------

}

// (***)
doesntUpdate(3);             // ❗ (parameter `id` is not updated)
```

{% endtab %}

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

* [JS spec](/web/master/ref/js-spec.md) ⟩&#x20;
  * [FunctionDeclarationInstantiation](https://tc39.es/ecma262/#sec-functiondeclarationinstantiation)
  * [Function Environment Record](https://tc39.es/ecma262/#sec-function-environment-records)
    {% endtab %}

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

* [for](/web/js/grammar/statement/loop/for/for.md) loop
* [closure](/web/js/val/func/closure.md)
* [lexical environment](/web/js/concept/execution-context/lexical-environment.md)
* [parameter](/web/js/val/func/param.md) / [argument](/web/js/val/func/argument.md)
* [strict mode](/web/js/concept/env/js-engine/mode/strict-mode.md)
* :white\_check\_mark:[let can't shadow parameter even in sloppy mode❗️](/web/js/variable/declare/let/let-cant-shadow-param.md)
  {% endtab %}

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

* [shadowing parameters by local variables?](https://stackoverflow.com/questions/74154964/shadowing-parameters-by-local-variables) (my question)
* [Where are arguments positioned in the lexical environment?](https://stackoverflow.com/questions/61208843/where-are-arguments-positioned-in-the-lexical-environment) ⭐️
  {% endtab %}

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

* [ ] [YDKJS: Scope & Closures (v.2)](/web/master/ref/book/you-dont-know-js-series-v.2/ydkjs-scope-and-closures-v.2.md) ⟩ Ch. 8 ⟩ [Parameter Scope](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/apA.md#parameter-scope)
  {% endtab %}

{% tab title="🚧" %}

* [ ] Function Environment Record
* [x] formal parameter === parameter
* [ ] function body
* [ ] default value initializer
  {% endtab %}
  {% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lochiwei.gitbook.io/web/js/variable/declare/var/param-by-var.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
