Fact-checked by Grok 2 weeks ago

Variable shadowing

Variable shadowing is a scoping phenomenon in computer programming where a variable declared in an inner scope shares the same name as a variable in an outer enclosing scope, causing the inner variable to hide or obscure the outer one from access within that inner scope. This behavior is common across many programming languages, including , , , C++, and , and arises due to lexical scoping rules that prioritize the most recent declaration in the current scope. In practice, variable shadowing typically occurs in nested blocks, functions, or class methods, where the inner declaration takes precedence for name resolution, but the outer variable remains accessible if explicitly referenced (e.g., via qualifiers in some languages). For instance, in , a local variable can shadow a class field of the same name, leading to a compile-time error only if the shadowing declaration attempts to reuse the name invalidly within the same scope. Similarly, in , shadowing can apply to inherited elements using the Shadows keyword, allowing a derived class to redefine and hide a base class member without polymorphism. While variable shadowing enables flexible code organization—such as temporarily redefining variables for specific computations—it can introduce subtle bugs if developers unintentionally refer to the wrong variable, especially in languages without strict scoping enforcement like early JavaScript versions before let and const. In modern , let and const declarations use block scoping to shadow outer variables throughout the inner scope and introduce a temporal dead zone that prevents access to the inner variable before its declaration, enhancing predictability by avoiding the hoisting behaviors of var. Languages like C++ and permit shadowing freely but recommend avoiding it in favor of distinct names to improve and reduce errors. Distinguishing variable shadowing from related concepts is crucial: unlike in , which involves runtime polymorphism for behavior substitution, shadowing is a compile-time name-hiding mechanism that does not invoke the hidden element. This static resolution makes shadowing useful for encapsulation but requires careful design to avoid masking important outer variables, such as built-ins or globals.

Fundamentals

Definition

Variable shadowing occurs when a variable declared in an inner has the same name as a variable in an outer enclosing , rendering the outer variable inaccessible within the inner through that name. This mechanism is enabled primarily by lexical scoping, where name resolution depends on the static structure of the code rather than runtime execution. In terms of basic mechanics, references to the name within the inner resolve to the inner , while the outer persists unchanged and regains accessibility via the shared name once the inner concludes. The inner effectively hides the outer one without altering its value or lifetime, allowing temporary name reuse in nested contexts. The concept of variable shadowing emerged with the introduction of block-structured languages in the 1960s, notably , which formalized nested blocks and local declarations that permit redeclaration of identifiers in inner scopes. This allowed for modular code organization through scoped name reuse, influencing subsequent languages with similar scoping rules. To illustrate, consider the following pseudocode:
outer block:
  declare x = 1
  print(x)  // outputs 1
  inner block:
    declare x = 2
    print(x)  // outputs 2
  print(x)  // outputs 1
Here, the inner x shadows the outer one during the inner block's execution.

Relation to Variable Hiding

Variable hiding is a general concept in programming languages referring to the mechanism by which a declaration in an inner or derived scope obscures access to another declaration with the same name in an outer or base scope. This obscuration creates a "hole" in the visibility of the outer declaration, making it inaccessible without explicit qualification in the inner scope. A key distinction lies in the : variable shadowing specifically pertains to declarations of the same type—typically —in nested scopes, such as a within a obscuring a global or enclosing one, without involving polymorphic behavior or inheritance hierarchies. In contrast, variable hiding extends to broader scenarios, including or -level obscurations in , where a member in a derived class may hide a member from the base class, regardless of type compatibility. The concepts overlap significantly in non-object-oriented contexts, where shadowing serves as a primary form of hiding, temporarily overriding outer bindings during name resolution in static scoping rules. However, in object-oriented languages, hiding more commonly denotes the inheritance-specific case, such as when a subclass or static conceals an identically named in the superclass, resolved at rather than . For instance, in C++, a declared in an inner block shadows (or hides) an outer of the same name, limiting access to the inner one within that block. Separately, in , a derived member with the same name as a member hides the base version entirely, even if signatures differ, unless using directives or qualifiers bring the base into .

