Intuitively it is assumed that JavaScript code executes from the top to the next line, but in practice it is not entirely true.
Console.log (a); // Referenceerror
A = 2; var A;console.log (a); // 2
Console.log (a); // undefined var a = 2;
The correct thinking is that all declarations, including variables and functions, will be processed first before any code is executed .
When you see var a = 2, you might think of this as a declaration. But JavaScript actually sees it as two declarations: Var A; and a = 2;.
The first definition declaration is made during the compilation phase (the variable declaration is scoped to the corresponding scope).
The second assignment declaration is left in place for the execution phase.
This process is as if the variables and function declarations are "moved" from where they appear in the code to the top, and this process is called Ascension .
For example, the following code, the Var foo is promoted, the Execution of Foo (), foo or undefined, undefined function call is naturally tyeperror.
// not referenceerror, but typeerror!. var function Bar () { // ... };bar (); // Referenceerror, because bar is a named function expression, the bar identifier is only declared inside the function, which is actually equivalent to the functions () {var bar = ...}
Both the variable declaration and the function declaration are promoted, and the function declaration is promoted before the variable declaration:
Foo (); // 1 var foo; // Although the Foo function is declared before, the Foo function is preferentially promoted, and when the compiler declares the Foo variable, there is already a Foo declared in the scope, so the declaration of the variable foo is ignored, which avoids inadvertently overwriting the function declaration. function foo () {console.log (1);} Bar (); // TypeError, note that the precedence promotion is only a function declaration, not a function expression. varfunction() {//...}
Closed Package
in JS, closures are ubiquitous, and closures are the natural result of writing code based on lexical scope .
A closure is when a function leaves the scope of its original declaration, and the function still has access to the original parent scope, as if the function were wrapped in the original parent scope.
Let's look at this classic loop example to explain closures:
for (var i=1; i<=5; i++) { function timer () { console.log (i); // 5 x 6 }, i*1000 );}
Solution One:
for (var i=1; i<=5; i++) { (function() { var j = i; function timer () { console.log (j); }, J*1000 ); }) ();} or for (var i=1; i<=5; i++) { (function() { function timer () { console.log (j); }, J*1000 ); }) (i);}
Solution Two:
for (var i=1; i<=5; i++) { // Yes, block scope of closures! function timer () { console.log (j); }, J*1000 );} for (Let I=1; i<=5; i++) {//let indicates that avariable is not declared more than once during a loop, each iteration is declared, and there are 5 separate closures. function timer () { console.log (i); }, I*1000 );}
Implement module mode with closures:
functionModule () {varE =true; functionHelloe (name) {varHellotxte = "Hello"; Console.log (Hellotxte+name); } functionHelloc (name) {varHELLOTXTC = "Hello"; Console.log (HELLOTXTC+name); } functionChangelanguage () {e= !e; if(e) {Publicapi.hello=Helloe; }Else{Publicapi.hello=Helloc; } } varPublicapi ={hello:helloe, changelanguage:changelanguage}; returnPublicapi;}varm =Module (); //If you want to implement a singleton, you only need to use Iife M.hello for module("Zyong"); //hello zyongm.changelanguage (); M.hello ("Zyong");//Hello Zyong
Module Dependency Manager:
functionHellomodule () {varE =true; functionHelloe (name) {varHellotxte = "Hello"; Console.log (Hellotxte+name); } functionHelloc (name) {varHELLOTXTC = "Hello"; Console.log (HELLOTXTC+name); } functionChangelanguage () {e= !e; if(e) {Publicapi.hello=Helloe; }Else{Publicapi.hello=Helloc; } } varPublicapi ={hello:helloe, changelanguage:changelanguage}; returnPublicapi;}varModulemanager = (functionModulemanager () {varModules = []; functiondefine (name, Deps, Impl) { for(Let i=0; i<deps.length; i++) {Deps[i]=Modules[deps[i]]; } Modules[name]=impl.apply (Impl, deps); } functionget (name) {returnModules[name]; } varAPI ={define:define, get:get}returnAPI;}) (); Modulemanager.define ("Hellomodule", [], hellomodule);varHellomodule = Modulemanager.get ("Hellomodule"); Hellomodule.hello ("Zyong"); Hellomodule.changelanguage (); Hellomodule.hello ("Zyong");
Finally, the programming language is divided into lexical scopes and dynamic scopes for the declaration of variables and functions, and JS belongs to the former. The lexical scope limits the scope to where the code is written, where it is concerned , and where the scope of a dynamic scope looks for variables based on the call stack during code execution. The This keyword in JS is a bit like a dynamic scope (but not).
JS Précis-writers-scope 2