The essence, definition and usage of variables and scopes in JS

Global scope and local scope

global scope

Local scope: function scope

Global scope can be accessed globally and locally, while local scope can only be accessed locally

var name="cyy";

function fn(){
    var age=25;
    console.log(name);//cyy
    console.log(age);//25
}
fn();
console.log(name);//cyy
console.log(age);//age is not defined

js has no block level scope, and it is still a global variable here

if(){
    //global variable
}
for(){
    //global variable
}

In the function, the variables declared with var are local variables, and those without var are global variables

function fn(){
    var x=y=1;
}
fn();
console.log(y);//1
console.log(x);//x is not defined
var name="cyy";
function fn(){
    name="cyy2";//var is not used, so the external global variable name is modified here
    console.log(name);//cyy2
}
fn();
console.log(name);//cyy2

Variable object and scope chain

There are name variables and fn functions in the global scope. In fact, they are all on the window object

The properties and methods of variable objects in global scope can be seen and touched, and can be accessed

var name="cyy";
function fn(){
    var age=25;
    function fn2(){
        var gender="girl";
    }
}
console.log(window.name===name);//true
console.log(window.fn===fn);//true

There are age variables and fn2 functions under fn

Properties and methods of variable objects in local scope are invisible and intangible

 

If you access a variable that does not exist, an error will be reported

Access to nonexistent properties, no error will be reported

Here's to add: at the beginning, I tested with name, and there was an unexpected situation

Later, it was found that name is a built-in attribute of js objects. It should be avoided to use it when naming. It is recommended to use name

Print window object to view name

 

 

console.log(window._name);
console.log(_name);

 

Scope chain:

If you want to find a variable, you will first find it in the current scope;

If not, go to the upper scope to find;

Up to window

Therefore, the inner layer can access the variables of the outer layer, but the outer layer cannot access the variables of the inner layer

 

Method of extending scope chain

with() opens up a new scope

If you can't find the attribute in it, you will go to the outer window to find it

However, it is not recommended to use with, which will cause other problems in the future

var person={};
person.name="cyy";
person.age=25;
var score=90;

console.log(person.name);//cyy
console.log(person.age);//25
console.log(score);//90

with(person){
    name="cyy2";
    age=cyy2;
    score=99;
}
console.log(person.name);//cyy2
console.log(person.age);//cyy2
console.log(score);//99

Add click events circularly to get the index of each click button

The click method needs to be defined outside the loop, otherwise it will only output the value of i after the end of the loop

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button>1</button>
    <button>2</button>
    <button>3</button>
<script>

var btns=document.querySelectorAll("button");
for(var i=0,len=btns.length;i<len;i++){
    myClick(i);
}
function myClick(i){
    btns[i].onclick=function(){
        alert(i);
    }
}
</script>
</body>
</html>

A non-existent variable or function will report an error; a non-existent property or method will return undefined; |||is a short-circuit operation, like a||b. if the value of a is converted to a Boolean value, a||b is equal to a; if the value of a is converted to a Boolean value, a||b is equal to B

Here, window.person = undefined, so window.person="cyy" is returned

//console.log(person || (person="cyy"));//person is not defined
console.log(window.person || (window.person="cyy"));//cyy

If the click event is bound directly in the loop, because it is only bound in the loop; when the click button is clicked, the loop has already ended, so i will always be the value after the end of the loop

var btns=document.querySelectorAll("button");
for(var i=0,len=btns.length;i<len;i++){
    btns[i].onclick=function(){
        alert(i);//3
    }
}

JS parsing mechanism: pre parsing

The simplest case

var age=25;
function fn(){
    var age=26;
    console.log(age);//26
}
fn();

JS parsing process:

Pre parse

Read code line by line

var age=25;
function fn(arg){
    console.log(age);
    var age=26;    
}
fn();
/*
js Analysis mechanism:
window:
    age undefined 25
    fn function fn(arg){
            console.log(age);//undefined
            var age=26;    
            console.log(age);//25
        }
fn:
    arg(Parameter as a local variable) undefined
    age undefined
 First, find all the vars, and assign the variables declared by var to undefined
 Take the function directly
 When reading, because the function has been declared, it will be skipped during normal execution
 Direct execution fn()
console.log(age)age in is pre parsed undefined
*/

