预解析

  • 代码运行到浏览器,浏览器提供了一个供JS代码执行的环境(栈区),在代码执行之前先进行预解析;预解析完成了,代码才会执行。
  • 预解析又称为变量提升,预解析会对所有(全局与局部)带有var和function关键字的进行预解析;
  • 预解析分为以下两部分:
    • 声明 var a;
    • 定义 a=100;(赋值)
  • var的预解析只声明不定义;function的预解析声明+定义(function在预解析的声明+定义已经完成了)

知识点:

  • js中分为两大区域

    1. 栈区:提供代码运行的环境
    2. 堆区:存储引用数据类型的值
  • js中一旦遇到引用数据类型,就会开辟一块内存,将引用数据类型的值进行储存,并给这块堆内存分配一个16进制地址。

  • 函数执行会生成一个私有作用域,里面代码从上到下执行。(栈区)

栗子1:

1
2
3
4
5
6
7
console.log(a,b); //undefined undefined
var a = 100;
var b = 200;
sum();
function sum(){
console.log("2022平安喜乐") //2022平安喜乐
}

解析:

先进行预解析,预解析完了,代码从上往下开始运行;堆区是存储的,栈区才是代码执行;

栗子1

栗子2:

Tips:先把外层的函数合起来,这样就好分析了。

1
2
3
4
5
6
7
8
9
10
11
12
13
console.log(a, b); //undefined undefined
var a = 100;
var b = 200;
sum();
function sum() {
console.log(a, b);//undefined undefined
var a = 1000;
var b = 2000;
hello();
function hello() {
console.log("2022平安喜乐") //2022平安喜乐
}
}

解析:

栗子2

栗子3:

Tips:先把外层的函数合起来,这样就好分析了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var a = 100;
var b = 200;
var c = 300;
function test1(num1) {
var a = 10;
var b = 20;
a++;
b++;
c++;
num1++;
console.log(a, b, c, num1);
function test2() {
var c = 30;
a++;
b++;
c++
console.log(a, b, c);
}
test2();
}
test1(5);
console.log(a, b, c);

知识点:

作用域链:

作用域链,是一种查找机制,在当前作用域下用到某个变量或方法,先看当前这个作用域有没有,有先用自己私有的,没有往上一级作用域进行查找,上一级作用域没有,再往上一级作用域进行查找,知道找到全局作用域为止(window为止)

栗子3

PS:函数执行完成会自动销毁,定义一个函数可以调用无数次,每次相互独立的;即从xxxfff000<=>test(1)执行完,就销毁释放内存了;