❗var can shadow parameter even in strict mode❗️
🚧 under construction
JS ⟩ variable ⟩ shadowing ⟩ var can shadow parameter even in strict mode.
⭐ function declaration instantiation
When an execution context is established for evaluating an ECMAScript function:
a new Function Environment Record is created and bindings for each formal parameter are instantiated in that Environment Record.
Each declaration in the function body is also instantiated.
If the function's formal parameters do not include any default value initializers then the body declarations are instantiated in the same Environment Record as the parameters ❗
If default value initializers exist, a second Environment Record is created for the body declarations ❗
Formal parameters and functions are initialized as part of FunctionDeclarationInstantiation. All other bindings are initialized during evaluation of the function body.
replit:shadowing parameters
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)Last updated
Was this helpful?