Scoping Mechanisms

Lexical Scoping

Lexical scoping, also known as static scoping, determines the scope and visibility of based on their position within the static structure of the source code, particularly the nesting of blocks or functions, with resolution occurring at compile-time rather than relying on the . This static resolution enables variable shadowing by prioritizing declarations in inner over those in enclosing outer through a hierarchical lookup process: when a is referenced, the searches from the innermost outward until a matching declaration is found, allowing the inner to mask the outer one locally. Unlike dynamic scoping, which resolves variables based on the active calling context at runtime and can produce varying results depending on execution paths, lexical scoping ensures consistent behavior tied to code layout; dynamic scoping is uncommon in contemporary languages, whereas lexical scoping serves as the standard in languages like and . Introduced in as a key innovation for nested functions, lexical scoping gained widespread adoption in later languages due to its efficiency in permitting compile-time analysis and eliminating the runtime overhead of dynamic lookups.

Name Resolution

Name resolution in the presence of variable shadowing operates within the framework of lexical scoping, where the binding of a name is determined by its position in the program's static structure. The algorithm for resolving a variable reference begins by searching the current scope for a declaration of the name. If found, the reference binds to that local declaration. If not, the search continues in the immediately enclosing outer scope, proceeding recursively through the hierarchy of nested scopes until a matching declaration is located or the outermost (global) scope is exhausted, resulting in a resolution error if the name remains unbound. This process ensures that bindings are resolved statically at compile time in most languages supporting lexical scoping. Variable shadowing directly influences this resolution by prioritizing inner-scope declarations. Upon encountering a local declaration of a name already bound in an outer scope, the lookup terminates at the inner declaration, binding all subsequent references within that scope to the new variable while leaving the outer binding intact for references outside the shadowing scope. This mechanism allows inner scopes to introduce local variables without altering the visibility of outer ones, effectively "hiding" the outer binding temporarily without deactivation. The shadowing declaration does not override or modify the outer variable; it simply intercepts lookups originating from within its scope. Edge cases in name resolution highlight variations across languages. In cases of forward references to a shadowed variable (use before its declaration in the scope), the reference binds to the local variable, often resulting in an error such as accessing an uninitialized or unbound variable, because the local declaration applies to the entire scope. For example, in Python this raises an UnboundLocalError, in C it is a compile-time error for use before declaration, and in JavaScript with let or const it triggers a ReferenceError due to the temporal dead zone. Redeclaration within the same scope typically leads to an error in most languages to avoid ambiguities, where multiple bindings for the same name could exist. The resolution process can be formalized in pseudocode as a recursive function that traverses the scope chain:
function resolve(name, current_scope):
    if current_scope.has_declaration(name):
        return current_scope.get_binding(name)
    else if current_scope.has_outer():
        return resolve(name, current_scope.outer)
    else:
        raise NameError("Unresolved name: " + name)
This captures the outward traversal until a binding is found or an error is raised, with shadowing enforced by the initial local check.

Implications

Advantages

Variable shadowing enhances code modularity by permitting the declaration of local variables that reuse names from outer scopes, thereby isolating them and preventing pollution of broader namespaces. This mechanism allows developers to employ familiar identifiers, such as loop counters, in nested or independent code blocks without risking interference with global or enclosing variables, fostering reusable and self-contained modules. By confining variable visibility to specific contexts, shadowing improves readability in extended functions or programs, as it minimizes the of tracking numerous unique names across large scopes. Local names remain relevant only where needed, reducing visual clutter and enabling clearer focus on the logic within each without constant to distant declarations. In terms of , shadowing supports direct to local variables without the overhead of qualified references, such as prefixes required for instance members in object-oriented designs, resulting in more concise . Local variables, typically allocated on the , offer faster access times compared to or instance variables stored in segments or heaps, with benchmarks showing access speeds over 200% faster in some implementations. Historically, in pioneering block-structured languages like , variable shadowing through block structure allowed local declarations within nested blocks to hide outer ones, thus avoiding name conflicts.

