[reread the knowledge points related to the scope of js Plan you don't know] recheck [1]

Posted by joejoejoe on Thu, 23 Dec 2021 08:00:17 +0100

1. Concept of scope

1.1 what is the scope?

In the program, we will use traversal, and how do we store these variables, and then how do we find them when we need to change these variables? Therefore, there is a rule in the program to store variables, which is convenient for us to query later, and this set of rules is what we call scope.

In the traditional compilation language process, the code of the program will undergo "compilation" (divided into three parts) before execution:

  1. Word segmentation / lexical analysis
  • Decompose the character string into meaningful code blocks (lexical unit token)
  • var a = 2; => var, a, =, 2 , ;
  • If there is a space, it depends on whether the space is meaningful in this language
  1. Parsing / syntax parsing
  • Generate abstract syntax tree AST
  1. code generation
  • Convert syntax tree AST into executable code

1.2 understanding scope

  • Engine: complex js compilation and execution process from beginning to end
  • Compiler: responsible for syntax analysis and code generation
  • Scope: it is a set of rules to collect variables, maintain queries, and determine the access rights of the currently executing code to these variables

for instance:

var a = 2;

This simple code will be executed by the engine and compiler together. As mentioned earlier, before executing a piece of code, it will be compiled, decomposed into lexical units, and then generate AST tree for execution. The compilation process may be a little more complicated than we thought. Let's go back to the above example:

The compiler performs the following processing:

  1. var a: first, the compiler will ask the scope (query variables) whether a variable with this name exists in the same scope. If so, continue compiling; otherwise, the scope is required to declare a new variable in the collection of the current scope, named a
  2. The compiler generates the code that the engine needs to execute, a = 2, assignment. At this time, the scope appears again. The engine will ask the scope (query variables) whether a variable with this name exists in the same scope. If so, use this variable; otherwise, continue to search (to the scope chain);
  3. If the variable is found, assign 2 to it, otherwise an error exception will be thrown.

1.3 LHS RHS

Before the engine executes the code, it will query whether a has been declared through the scope chain, but the engine search is divided into two types:

var a = 2; // LHS variable: find a target variable for = a on the left of the assignment
console.log(a); // RHS (just find this value output)

1.4 small examples

function foo(a) {
    console.log(a);
}
foo(2); 

Analyze from your perspective

function foo(a) {
    console.log(a + b); // No b
}
var b = 7;// Look for the overall situation
foo(1)

2. Classification of scope

2.1 lexical scope / dynamic scope (understand)

As we said before, the first step in the compilation phase of a language is lexical analysis, and the lexical scope is the scope defined at this stage. It is determined by where you write variables and block scopes when you write code.

function foo(a) {
    var b = a * 2;

    function bar(c) {
        console.log(a, b, c);
    }

    bar(b * 3);
}

foo(2)
  • Execute foo()
  • Execute bar()
  • console.log(a,b,c)
  1. There are no a, b, but only c in the scope of bar
  2. Go up and find foo. b and a are in the scope of foo (a is also in the scope of foo as a parameter of foo)

2.2 deception morphology: (try not to use Oh, learn about it)

2.2.1 evel

function foo(str, a) {
    eval(str);
    console.log(str) // var b = 3;
    console.log(b) // 3
    console.log(a, b); // 1 3
}

var b = 2;
foo("var b = 3;", 1);

When using the even function, the string passed inside will be used as a piece of code. For example, the above example will become like this: b is within the scope of the function foo, so the value obtained is 3 instead of the external 2

function foo(a) {
    var b = 3;
    console.log(a, b); // 1 3
}

var b = 2;
foo(1);

2.2.2 with

  • Action 1
    Batch modify object properties
var obj = {
    a: 1,
    b: 2,
    c: 3
};

// Do not use with
obj.a = 3;
onj.b = 6;
obj.c = 5


// Use with
with (obj) {
    a = 3;
    b = 6;
    c = 9;
}

console.log(obj.a, obj.b, obj.c);
  • Scope 2 creates a new lexical scope out of thin air based on the object passed to it
function foo(obj) {
    with (obj) {
        a = 2;
    }
}

var o1 = {
    a : 3
};

var o2 = {
    b : 3
};

foo(o1);
console.log(o1.a);
// 2 O1 has a, take a = 2

foo(o2);
console.log(o2.a); // undefined
//  The attribute b is not found in o2 
console.log(a)  // 2
//  But a global a = 2 is also created, that is, when o2 is passed into with,
//  It is not found in the current scope and global, so it creates a global a and performs the assignment operation of a = 2

The reference of an object is treated as a scope, and the attribute of the object is treated as an identifier of the scope

2.3 function scope

Function scope means that all variables belonging to this function can be used and reused (including nesting) within the whole function scope

2.3. 1 suitable writing

function doSometing(a) {
    b = a + doSomethingElse(a * 2);
    console.log(b * 3); // 15
}

function doSomethingElse(a) {
    return a - 1;
}

var b;
doSometing(2); // 15

However, b and doSomethingElse in dosomething should be private methods. We should not use them to define them outside. It is better to modify them as follows

function doSometing(a) {
    function doSomethingElse(a) {
        return a - 1;
    }
    var b;

    b = a + doSomethingElse(a * 2);

    console.log(b * 3); // 15
}

doSometing(2); // 15

2.3. 2 add wrapper function,

It can be placed inside a function to affect external variables
However:

  1. The foo() function needs to be defined
  2. Need to execute
var a = 2;
function foo() { // foo is not affected outside the scope
    var a = 3;
    console.log(a);
}

foo();
console.log(a)

Execute function resolution now:

var a = 2;
(function foo() { 
    var a = 3;
    console.log(a);
})();
console.log(a)

Wrapper functions starting with () are executed as function expressions rather than as standard functions

Tip: distinguish between function expression and declaration: if function is the first word of the declaration, it is the function declaration, otherwise it is the expression;

Small example:

  1. Anonymous function expressions: callback parameters
setTimeout(function () {
    // code
},1000)
  1. Execute the function immediately: the one just now
(function foo() { 
    var a = 3;
    console.log(a);
})();

2.4 block level scope

for (var i = 0; i < 10; i++) {
    console.log(i) // Print 1-9
}
console.log(i,'1ss') // Print 10 
{
    let j;
    for (j = 0; j < 10; j++) {
        let i = j
        console.log(i) // Print 1-9
    }
}

es6 adds a block level scope, including the declaration let const. Let's see the differences between them and var:

2.5 var let const

  • Variables declared by var will be mounted on window, while variables declared by let and const will not:
var a = 1;
let b = 3;
const c = 4;

console.log(a)
console.log(window.a)

console.log(b)
console.log(window.b)

console.log(c)
console.log(window.c)

// 1
// 1
// 3
// undefined
// 4
// undefined

  • var declares that variables have variable promotion, while let and const do not
console.log(a)
console.log(b)
console.log(c)

var a = 0; // undefined var = undefined promoted to the front
let b = 5; // report errors
const c = 6; // report errors
  • let and const declarations form a block scope
  • let and const cannot declare variables with the same name under the same scope, while var can (promote override)
if(1){
    var a = 100;
    let b = 10; // So is const
}

console.log(a); // 100
console.log(b)  // Error b not found
  • Temporary deadband
a = 3
let a;
// ReferenceError: Cannot access 'a' before initialization
  • const must be assigned as soon as it is declared
  • const cannot modify the value, it is a constant
const a = 0;
a = 4
// TypeError: Assignment to constant variable.
  • If it is composite type data, its properties can be modified
const a = {
    aa:'1'
}
a.aa = 'hh'
console.log(a.aa)

Write it at the back

This Plan, reread the javascript series you don't know, and learn together. The goal is to update part of the learning records every week. Come on!

  • Scope and closure series [1]

Topics: Javascript