Scope also called stack memory

Global scope: window

Private scope: Function execution forms a private scope

Block-level scope: There is block-level scope for creating variables using let

Scoped chain: a variable encountered by the current scoped code is first checked to see if it is private,

If the variable is private in the current scope, the operation is private when the variable is encountered in the private scope in the future (closure: the private scope protects the private variable from external interference).

If it’s not private, it looks up in its parent scope, and if it’s not private in its parent scope, it looks up in its parent scope, and it looks up in its parent scope, and it looks up in its parent scope, and it looks up in its parent scope, and it looks up in its parent scope, and it looks up in its parent scope, and it looks up in its parent scope, and it looks up in its parent scope, and it looks up in its parent scope.

If it’s global, it’s global;

< span style = “box-width: border-box; 2, get: error

Finding private variables

There are only two types of private variables in js:

    1. A variable or function declared during the private scope variable promotion phase
    1. Parameters are also private variables
function fn(num1,num2){
    var total=num1+num2;
    return total;
}
var result=fn(100.200)

Totle num1 Num2 is private
//result fn is global
Copy the code

The steps performed by the function

The function executes to form a new private scope, and in the private scope:

    1. Parameter Assignment (attached variable declaration and assignment)
    1. Variable ascension
    1. Top down code execution
    1. Current stack memory (private scope) is destroyed or not destroyed
    //=>1. var y; var z; fn=aaafff111;
    var x=10,
        y=20,
        z=30;
    function fn(x,y){
        //=> Private scope
        Var x=10 var y=20 (x/y is private) all xy variables in the function are private
        // Var x should be promoted again, but the parameter x already exists so ignore var x. X is 10 instead of undefined
        console.log(x,y,z)      //=> 10 (private x) 20 (private y) 30 (z is global)
        var x=100;// Private x=100, no var
        y=200;// Private y=200
        z=300;// global z=300
        console.log(x,y,z)  / / 100 200 300
    }
    fn(x,y,z)  Fn (10,20,30); fn(10,20,30);
    console.log(x,y,z)  / / 10 20, 300
Copy the code
function fn(b){
    //=> Private scope
    Var b=1(private);
    //=> variable promotion: ignores the declaration of function b, but reassigns b (where the assignment replaces the 1 assigned to the parameter)
    console.log(b) => function itselffunction b(){
        // Private scope
        // No parameter assignment, no variable promotion
        console.log(b)  // Find the b output function itself in the parent scope through the scope chain
    }
    b();
}
fn(1)
Copy the code
function fn(b){
	//=> Private scope
    //=> Parameter assignment: b=1(private variable);
    //=> variable promotion: ignores statement B and does not assign
	console.log(b); / / 1
	var b=10;
}
fn(1) 
Copy the code

How to find the parent scope:

Function execution forms A private scope (A). The parent scope of A does not depend on where it is executed. It depends on where it is defined and in which scope it is defined.

