---
description: 🚧 under construction
---

# var can shadow parameter even in strict mode❗️

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

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

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

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

* 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 [declare](../../../grammar/declare "mention") 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](../../../../master/ref/js-spec "mention") ⟩ [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](../../../../master/ref/js-spec "mention") ⟩&#x20;
  * [FunctionDeclarationInstantiation](https://tc39.es/ecma262/#sec-functiondeclarationinstantiation)
  * [Function Environment Record](https://tc39.es/ecma262/#sec-function-environment-records)
{% endtab %}

{% tab title="👥 相關" %}
* [for](../../../grammar/statement/loop/for/for "mention") loop
* [closure](../../../val/func/closure "mention")
* [lexical-environment](../../../concept/execution-context/lexical-environment "mention")
* [param](../../../val/func/param "mention") / [argument](../../../val/func/argument "mention")
* [strict-mode](../../../concept/env/js-engine/mode/strict-mode "mention")
* :white\_check\_mark:[let-cant-shadow-param](../let/let-cant-shadow-param "mention")
{% 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-and-closures-v.2](../../../../master/ref/book/you-dont-know-js-series-v.2/ydkjs-scope-and-closures-v.2 "mention") ⟩ 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 %}
