P粉5462579132023-08-22 12:41:43
Javascript uses scope chains to determine the scope of a given function. There is usually a global scope and each defined function has its own nested scope. Any function defined within another function has a local scope linked to the outer function. It is always the location in the source code where the scope is defined.
An element in a scope chain is basically a map with a pointer to its parent scope.
When parsing variables, JavaScript starts from the innermost scope and searches outward.
P粉1655228862023-08-22 10:58:25
JavaScript has lexical (also called static) scope and closures. This means you can determine the scope of an identifier by looking at the source code.
The four scopes are as follows:
Except for the special cases of global and module scope, variables use var
(function scope), let
(block scope) and const
( block scope) declaration. In strict mode, most other forms of identifier declarations have block scope.
Scope is the area in the code base where the identifier is valid.
The lexical environment is a mapping between identifier names and the values associated with them.
A scope is formed by a linked nesting of lexical environments, with each nesting level corresponding to the lexical environment of an ancestor execution context.
These linked lexical environments form a scope "chain". Identifier resolution is the process of searching along this chain for a matching identifier.
Identifier parsing will only be done outward. This way, the outer lexical environment cannot "see" the inner lexical environment.
When deciding the scope of an identifier in JavaScript, there are three relevant factors:
Declaration methods of some identifiers:
var
, let
and const
var
is omitted in non-strict mode) import
Statementeval
Declaration location of some identifiers:
Identifiers declared using var
have function scope unless they are declared directly in the global context, in which case they are added as properties of the global object and have global scope area. There are separate rules for their use in the eval
function.
Identifiers declared using let
and const
have block scope unless they are declared directly in the global context, in which case they have global scope .
Note: let
, const
and var
are all promoted . This means that their logical place of definition is at the top of their enclosing scope (block or function). However, variables declared using let
and const
cannot be read or assigned until the flow of control passes through the declaration point in the source code. This temporary period is called the temporary dead zone.
function f() { function g() { console.log(x) } let x = 1 g() } f() // 1 because x is hoisted even though declared with `let`!