var n=10;
function sum(){
    console.log(n)
}
sum()  / / = > 10
~function(){
    var n=100;
    sum()  //=>10 sum is hosted by the private scope of the current self-executing function} ()Copy the code
//=>window Global scope
//=> var n; var obj;
// Code execution
var n=10;     //=>n=10
var obj={     //=> obj=AAAFFF000 One memory space
    n:20.//n:2
    fn: (function(){             // The result returned by the self-executing function is assigned to fn
                // The parameter is not assigned
                Var n;
        var n=30;       //n=30
        return function(){
            console.log(n)
        }
        //=> return AAAFFF111
        //return the address of the heap.}) ()//=>fn=AAAFFF111
}

obj.fn()  / / = > 30
Copy the code

{} is only a heap memory block-level scope, not a scope (scope must be created by function execution), so the parent scope of the self-executing function is the global window

//=>window Global scope
//=> var n; var obj;
// Code execution
var n=10;     //=>n=10
var obj={     //=> obj=AAAFFF000 One memory space
    n:20.//n:2
    fn: (function(){             // The result returned by the self-executing function is assigned to fn
        return function(){
            console.log(n)
        }
        //=> return AAAFFF111
        //return the address of the heap.}) ()//=>fn=AAAFFF111
}

obj.fn()  / / = > 10

//obj={} {} only the heap memory is not scoped, so the upper scope of the only function to be executed is the global window
Copy the code
var n=10;     //=>n=10
var obj={     //=> obj=AAAFFF000 One memory space
    n:20.//n:2
    fn: (function(n){             // The result returned by the self-executing function is assigned to fn
        return function(){
            console.log(n)
        }
    })(obj.n)       //=> The memory address is assigned to the variable after the execution of the self-executing function. Obj is undefined, so obj.n fails

}

obj.fn()   // error n of undefined

Copy the code

Closures (self-executing functions)

Function execution, forming a private scope, inside the private variables from outside interference, this protection mechanism is called closure **

However, many people now believe that a closure is a mode in which functions are executed, forming an undestroyed private scope that can store something in addition to protecting private variables

var utils=(function(){

    return{}}) ();Copy the code

Closure action – Protection: Function execution creates a private scope to protect private variables from external interference

In real projects, we use this mechanism to achieve collaborative team development (avoiding the problem of code conflicts caused by multiple people having the same name).

Team development, where each developer keeps his code in a private closure to prevent conflicts; Expose methods that need to be used by others globally via return or window.XXX.

//=>A
~function(){
      //=> Code written by A
      function fn(){}window.fn=fn
}();
//=>B
~function(){
      //=> Code written by B
      // IF B wants to fetch the fn written by A, write window.fn=fn in the code written by A
       window.fn()  // Execute A code} ();Copy the code

JQuery source code is also the use of protection mechanism

~function(){
    var jQuery=function(){
        / /...
    }

    window$=window.jQuery=jQuery; } ()Copy the code

Closure action – save: An undestroyed private scope (stack memory) is formed to save the contents inside

The execution of a function forms a private scope, and after the execution of the function completes, the resulting stack memory is usually freed automatically

But there are special cases: Function is complete, the current private scope (stack) in a part of content is something other than the stack memory/elements of the event (variable) take up, the current stack memory cannot release, also has not destroyed the private scope of private variables will not be destroyed (inside), returned to the reference data types of data And external references)

Function execution forms a private scope. If part of the private scope is occupied by a variable other than the private scope, the current scope is not destroyed

In the form of

The function returns oneReference data type heap memory addressIf a variable outside the scope accepts the return value, the current scope cannot be destroyed.

function fn(){
    var i=1;
    return function (n){
        console.log(n+i++); }}var f=fn();   //fn should be destroyed after execution, but the function inside fn is occupied by external f, so fn is an undestroyed stack memory
f(10)           / / = > 11
fn()(10)        //fn() reopens a memory 11
f(20)           / / 22
fn()(20)          / / 21

function fn(i){
    return function (n){
        console.log(n+(++i)); }}var f=fn(10);
f(20)          / / 31
fn(10) (20)      / / 31
f(30)           / / 42
fn(20) (10)          / / 31
f(40)           / / 53
//fn executes all the processes again (the parameter assignment code is promoted), regardless of other fn executes
Copy the code

If an object or function (referring to a datatype) returns an address that is occupied by an external variable, the stack memory created by the function is not destroyed. If the function returns an underlying datatype, the stack memory is destroyed

Each execution of fn repeats all the processes again (the parameter assignment variable is promoted), independent of any other fn execution

TAB closure solution

/ / TAB
var tabBox=document.getElementById('tabBox');
var oList=tabBox.getElementsByTagName('li');
var oDivList=tabBox.getElementsByTagName('div');

function changeTab(index){
    for( var i=0; i<oList.length; i++){ oList[i].className=oDivList[i].className=null;
    }
    oList[index].className=oDivList[index].className='select';
}
for(var i=0; i<oList.length; i++){// I can't pass I directly.
    // Only the click event given to each Li is not executed (it is executed when clicked)
    So when I hit Li I is always equal to olist. length and I is global; When clicked, the method is executed, creating a private scope, using the variable I. I is not a private variable, and we want to look globally. At this point, the global I is already the olist.length of the last loop

    //**** All event bindings are programmed asynchronously (methods are not executed when they are bound), and by the time the click event is triggered and the method is executed, the loop has already ended
    oList[i].onclick=function(){
        changeTab(i)   / / I can't}}// Custom attributes
for(var i=0; i<oList.length; i++){var oList[i].myIndex=i;
    oList[i].onclick=function(){
        changeTab(this.myIndex)
    }
}

// Add a layer of non-destructible private scopes to make use of closures
// Improves heap memory usage
for(var i=0; i<oList.length; i++){ oList[i].onclick=(function(i){
        // The scope formed by self-executing functions is not destroyed
        // Because the self-executing function assigns a reference data type to Li's click event
        return function(){
         changeTab(i)
        }
    })(i)
}
for(var i=0; i<oList.length; i++){ ~function(i){
        // The scope formed by self-executing functions is not destroyed
        // Because the self-executing function assigns a reference data type to Li's click event
        oList[i].onclick=function(){
            changeTab(i)
        }
    }(i)
}

// Block level scopes in ES6 are not considered compatible
for(let i=0; i<oList.length; i++){ oList[i].onclick=function(){
        changeTab(i)
    }
}
Copy the code

Obj ={} {} only heap memory is not scoped,

Window is neither a keyword nor a reserved word