JavaScript lexical scopes (JavaScript you Don't know)

Source: Internet
Author: User

JavaScript lexical scopes (JavaScript you Don't know)
JavaScript is not a traditional block-level scope, but a function scope!
I. Scope 1. the JavaScript engine will compile the code before execution. In this process, declarations such as var a = 2 will be divided into two independent steps:
Step 1 (compilation phase): var a declares new variables in its scope. This will be performed in the initial stage, that is, before code execution.
Step 2 (running phase): a = 2 queries the variable a (LHS query) and assigns values to it.
2. LHS & RHS (current scope-> upper-level scope->...-> global scope)
LHS (left side): Try to find the variable container itself
RHS (right side): 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 places): foo (2); = a; B;
3. Exceptions
function foo(a){console.log(a + b);b = a;}foo(2);
(1) In ES5 "strict mode", LHS throws a ReferenceError. In "non-strict mode", LHS automatically and implicitly creates a global variable.
(2) A ReferenceError is thrown when RHS queries fail to traverse all nested scopes.
(3) RHS queries a variable, but if you try to operate it unreasonably (reference a property in the null or undefined type), a TypeError will be thrown.
In a word, ReferenceError is related to failure in scope discrimination. TypeError indicates that the scope discrimination is successful, but the operation on the result is illegal or unreasonable.
PS: in principle, I elaborated on the JavaScript function and prototype function execution overwrite in my blog !!!
2. Lexical scope the lexical scope means that the scope is determined by the position of the function declaration during code writing. JavaScript has two mechanisms to "cheat" the lexical scopes: eval (...) and.
1. eval
The eval function can accept a string parameter and regard the content as code that appears in the position of the Program During writing (code can be generated and run at the current position ).
Eval can calculate a piece of "code" string containing one or more declarations and modify the existing lexical scope (runtime stage ).
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, it can be obtained through window. B. If a non-global variable is overwritten, it cannot be accessed!
In 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 is usually used as a shortcut to repeatedly reference multiple attributes of an object. You do not need to repeat the object itself.
With processes the object attributes as the identifiers in the scope, and creates a new lexical scope (runtime stage ).
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, indicating that a is leaked to the global scope!
The side effect of these two mechanisms is that the engine cannot optimize the scope search during compilation, resulting in slow code running. We recommend that you do not use them!
PS: explains the reason why "with" cannot be used in "the essence of JavaScript language", "dregs" and "cancer !!!
Iii. Function scope and block Scope 1. Anonymous and named
/* Anonymous (reference itself can only be referenced with expired arguments. callee) */setTimeout (function () {console. log ("I wait 1 second! ")}, 1000);/* Name (good readability) */setTimeout (function timeoutHandler () {console. log (" I wait 1 seco nd! ")}, 1000 );
2. Execute the 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 */var 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 creates a block scope.
Try {undefined ();} catch (err) {console. log (err); // can be used normally} 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 report an error !! Var bar = 2 ;}
Introduce the New let keyword in ES6 !!
/* Fill in 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/* fill in 2 */{console. log (bar); // SyntaxError !! Let bar = 2 ;}

We recommend two tools to convert ES6 code into an environment compatible with ES6 (most of which are ES5, but not all): Traceur and let-er

 

Related Article

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.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.