Disadvantages

Variable shadowing can lead to unintended bugs when developers accidentally declare a new variable in an inner scope that hides an outer one, causing modifications or references to affect the wrong variable and resulting in subtle, hard-to-debug errors. For instance, in nested functions or loops, the shadowed variable may prevent access to the intended outer variable, leading to logical inconsistencies that are not immediately apparent during or testing. During , overlooked shadowing can break access to outer variables, complicating maintenance efforts in evolving codebases as changes in one scope unexpectedly impact others. This issue is particularly pronounced when renaming or restructuring scopes, where maintainers may inadvertently alter the visibility of shadowed names, requiring extensive retesting to identify regressions. In large codebases, variable shadowing reduces readability by obscuring the programmer's intent, especially when similar names are used across multiple scopes, making it difficult to track which declaration is active without careful scope analysis. This confusion can slow down onboarding for new developers and increase the cognitive load during debugging or collaboration. To mitigate these risks, developers should use distinct variable names to avoid accidental overlaps, employ linters such as ESLint's no-shadow rule to flag potential shadowing during development, and enable compiler warnings like GCC's -Wshadow option for early detection. Additionally, integrated development environments (IDEs) like Visual Studio Code and IntelliJ IDEA provide built-in warnings for shadowing through configurable linting extensions, helping enforce best practices in modern workflows since the mid-2010s.

Examples

Lua

In Lua, variables are global by default unless explicitly declared as local using the local keyword, and local variables are scoped to the block in which they are declared, such as a function body, control structure, or explicit do-end block. Local variables shadow any global variables or outer local variables with the same name within their scope, meaning references to that name inside the block resolve to the local variable rather than the outer one. This shadowing behavior follows Lua's lexical scoping rules, where name resolution occurs based on the textual structure of the code. Lua's closure mechanism involves upvalues, which are references to local variables from an outer that an inner accesses after the outer has ended. When an inner is defined inside a scope where a is shadowed by another local with the same name, the inner captures the shadowed local as an upvalue if it references that name, effectively hiding the outer variable from direct access within the . However, upvalues allow the to maintain access to the intended outer locals despite intermediate shadowing in the code structure. The following example demonstrates basic shadowing with local variables in Lua:
lua
local x = 1
do
  local x = 2
  print(x)  -- Outputs: 2 (the inner local shadows the outer)
end
print(x)    -- Outputs: 1 (back to the outer local)
This code shows how the inner local x temporarily hides the outer one within the do-end block, but the outer value remains unchanged outside it. Starting with Lua 5.2, the language provides explicit control over upvalues through the debug library, including functions like lua_upvaluejoin that allow joining or sharing upvalues between closures, enabling developers to manipulate access to outer variables and potentially bypass the effects of shadowing in more advanced scenarios.

Python

In , variables follow lexical scoping, where a in an inner shadows a of the same name in an enclosing outer . When an assignment is made to a within a , treats it as a by default, creating a new binding that hides the outer unless explicitly declared otherwise. This shadowing mechanism ensures that inner scopes do not inadvertently modify outer variables without intent, promoting predictable name resolution during execution. In nested functions, this shadowing becomes particularly relevant: defining a in an inner creates a local that shadows the enclosing 's of the same name. To modify the enclosing instead, the nonlocal keyword must be used to bind the name to the nearest enclosing excluding the . Without nonlocal, any assignment in the inner would create a new local, leaving the outer unchanged. For instance, consider the following code:
python
x = 1  # [Global variable](/page/Global_variable)

def outer():
    x = 2  # Local to outer, shadows global x
    def inner():
        nonlocal x  # Binds to outer's x
        x = 3
    inner()
    [print](/page/Print)(x)  # Outputs: 3

