后期画图的时候,省略执行环境栈的绘制,只画执行上下文,默认我们知道,每一个执行上下文出现后, 都要进栈执行
# 浏览器的垃圾回收机制
谷歌等浏览器是基于引用查找
来进行垃圾回收的(自己内部处理)
- 开辟的堆内存,浏览器自己默认会在空闲的时候,查找所有内容的引用,把那些不被引用的内存释放掉
- 开辟的栈内存(上下文),一般在代码执行完都会出栈释放,如果遇到上下文中的东西被外部占用,则不会释放
IE等浏览器是基于计数器
机制来进行内存管理的
- 创建的内存会被引用一次,则计数1,再被引用一次,计数2... 移除引用减去1... 当减为零的时候,浏览器会把内存释放掉
=> 真实项目中,某些情况导致计数规则会出现一些问题,造成很多内存不能被释放掉,产生
内存泄露
;查找引用的方式如果形成相互引用,也会导致内存泄露
// 当前地址被其他地方占用不能被释放掉
let obj = {name: 'dyc'}
let oop = obj
// 释放
obj = null
opp = null
思考题
总结内存泄露导致的情况?(JS高级程序设计第三版 最后章节中有介绍)
# 闭包作用域
- Scope: 作用域,创建函数的时候赋予的
- Scope Chain: 作用域链
# 练习题
# 例1
let x = 1
function A(y){
let x = 2
function B(z){
congsole.log(x+y+z)
}
return B
}
let C = A(2)
C(3)
解析
# 例2
let x = 5
function fn(x){
return function(y){
console.log(y + (++x))
}
}
let f = fn(6)
解析
# 例3
let a = 0,b=0
function A(a){
A = function(b){
alert(a+b++)
}
alert(a++)
}
A(1)
A(2)
解析
# 总结
函数执行会形成全新的私有上下文,这个上下文可能被释放,也可能不被释放,不论是否被释放,它的作用是:
- 保护:划分一个独立的代码执行区域,在这个区域中,有自己私有变量存储的空间,而用到的私有变量和其他区域中的变量不会有任何的冲突(防止全局变量污染)
- 保存:如果上下文不被销毁,那么存储的私有变量的值也不会被销毁,可以被其下级上下文中调取使用
我们把函数执行,形成私有上下文,来保存和保护的机制,称之为闭包
=> 它是一种机制,不是具体的某个形式。
市面上一般认为只有形成私有上下文不被释放,才算是闭包(因为如果一旦释放,之前的东西也就不存在了); 还有人认为,只有一下级上下文用到了此上下文中的东西才算闭包; 如果遇到这些的观点。也是对的。