Variable name conflict: undefined in pre parsing

var age=25;//Pre analysis: undefined
...
var age=26;//Pre analysis: undefined

Conflict between variable and function name: skip variable name during pre parsing, only declare function

var age=25;//Pre analysis: undefined
function age(){
    
}

Conflict between function and function name: select the latter function during pre parsing, and the first function is killed

function age(){
    var age=24;
}
function age(){
    var age=25;
}

In some older browsers, such as Firefox, functions inside if or for cannot be parsed

Therefore, it is not recommended to define functions in code blocks

if(){
    function fn(){

    }
}

for(){
    function fn2(){
        
    }
}

Variable resolution mechanism:

Variables declared in var are pre parsed

Variables declared in let do not pre resolve

Function declaration resolves

Function expressions do not pre parse

document.write(fn);
function fn(){}

 

The function declaration is already declared in advance when it is pre parsed

The assignment of function variables, which is defined as undefined during pre parsing

document.write(fn);//undefined
var fn=function(){}

Print the later variables in advance. The printed variables are undefined

console.log(age);//Pre parsed as undefined
var age=25;

If it is not declared with var, it cannot be pre parsed. When printing in advance, if you do not know the existence of the variable, you will report an error

console.log(age);//Report errors
age=25;
console.log(a);//Print out the result of pre parsing, which is a function a()
var a=1;
console.log(a);//1
function a(){
    console.log(2);//Skip not executed
}
console.log(a);//1
var a=3;
console.log(a);//3
function a(){
    console.log(4);//Skip not executed
}
console.log(a);//3
a();//here a Yes, 3. It cannot be executed as a function, so an error is reported

/*
Find var before pre parsing: find var a=1; and var a=3; the pre parsing result is undefined
 Then find the function and find that function a has the same name as the variable. At this time, the variable is killed
 Because there are two functions with duplicate names, the previous function is killed, so the pre parsing result of a is:
function a(){
    console.log(4);
}
*/

Pre parsing is done by label

There is no contact between the top and bottom of this place, and an error will be reported

<script>
    console.log(a);//Report errors
</script>

<script>
    var a=1;
</script>

However, there is no problem with the up and down sequence swapping, because it has been executed normally and has nothing to do with pre parsing

<script>
    var a=1;
</script>

<script>
    console.log(a);//1
</script>
    var a=1;//undefined 1
    function fn(){
        console.log(a);//undefined
        var a=2;//undefined 2
    }
    fn();
    console.log(a);//1

When there is no var in the function, it will not be pre parsed, and the variable will be searched through the scope chain

If there is var in the function, it will be pre parsed, and the variable will be undefined if it is printed in advance

    var a=1;//undefined 1
    function fn(){
        console.log(a);//1 No, var Perform pre parsing to find the external a
        a=2;//No, var Pre parse, change through scope chain a
    }
    fn();
    console.log(a);//2

Parameters as local variables are also pre parsed

    var a=1;//undefined 1
    function fn(a){
        //a As a parameter, it is also a local variable, which will also be pre parsed
        console.log(a);//undefined
        a=2;//Modify parameters here a Is 2, the global variable has no effect
    }
    fn();
    console.log(a);//1
    var a=1;//undefined 1
    function fn(a){
        //a As a parameter, it is also a local variable, which will also be pre parsed
        console.log(a);//undefined 1
        a=2;//Modify parameters here a Is 2, the global variable has no effect
    }
    fn(a);//The execution parameters are a=1
    console.log(a);//1

Memory management and garbage collection mechanism

Release useless data and reclaim memory

Automatic JS

Manual Objective-C

Principle: find out useless data, mark it, and release memory; execute periodically

Tag policy: tag clear reference count (not commonly used)

 

IE

JS : BOM  DOM

The BOM and DOM of the old version of IE are implemented on the basis of c++ COM and based on the reference counting method

So even if you use tag cleanup, you still have the problem of circular references

 

memory management

Set to null to dereference

Tags: Javascript Attribute IE Firefox

Posted on Mon, 10 Feb 2020 22:52:59 -0800 by holladb