outer()
Here, the inner() call modifies the x from the outer scope to 3, demonstrating how nonlocal pierces the local shadowing to enable updates in nested contexts. This approach can lead to accidental locals shadowing outer variables if nonlocal is omitted, a common pitfall in closure-like patterns. The nonlocal keyword was introduced in Python 3.0 in 2008 via PEP 3104 to address limitations in handling outer scope modifications, resolving frequent issues with variable shadowing in nested functions that plagued 2.x code. Prior to this, developers often resorted to workarounds like mutable objects (e.g., lists) to simulate outer variable changes, but nonlocal provides a direct, declarative solution for rebinding names in enclosing scopes. This evolution enhances 's support for paradigms, such as closures, by making scope interactions more explicit and less error-prone.

Rust

In , variable shadowing is a deliberate language feature that permits declaring a new with the same name as an existing one using the let keyword, thereby creating a fresh that obscures the prior one within the enclosing . This approach differs from , as it generates an entirely new immutable by default, enabling developers to rebind names without altering the original value's or requiring the mut keyword. Shadowing facilitates type changes—for instance, transforming a slice into its as a usize—and supports value transformations, such as incrementing or reformatting data, while upholding 's emphasis on immutability. The scoping of shadowed variables is strictly lexical and block-bound, confined to the {} delimiters of the current ; upon exiting the , the outer resumes accessibility unchanged, and transfers or mutations within the inner do not propagate outward. This containment aligns with Rust's semantics, where shadowing can introduce new bindings that effectively drop prior borrows, allowing safe reborrowing without violating guarantees. Rust documentation highlights shadowing's utility in avoiding unnecessary mutable declarations, which could otherwise invite borrow checker conflicts during reassignment. The following code exemplifies shadowing's mechanics, including type inference and block isolation:
rust
fn main() {
    let x = 5;                    // x binds to i32 value 5
    let x = x + 1;                // New binding shadows prior x, now i32 value 6
    println!("Outer x: {}", x);   // Outputs: Outer x: 6

    {
        let x = "shadowed";       // Inner binding shadows x within block (now &str)
        println!("Inner x: {}", x); // Outputs: Inner x: shadowed
    }
    println!("Outer x after block: {}", x); // Outputs: Outer x after block: 6
}
In this example, the inner shadowing temporarily hides the outer x but leaves it intact post-block, demonstrating non-interference with outer scope state. Rust promotes shadowing for enhancing code clarity, particularly in sequential value transformations like parsing inputs, where it obviates mutable reassignments that might clash with concurrent borrows. Nonetheless, the borrow checker enforces strict rules during shadowing: if the inner binding involves a borrow of the outer variable, mutable access to the outer remains prohibited for the duration of the inner scope to avert aliasing violations, triggering a compile-time error (e.g., E0502) if attempted. This integration ensures shadowing aids safe refactoring without compromising Rust's thread-safety invariants.

C++

In C++, variable shadowing, also known as name hiding, occurs when a declaration in an inner obscures a declaration of the same name in an outer , preventing unqualified access to the outer entity within the inner . This behavior is governed by the language's scoping rules, which include block , namespace , and class . In block , a variable declared within curly braces {} hides any identically named variable from enclosing blocks or the global , with the inner variable taking precedence for all unqualified uses until the block ends. For instance, the following code demonstrates this:
cpp
#include <iostream>

