作用域链是什么
函数在使用一个变量的时候,会查找这个变量,如果自己内部没有,就会向上找,这个查找的过程就叫 作用域链
普通函数的作用域链
1、创建一个函数fn()时,会创建一个包含全局变量的作用域链,保存在该函数的[[scope]]属性中。
2、抵用函数fn()时,为此函数创建一个执行环境。、
3、然后复制函数的scope属性,构建起执行环境的作用域链
3、此后,函数内部创建的活动对象,推入执行环境作用域的前端(【0】位置)
闭包的作用域链
1.内部函数innerfn()创建相对于自己的全局变量作用域链,保存在Scope属性中。
2、对于内部函数而言,外部函数中的活动对象(局部变量)也属于自己的作用域链。
3、及时外部函数执行完毕,但仍然在内部函数的属性(scope 作用域链)中进行引用
及时外部函数的执行环境/作用域链全部销毁,但是变量还在内存中留着
4、根据 垃圾回收机制,被引用的变量不回回收吗,因此会产生内存泄露
举例 (闭包+使用场景)
function f1() {
// 被闭包使用
let n = 100
// 闭包f2
function f2() {
n = n + 100 // 作用域链:f2内部没有n,向上一层在f1中查找到n
// 每次调用f2的时候,n都会使用上次更改后的值
console.log(n)
}
// 返回的是函数f2
return f2
}
var temp = f1() // temp本质 = f2
temp() // 200 // 本质=f2()
temp() // 300 // 本质=再次f2(),这时候再次对n进行修改。这时获取到的n是200了。
解决办法:取消引用
temp = null // 取消对闭包(内部函数)的引用