First, function scope
You can add wrapper functions outside of your code to hide internal variables and function definitions.
var a = 2; function foo () { //<--Add this line var a = 3; Console.log (a); 3} //<--and this line foo (); <--and this line Console.log (a);//2
This technique must declare a named function foo (), and Foo itself "pollutes" the scope. Second, you must explicitly call this function through the function name (foo ()) to run the code in it.
var a = 2;(function foo () { //<--Add this line var a = 3; Console.log (a); 3}) (); <--and this line Console.log (a);//2
The declaration of a wrapper function, which begins with function rather than function, is treated as a functional expression rather than as a standard function declaration. If function is the first word in a declaration, it is a function declaration, otherwise it is a function expression.
The most important difference between a function declaration and a function expression is where their name identifiers are bound.
The first fragment of Foo is bound to the scope and can be called by Foo (). The second fragment of Foo is bound to the function of the function expression itself instead of the scope in which it resides. (function () {...}) As a function expression means that Foo can only be in ... Represents a location that is accessed, not an external scope. The foo variable name is hidden in itself, which means that the external scope is not unnecessarily polluted.
Second, Anonymous and named
Anonymous functions have some drawbacks:
- Anonymous functions do not display meaningful function names in stack traces, making debugging difficult.
- If there is no function name, only Arguments.callee that have expired can be used when the function needs to refer to itself, such as in recursion. Another example of a function that needs to refer to itself is when the event listener needs to unbind itself after the event is triggered.
- Anonymous functions omit function names that are important for code readability/courtesy.
You can assign a function name to a function expression.
Iii. immediate execution of function expressions (Iife)
var a = 2;(function foo () { var a = 3; Console.log (a);}) ();
Since the function is enclosed in parentheses, it becomes an expression that can be executed immediately by adding () at the end. The first () turns a function into an expression, and the second () executes the function.
More people use the improved form (function () {...} ())。 They function the same.
Iife Another very common advanced usage is to use them as function calls and pass parameters in.
var a = 2;(function iife (global) { var a = 3; Console.log (a); 3 Console.log (GLOBAL.A); 2}) (window); Console.log (a); 2
We pass a reference to the Window object, but name the parameter global, so that the reference to the global object in the code style becomes clearer than referencing a variable that does not have a "global" typeface.
Another scenario for this pattern is to resolve the exception that is caused by the default value of the undefined identifier being overwritten by an error. Name a parameter undefined, but do not pass in any value at the corresponding location, so that the value of the undefined identifier in the code block is really undefined.
Iife There is also a change in the use of inverted code execution order, the need to run the function in the second place, after the Iife executes the parameters passed in.
var a = 2;(function iife (def) { def (window);}) (Function def (global) { var a = 3; Console.log (a); 3 Console.log (GLOBAL.A); 2});
The function expression def is defined in the second part of the fragment, and then as a parameter (also called Def) is passed to the first part of the Iife function definition. The last parameter def (passed in function) is called and the window is passed in as the value of the global parameter.
Iv. block Scope
There are only function scopes in JavaScript and no block-level scopes.
for (var i = 0; i < i++) {}console.log (i); 10
The variable i is defined on the head of the for loop, usually just want to use I in the context of the For loop, while ignoring I is bound to an outer scope (function or global).
var foo = true; if (foo) { var bar = foo * 2; } Console.log (bar); 2
Bar variables, although used in the context of the if declaration, are ultimately part of the external scope.
4.1 With
With is also a form of block-level scope, with the scope created from the object with the with only valid in the with declaration.
4.2 Try/catch
The catch clause of the try/catch of the ES3 specification creates a block-level scope in which the declared variable is valid only within the catch.
Try { undefined ();} Catch(err) { var a = 0; Console.log (err); Can execute }console.log (a); 0;console.log (err); Err not found
4.3 Let
The Let of ES6 can bind a variable to any scope in which it resides (usually {...} )。
var foo = true; if (foo) {let bar = foo * 2; Console.log (bar); 2}console.log (bar); Referenceerror
Explicitly create blocks for block-level scopes
var foo = true; if (foo) { { //<--explicit block let bar = foo * 2; Console.log (bar); 2 }}console.log (bar); Referenceerror
Claims made with let are not promoted in a block-level scope. The declaration does not "exist" until the declared code is run.
{ Console.log ( bar); Referenceerror let bar = 2
4.4 Const
ES6 Introducing Const can also create block-level scopes, but their values are constants.
var foo = true; if (foo) { var a = 2; Const B = 3; block-level scope constants contained in if a = 3; b = 4; error }console.log (a);//3console.log (b);//Referenceerror
JavaScript you don't know function scope and block-level scope