int main() {
    int x = 1;
    {
        int x = 2;
        std::cout << x << std::endl;  // Outputs 2 (inner x shadows outer x)
    }
    std::cout << x << std::endl;  // Outputs 1 (outer x is accessible after inner block ends)
    return 0;
}
This example illustrates how the inner x temporarily hides the outer one, restoring access to the outer variable upon exiting the block. In namespace scope, declarations within an inner namespace can shadow those in an enclosing or global namespace, but the global scope operator :: or qualified names allow access to the hidden entities. For example, a variable foo declared in namespace N { int foo; } would hide a global int foo unless explicitly referenced as ::foo. An exception arises with argument-dependent lookup (ADL), which extends name resolution for functions and operators to associated namespaces of argument types, potentially finding hidden names that standard unqualified lookup would miss; however, this does not apply to variables, where hiding remains strict. Within class scope, particularly in inheritance hierarchies, a member variable in a derived class can shadow a member variable of the same name in its base class, limiting access to the base member without qualification. To resolve the shadowed base member, qualifiers such as Base::member or this->member (if the name conflicts with a local or ) are required. This hiding extends to or namespace variables shadowed by class members, emphasizing C++'s preference for explicit qualification to disambiguate. Since , lambda expressions introduce their own and support capture clauses that bind outer variables by value or , enabling access to enclosing names without introducing shadowing conflicts in the lambda body or relying on qualifiers.

Java

In , variable shadowing adheres to strict lexical scoping, where the scope of a declaration is the region of the program text within which uses of the declared name refer to that declaration. Local variables declared within a or constructor can shadow instance fields or static fields of the enclosing , meaning the local variable takes precedence in name resolution within its scope. This behavior is defined in the Java Language Specification (JLS), ensuring that inner scopes do not unexpectedly access outer declarations without explicit qualification. To access a shadowed instance from within a , the this keyword must be used to qualify the field name, disambiguating it from the local variable. For example, in a static , a local variable can shadow a static of the , and the field must be accessed via the name (e.g., ClassName.field) if needed. However, prohibits shadowing of parameters by local variables within the same body, treating such attempts as a compile-time error to prevent confusion and unintended redeclarations. This rule applies similarly to exception parameters and formal parameters in constructors. The following code illustrates local variable shadowing of an instance field:
java
class C {
    int x = 1;
    
    void m() {
        int x = 2;
        System.out.println(x);      // Outputs: 2 (local variable)
        System.out.println(this.x); // Outputs: 1 (instance field)
    }
}
In this example, the local x shadows the instance field x within the method m(), but this.x explicitly refers to the field. This design promotes clarity in object-oriented programming by encouraging explicit access to shadowed members, contributing to modularity as discussed in broader implications of shadowing.

JavaScript

In , variable shadowing occurs when a variable declared in an inner has the same name as a variable in an outer , temporarily hiding the outer variable during the inner 's execution. With the var keyword, variables are function-scoped and hoisted to the top of their containing or global , allowing redeclaration that shadows and overrides any outer var with the same name in the same . For example:
javascript
var x = 1;
if (true) {
  var x = 2;  // Redeclares and shadows the outer x
}
console.log(x);  // Outputs: 2 (outer x is overwritten due to function scope)
This behavior stems from var's lack of block scoping, where declarations inside blocks like if statements still hoist to the function level. In contrast, let and const—introduced in ECMAScript 2015—provide block scoping, meaning they are confined to the nearest enclosing block (such as {} braces), and they shadow outer variables without hoisting their initialization, enforcing a temporal dead zone (TDZ). The TDZ is the period from the start of the block until the declaration line, during which accessing the variable throws a ReferenceError, preventing use before declaration. Redeclaration of let or const in the same scope is not allowed, but shadowing an outer variable creates a distinct inner . For instance:
javascript
let x = 1;
{
  let x = 2;  // Shadows outer x in this block
  console.log(x);  // Outputs: 2
}
console.log(x);  // Outputs: 1 (outer x unchanged)
Attempting to access the inner x before its declaration within the block would trigger a TDZ error. The introduction of block scoping with let and const in ECMAScript 2015 addressed longstanding issues with var's function scoping, such as unintended variable leakage and shadowing bugs in loops or conditionals, marking a significant evolution in 's variable handling. This change promotes safer code by reducing surprises from hoisting and enabling true lexical scoping in s.

