a summary of the basic functions of JS including lexical scope and module Foundation. 1 Compiler---scope---engine The compiler is responsible for parsing and code generation, and the scope is responsible for maintaining a series of queries that consist of all identifiers (variables), and the engine is responsible for executing the code according to the rules defined by the scope. Therefore, the scope is equivalent to mediation, first the compiler compiles, the scope is maintained, and then the engine executes according to the scope. So although JS is an interpreted language, it is still actually compiled and executed first. the engine takes LHS queries and RHS queries when executing. As I understand it, the LHS query is the query "container", which is the variable that loads the data. The RHS query is the variable value itself. 2 Calendar rules for nested scope chains The engine looks for the variable from the current known execution scope, and if it cannot find it, it looks up to the first level. When the outermost global scope is reached, the lookup process stops regardless of whether it is found. 3 JS follows the lexical scope. the scope of a function depends on the domain of the definition in which it is defined, regardless of where it is called. (function declaration elevation, which is also promoted in the scope in which it is defined, so it is still in the same scope, no effect) to avoid the scope of function contamination (for example, if a function needs to run only once and then not needed), then you can use (function foo () {}) (), which is Iife In addition to the function, you can also use {let A = 1;} That is let and curly braces to explicitly create the block scope. The Let's function is to allow the allowed variable to be used only in the block where it is located, beyond the scope of the block. explicitly declares a block scope for a variable, that is, to put some variables into {}, declare with Let, and bind the variables locally so that when the variable is used, the data is garbage collected. What do you mean? That is, a data is actively put into the block scope, that is, the outside can not be used, so the garbage collection mechanism will know that once the data is exhausted, the scope outside the scope of the block is no longer used (also can not use) it, so it could be directly garbage collection. This reduces memory consumption. 4 About Ascension all declarations, including variables and functions, are processed during the compilation phase, i.e. declaration elevation. The assignment or other running logic remains in place and waits for the execution phase. As already known, JS is compiled after the execution, so you can know is the first declaration, after the assignment. function declarations and variable declarations are promoted, but function declarations are promoted first, which is promoted to the top of their scope, exceeding the variable declaration. 5 Closures since JS follows the lexical scope, the function is called (in the same way as the function itself, or whatever) in another place (not in its scope), and execution follows its scope, thus forming a closure. It is not easy to understand that the function is treated as a value type and exported, regardless of where it is passed, because it follows the lexical scope, the runtime or the defined domain where the function's seat is defined. Or can be understood as, function aa () {...} This entire function is defined at the very beginning, followed by the scope there. when a function can remember and access the lexical scope in which it resides, even if the function executes outside the current lexical scope, a closure is generated. as long as the callback function is used, the closure is actually used. (The reason is that the function is defined in an asynchronous parameter and is called in another thread, so the runtime is, of course, the scope chain where the definition is located) For (let I=1; i<=5; i++) {setTimeout (function timer () {Console.log (i);}, i*1000);}This is an alliance of closures and block scopes. Closures refer to settimeout async, which is a block scope that refers to a let. Calling let in the for loop means that each time I is re-declared. In fact, a closure is a function that is defined on scope A and called at a scope outside of scope a. 6 About Modules module is the use of closures. As I understand it, it is a function in which the inner function and the variable are written, that is, the closure, and then return the function. Call the outer function each time, get the function inside, call outside. Module mode must have two conditions: 1 must have an external enclosing function, the function must be called at least once (each call will create a new module instance) 2 The enclosing function must return at least one intrinsic function in order for the intrinsic function to form a closure in the private scope. and can access or modify private variables. Examples of modules:var mymodules = (function Manager () {var modules = {}; function define (name, Deps, Impl) {For (Var i=0;i<deps.length;i++) {Deps[i] = modules[deps[i]]; }Modules[name] = impl.apply (impl,deps);Console.log (modules); } function Get (name) {return modules[name]; } return {Define:define,Get:get }})(); first of all, this is a module creator called manager, immediately after the invocation of the API interface exposed to the mymodules, so it is only executed once, that is, a singleton mode. This Manager module has a modules, which is the object of each module. The define is the wrapper function used to define the new module. Pass in 3 parameters, the name of the new module, Deps, the other modules that the module needs to rely on (note that only the modules needed to define the new module, not all modules, are passed in as an array, each of which is the name of the required dependency module); Impl, That is, the definition of the new module. The define function first iterates through the deps in order to take the module out of the modules and put it in Deps. Modules[name] = impl.apply (impl,deps), which means binding the Impl's run context to its own function, passing in a dependency deps and running, storing the result in modules named after the name passed in. (note, here with the Apply function, I personally think that it is a convenient feature of the Apply function, that is, you can directly split the array into one element into the function)Next is the call: mymodules.define (' Bar ', [],function () {function Hello (who) {return ' Nihao ' + who; }return {Hello:hello }}); mymodules.define (' Bye ', [],function ()} {function Bye (who) {return ' bye ' +who; }return {Bye:bye }}); mymodules.define (' foo ', [' Bye ', ' Bar '],function ()} {var who= ' Mike ';var args = arguments;function Awesome () {Console.log (Args[0].bye (WHO));//When you run a function with apply, you can use arguments to get the arguments, so that you do not have to list all the formal parametersConsole.log (Args[1].hello (WHO)); }return {Awesome:awesome }}); var foo = mymodules.get (' foo ');foo.awesome ();//bye Mike Nihao Mike
Welcome to communicate with each other and learn from each other. Front-end development QQ Group: 711357426
The lexical scope of JavaScript syntax