闭包机制

javaScript

后期画图的时候,省略执行环境栈的绘制,只画执行上下文,默认我们知道,每一个执行上下文出现后, 都要进栈执行

# 浏览器的垃圾回收机制

谷歌等浏览器是基于引用查找来进行垃圾回收的(自己内部处理)

  • 开辟的堆内存,浏览器自己默认会在空闲的时候,查找所有内容的引用,把那些不被引用的内存释放掉
  • 开辟的栈内存(上下文),一般在代码执行完都会出栈释放,如果遇到上下文中的东西被外部占用,则不会释放

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)

解析 dyc

# 例2

let x = 5
function fn(x){
    return function(y){
        console.log(y + (++x))
    }
}
let f = fn(6)

解析 dyc

# 例3

let a = 0,b=0
function A(a){
    A = function(b){
        alert(a+b++)
    }
    alert(a++)
}
A(1)
A(2)

解析 dyc

# 总结

函数执行会形成全新的私有上下文,这个上下文可能被释放,也可能不被释放,不论是否被释放,它的作用是:

  • 保护:划分一个独立的代码执行区域,在这个区域中,有自己私有变量存储的空间,而用到的私有变量和其他区域中的变量不会有任何的冲突(防止全局变量污染)
  • 保存:如果上下文不被销毁,那么存储的私有变量的值也不会被销毁,可以被其下级上下文中调取使用

我们把函数执行,形成私有上下文,来保存和保护的机制,称之为闭包 => 它是一种机制,不是具体的某个形式。

市面上一般认为只有形成私有上下文不被释放,才算是闭包(因为如果一旦释放,之前的东西也就不存在了); 还有人认为,只有一下级上下文用到了此上下文中的东西才算闭包; 如果遇到这些的观点。也是对的。

Last Updated: 2021-04-26 14:38:08