# 四.同步编程
前言
- 创建执行环境
- 执行前预解释
- 执行中入栈、出栈
# 1.执行环境
js
代码会在一个栈
中执行代码,这个栈
称为执行栈
,由于栈
的特性为先进后出
,所以同步代码会首先进入栈
底、在代码执行的过程中,如果遇到要执行的函数会再次进栈,重复上述过程,直到没有入栈代码
然后栈
顶代码执行完后就出栈
,直到整个栈
没有代码,至此代码执行完成
# 2.预解释
js 是单线程,同步代码会从上往下执行,但代码在进入执行栈
前会先将代码扫描一遍,会将声明的变量放到代码块的最前面即变量提升
,此过程称为预解释
var
声明的代码会被提前到作用域
顶部
console.log("a:" + a)
var a = 1
1
2
2
不会报错
实际执行顺序
var a
console.log("a:" + a)
a = 1
1
2
3
2
3
- 5.var、变量提升
//在全局作用域中,带var和不带var的关系
//区别:带var的可以进行预解释,所以在赋值的前面执行不会报错;不带var的是不能进行预解释,在前面执行会报错
console.log(num) //-->undefined
var num = 12
console.log(num2) //VM229:1 Uncaught ReferenceError: num2 is not defined
num2 = 12
//关系:num2 = 12-->相当于给window增加了一个叫做num2的属性名,属性值是12
//var num = 12 -->首先它相当于给全局作用域增加了一个全局变量num,但是不仅如此,它也相当于给windwo增加了一个属性名num,属性值是12
var num = 12
console.log(num)
num2 = 12
console.log(num2)
//私有作用域中出现一个变量不是私有的,则往上级作用域查找,如果上级作用域没有则继续向上查找,一直找到window为止,如果window下也没有
//-->我们是获取值:console.log(total) -->报错了
//-->我们是设置值:total = 100 -->相当于给window增加了一个属性名total,属性值是100
function fn() {
// console.log(total)
total = 100
}
fn()
console.log(total)
//js中如果不进行任何特殊处理的情况下,上面的代码报错,下面的代码都不在执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 3.入栈
# 3.1 作用域
代码进入执行栈前会创建一个执行上下文
,就是当前执行栈中要执行的代码执行时所需要的一些信息,可以查询当前要执行的代码中某些变量的值,这些值就存储在当前作用域
中
# 3.2 作用域链
当函数有多层嵌套时,通过一层一层压栈后,最里面的函数先执行,如果所需要的变量在当前作用域中没有找到就会顺着作用域向上查找上一个作用域,直到找到最顶层的作用域,这种层层查找形成的链状现象称为作用域链
# 3.3 变量赋值
代码从上往下执行,当需要查询变量时,先去当前的作用域
中查找,当遇到有要执行的函数
时,会重复上述动作,进行入栈操作
# 4.出栈
当代码执行完成后,当前作用域
内没有变量被其他地方使用就会出栈,如果有被使用,变量就会常驻内存
中,形成了不销毁的作用域
,这个过程称为闭包