References

  1. [1]
    Chapter 6. Names - Oracle Help Center
    Jan 21, 1996 · Attempted Shadowing Of A Local Variable. Because a declaration of an identifier as a local variable of a method, constructor, or initializer ...
  2. [2]
    JavaScript language overview - MDN Web Docs
    Oct 30, 2025 · A variable declaration without ... This has some interesting interactions with variable shadowing, which don't occur in other languages.
  3. [3]
    Shadowing - Visual Basic | Microsoft Learn
    Sep 15, 2021 · When two programming elements share the same name, one of them can hide, or shadow, the other one. In such a situation, the shadowed element is not available ...
  4. [4]
    Variable Shadowing in C++ - GeeksforGeeks
    Jul 23, 2025 · Variable shadowing is a common programming concept where a variable declared in some specific scope takes precedence over a variable with the same name ...
  5. [5]
    Variable Shadowing in Python - GeeksforGeeks
    Jul 23, 2025 · Variable shadowing occurs when a variable defined in the inner scope has the same name as a variable in the outer scope.
  6. [6]
    Differences Between Shadowing and Overriding - Visual Basic
    Sep 15, 2021 · Shadowing and overriding are both used when a derived class inherits from a base class, and both redefine one declared element with another.
  7. [7]
    [PDF] CSE 341: Programming Languages - Washington
    multiple variable bindings to the same variable name is called “shadowing”. • affects both static and dynamic environments.
  8. [8]
    [PDF] Semantic Analysis Introduction with Emphasis on Name Analysis
    – Shadowing. • Variable shadowing allowed. • Struct definition shadowing allowed. 20 int a; void fun(){ int b; b = 0; if (b == 0){ int b; b = 1;. } c = b ...
  9. [9]
    [PDF] ALGOL 60 - Software Preservation Group
    This document constitutes the definition of the programming language. ALGOL 60, as established by the Internatonal Federation for Information. Processing, in an ...<|control11|><|separator|>
  10. [10]
    Block Structured Procedural and Object Based
    Block structured procedural languages use constants and variables which can be structured to represent many real world entities. The earliest version, ALGOL 60, ...<|control11|><|separator|>
  11. [11]
    Scope
    C++ allows you to create a variable inside a compound statement that has the same name as another variable that is defined outside of that compound statement.
  12. [12]
    None
    ### Summary of Name Hiding, Shadowing, and Variable Hiding in Scoping (Chapter 3)
  13. [13]
  14. [14]
    Hiding Fields - Java™ Tutorials
    Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different.
  15. [15]
    Lexical Scoping - an overview | ScienceDirect Topics
    Lexical scoping is a programming concept where the scope of a variable is determined by its closest surrounding scope in the code. In lexical scoping ...
  16. [16]
    Lexical and Dynamic Scope - Programming Research Laboratory
    Sep 5, 2019 · Under dynamic scoping, a variable is bound to the most recent value assigned to that variable, i.e., the most recent assignment during the ...
  17. [17]
    Static and Dynamic Scoping - GeeksforGeeks
    Sep 14, 2024 · It can lead to faster execution because the scope of variables can be determined at compile-time, which eliminates the need for runtime lookups.
  18. [18]
    Lexical vs Dynamic Scoping - Aditya Yadav
    Oct 31, 2025 · Lexical scoping means a function remembers where it was born; Dynamic scoping means a function adapts to who's calling it. 10. Key Takeaway for ...Missing: advantages | Show results with:advantages
  19. [19]
    Why ALGOL was an important programming language? - Bulldogjob
    ALGOL was the first language to allow the definition of nested functions, which had their lexical scope. The authors of the report recommended implementing ...
  20. [20]
    [PDF] A Theory of Name Resolution - Creating Web Pages in your Account
    In languages with lexical scoping, the redeclaration of a variable inside a nested region typically hides the outer declaration. Thus, the duplicate declaration ...
  21. [21]
    [PDF] Names, Scopes, and Bindings
    17-363/17-663: Programming Language Pragmatics. Reading: PLP chapter 3. Page 2 ... – (temporary) deactivation/shadowing of bindings. – reactivation of ...
  22. [22]
    [PDF] Revised report on the algorithm language ALGOL 60
    The present report represents the union of the Committee's concepts and the intersection of its agreements. April 1962 Conference [Edited by M. Woodger]. A ...
  23. [23]
    [PDF] Block-structured procedural languages Algol and Pascal
    Each block has a characteristic structure: a header giving the specification of parameters and results, followed by constant definitions, type definitions, ...
  24. [24]
    Java dynamic LVT optimization - ACM Digital Library
    programmer, local variables are the clear winner where performance is critical. Compared to instance variables, local variables can be accessed over 200% faster ...
  25. [25]
    no-shadow - ESLint - Pluggable JavaScript Linter
    The no-shadow rule disallows variable declarations from shadowing variables in outer scopes, aiming to eliminate shadowed variable declarations.Rule Details · Options · hoist · ignoreTypeValueShadowMissing: documentation | Show results with:documentation
  26. [26]
  27. [27]
    Variables should not be shadowed - CAST Highlight
    Overriding a variable declared in an outer scope can strongly impact the readability, and therefore the maintainability, of a piece of code.
  28. [28]
  29. [29]
    Programming in Lua : 4.2 - Local Variables and Blocks
    Unlike global variables, local variables have their scope limited to the block where they are declared. A block is the body of a control structure, the body of ...<|control11|><|separator|>
  30. [30]
  31. [31]
  32. [32]
  33. [33]
    Programming FAQ — Python 3.14.0 documentation
    This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the ...Missing: lexical | Show results with:lexical
  34. [34]
  35. [35]
  36. [36]
    PEP 3104 – Access to Names in Outer Scopes | peps.python.org
    Oct 12, 2006 · PEP 3104 proposes adding a `nonlocal` declaration to allow rebinding names in outer scopes, using `nonlocal x` to prevent a name from becoming ...
  37. [37]
  38. [38]
  39. [39]
    Variables and Mutability - The Rust Programming Language
    Shadowing. Shadowing is different from marking a variable as mut because we'll get a compile-time error if we accidentally try to reassign to this variable ...
  40. [40]
    Scope and Shadowing - Rust By Example
    Scope and Shadowing. Variable bindings have a scope, and are constrained to live in a block. A block is a collection of statements enclosed by braces {} .
  41. [41]
  42. [42]
    7.5 — Variable shadowing (name hiding) - Learn C++
    Jan 3, 2020 · The nested variable “hides” the outer variable in areas where they are both in scope. This is called name hiding or shadowing.
  43. [43]
  44. [44]
  45. [45]
  46. [46]
  47. [47]
    var - JavaScript - MDN Web Docs - Mozilla
    Jul 8, 2025 · Duplicate variable declarations using var will not trigger an error, even in strict mode, and the variable will not lose its value, unless the ...<|separator|>
  48. [48]
    Hoisting - Glossary - MDN Web Docs
    Jul 11, 2025 · Hoisting refers to the process whereby the interpreter appears to move the declaration of functions, variables, classes, or imports to the top of their scope.
  49. [49]
    let - JavaScript - MDN Web Docs
    Jul 8, 2025 · A variable declared with let , const , or class is said to be in a "temporal dead zone" (TDZ) from the start of the block until code execution ...Description · Redeclarations · ExamplesMissing: shadowing | Show results with:shadowing
  50. [50]
  51. [51]
  52. [52]
  53. [53]
    Block statement - JavaScript - MDN Web Docs
    Jul 29, 2025 · A block statement is used to group zero or more statements. The block is delimited by a pair of braces ("curly braces") and contains a list of zero or more ...Try it · Description · Examples