Recently reading an advanced JavaScript book, " You do not know the JavaScript (roll Up)", which analyzes a lot of basic concepts.
A more thorough understanding of JavaScript's deep-level knowledge points is possible.
First, function scope
1) function scope
is the scope in a "function", all the variables that belong to the function can be used and reused throughout the scope of the function.
function Foo (a) { var b = 2; function Bar () { // ... } var c = 3/ / failed // three all failed
The above "foo" function within a few identifiers, placed outside the function access will be an error, view the source code .
2) Execute function expression immediately
Add wrapper functions outside of any code fragment to "Hide" internal variables and function definitions, and external scopes cannot access any content inside the wrapper function.
For example, the bar, a, and several other identifiers above. This allows the variable to be protected from contamination.
When writing a plugin, it is often used to execute function expressions immediately, in order to protect the variables inside.
var a = 2;(function foo () { var a = 3; // 3 // 2
The first () in "foo" turns a function into an expression, and the second () executes the function.
There is a special term:Iife, which represents an immediate execution of a function expression (Immediately invoked function expression);
1. Advanced usage is to use them as function calls and pass parameters in
(function iife (global) { var a = 3; // 3 // 2}) (window);
2. One change is the use of inverted code , which is widely used in CMD or AMD projects.
(function iife (Factory) { Factory (window);}) (function def (global) { var a = 3; // 3 // 2});
Second, block scope
JavaScript does not support block scopes.
for (var i=0; i<10; i++) { console.log (i);}
The "I" in the code above is equivalent to the following
var i; for (i=0; i<10; i++) { console.log (i);}
But there are exceptions , "Try/catch", catch is a block scope.
Try { //} catch(err) { // can execute normally! // referenceerror:err not found
ES6 changed the status quo and introduced a new let keyword that allows a variable to be bound to any scope in which it resides (usually {...} Internal). In other words, let's declare the variable implicitly where the block scope is located.
Third, promote
The behavior of the function scope and the block scope is the same, which can be summed up as: Any variable declared within a scope will be attached to that scope.
1) Compile and execute
all declarations of variables and functions are processed first before any code is executed, and can be seen in the following code case.
A = 2; var A;console.log (a); // 2
This code is equivalent to:
var A; // A definition declaration is a = 2 during the compilation phase ; // assignment declarations are left in place for the execution phase Console.log (a);
2) function First
The function is first promoted and then the variable.
// 1 var foo; function foo () { 1function() { 2 );};
The var foo function expression is a duplicate declaration (and therefore ignored ), even though it appears before the declaration of the function foo (), because it is promoted to a normal variable.
And the above code is equivalent to:
function foo () { 1// 1function() { 2 );};
Four, closed package
1) definition
When a function can remember and access its scope, a closure is generated, even if the function is executed outside the current scope.
function foo () { var a = 2; function Bar () { console.log (a); } return var baz =// 2--This is the effect of closures.
1. Assign the function "bar" to "Baz", execute "Baz", the current scope is not in the scope of "bar", but can be executed.
2. Closures also block garbage collection, and when "foo" finishes executing, the internal scope still exists. This will allow the "Baz" to execute.
2) passing the function as a parameter
function foo () { var a = 2; function Baz () { // 2 } function Bar (FN) { // This is the closure package! }
The internal function Baz is passed to bar, and when this intrinsic function is called (FN), the closure of the inside scope of the Foo () that it covers can be observed because it can access a.
If the function is treated as a first-level value type and passed around , you will see the closure applied to these functions.
In a timer , event listener ,Ajax request , Cross-window communication ,Web Workers , or any other asynchronous (or synchronous) task , As long as the callback function is used, you are actually using closures!
3) Loops and closures
for (var i = 1; I <= 5; i++) { setTimeout (function timer () { Console.log ( i); * +);}
Each time the print will be 6, the callback of the deferred function will be executed at the end of the loop, viewing the source code .
Depending on how the scope works, the reality is that although the five functions in the loop are defined separately in each iteration, they are all enclosed in a shared global scope , so there is actually only one I.
Now use closures to implement a different I each time I print.
for (var i = 1; I <= 5; i++) { (function(j) { setTimeout (function timer () { console.log (j); * +); }) (i);}
Iife creates a scope by declaring and immediately executing a function. Callbacks in SetTimeout can remember the current scope, and the parameter "J" in each scope is different.
JavaScript you don't Know (a)-scope, elevation, and closure