Lexical Scope
Javascript is a lexically scoped language.
Lexical Scope (Static scope)
Lexical Scoping defines how variable names are resolved in nested functions: inner functions contain the scope of parent functions even if the parent function has returned.
Lexical scope can be deduced at compile-time (hence Static scope). Because of that we can derive the scope from reading the source code.
Example of Lexical scope
Example of dynamic scope (Lisp)
Here fun can either access x in dummy1 or dummy2, or any x in any function that call fun with x declared in it.
dummy1();
will print 5, dummy2();
will print 10.
JavaScript has 3 types of scope: Block scope
, Function scope
, Global scope
.
(Block came with ES6).
Block Scope
ES6 introduced: let
and const
. These two keywords provide Block Scope in
JavaScript. Variables declared with let
and const
inside a { }
block
cannot be accessed from outside the block.
Variables declared with the var
keyword can NOT have block scope.
Variables declared inside a { }
block can be accessed from outside the block.
Line 8 will print value 4
. Since var
is not block scoped.
Line 12 will throw ReferenceError
since var is function scoped and cannot
accessed outside function.
Both line 8, line 12 will throw ReferenceError
. Since let
is both block scoped
and function scoped.
Function Scope
Variables defined inside a function are not accessible from outside the function.
Variables declared with var
, let
and const
are quite similar when declared
inside a function. They all have Function Scope.
Global Scope
Variables declared Globally (outside any function) have Global Scope. Global variables can be accessed from anywhere in a JavaScript program.
Variables declared with var
, let
and const
are quite similar when declared
outside a block. They all have Global Scope.
var | let | const | |
---|---|---|---|
Inside function | function scoped | function scoped | function scoped |
Inside block | function scoped or global scoped | block scoped | block scoped |
Inside global | global scoped | global scoped (does not attach to window ) | global scoped (does not attach to window ) |
Global Variables in HTML
In JavaScript, the global scope is the JavaScript environment.
In HTML, the global scope is the window object.
Global variables defined with the var keyword belong to the window object:
Global variables defined with the let keyword do not belong to the window object:
var
The var
statement declares a function-scoped or globally-scoped variable.
Accessing a var
before it is declared has the result undefined
because of
hoisting.
let and const
let
and const
declares a block-scoped local variable.
Accessing a let
or const
before it is declared throws ReferenceError
because of TDZ. That doesn't mean it's not hoisted though.
Accessing foo in inner scope will result in ReferenceError
. This happens
because of TDZ. You can try to comment out let foo = "inner";
and see error
goes away.
let foo = "inner";
will be hoisted inside the function scope. Hence it will
create a TDZ.