JavaScript lexical scopes (JavaScript you don't know)

Source: Internet
Author: User

JavaScript is not a traditional block-scale scope, but a function scope!
First, Scope1. The JavaScript engine compiles the code before it executes, and in this process, a declaration such as var a = 2 is decomposed into two separate steps:
First step (Compile phase): Var a declares a new variable in its scope. This is done at the very beginning, that is, before the code executes.
Second step (Run phase): A = 2 queries the variable A (LHS query) and assigns it a value.
2. LHS & RHS (current scope, ancestor scope->...-> global scope)
LHS (left): trying to find the container itself of the variable
RHS (right): Find the value of a variable
Example:
function foo (a) {var b = A;return A + b;} var c = foo (2);//LHS (3): c;a (implicit variable allocation); b;//RHS (4): foo (2); =a;a;b;
3. Exceptions
function foo (a) {Console.log (A + b); b = A;} Foo (2);
(1) Under ES5 "Strict mode", LHS throws referenceerror; under non-strict mode, LHS automatically creates a global variable implicitly.
(2) RHS query throws Referenceerror if the required traversal is not found in all nested scopes.
(3) RHS queries to a variable, but you try to manipulate it unreasonably (referencing a property in null or undefined type), the TypeError is thrown.
In a nutshell: The Referenceerror is related to the failure to discriminate against the scope, while the TypeError represents the success of the scope, but the operation of the result is illegal or unreasonable.
PS: From the principle of the blog "JavaScript function and its prototype" function implementation coverage and OTHER issues!!!
Ii. Lexical scopesThe lexical scope means that the scope is determined by the location of the function declaration when the code is written. There are two mechanisms in JavaScript that can "spoof" a Lexical scope: eval (...) And with.
1. Eval
The Eval function can accept a string argument and treat it as if it were in the program at the time it was written (in the current location, code can be generated and run).
Eval can calculate a "code" string that contains one or more declarations and modify the lexical scope (run phase) that already exists.
function foo (str,a) {eval (str); Console.log (A, b);//1, 3console.log (A, window.b);//1, 2}var B = 2;foo ("var b = 3;", 1);
Explanation: The above global variable B is overwritten, because B is global and can be obtained by window.b, but non-global variables cannot be accessed if they are overwritten!
Under strict mode:
function foo (str,a) {"Use strict"; eval (str); Console.log (A, b);//1, 2console.log (A, window.b);//1, 2}var B = 2;foo ("var b = 3; ", 1);
2. With
With is often used as a shortcut to repeatedly reference multiple properties in an object, you can not refer to the object itself repeatedly.
With the object's properties as an identifier in scope, a new lexical scope (run phase) is created.
function foo (obj) {with (obj) {a = 2;}}  var O1 = {A:3};var O2 = {b:3};foo (O1); Console.log (o1.a);//2foo (O2); Console.log (o2.a);//Undefinedconsole.log ( a);//2, which indicates a leak to the global scope!
the side effect of these two mechanisms is that the engine cannot optimize scope lookups at compile time, causing the code to run slower, and it is not recommended to use them!
PS: From the principle of the blog "The Essence of JavaScript language," "dross, Cancer," the reason that with can not be used!!!
Three, function scope and block scope1. Anonymous and named
/* Anonymous (referencing itself can only be referenced with expired Arguments.callee) */settimeout (function () {Console.log ("I wait 1 second!")},1000);/* Named (readable) */ SetTimeout (function Timeouthandler () {Console.log ("I wait 1 seco nd!")},1000);
2. Execute function expression immediately
/* Iife mode */var a = 2; (function Iife (global) {var a = 3;console.log (a);//3console.log (GLOBAL.A);//2}) (window);/* UMD mode */v Ar b = 2; (function UMD (def) {def (window);}) (function Tmpf (global) {var b = 3;console.log (b);//3console.log (global.b);//2});
3. Block scope
Try/catch will create a block scope
Try{undefined ();} catch (Err) {Console.log (err);//can normally use}console.log (err);//referenceerror:err is not defined/* pit 1 */for (var i=0;i<10 ; i++) {}console.log (i);//10/* Pit 2 */{console.log (bar);//undefined will not error!! var bar = 2;}
Introducing the new let keyword in ES6!!
/* Pits 1 */for (let i=0;i<10;i++) {}console.log (i);//syntaxerror:block-scoped declarations (Let, const, function, class ) Not yet supported outside strict mode/* pits 2 */{console.log (bar);//syntaxerror Error!! Let bar = 2;}

Two recommended environments for converting ES6 code to compatible ES6 (mostly ES5, but not all) tools: Traceur and Let-er


JavaScript lexical scopes (JavaScript you don't know)

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.