哈喽哈喽,这里是小菜不拖延博主,没错,博主又新开了一个刷题的专题捏
闭包
leetcode:2620
内部函数可以访问到外部函数的作用域
可以看到本身外部是无法访问到n这个变量的,但是由于我们利于了闭包,内部函数可以访问外部作用域,外部函数返回一个内部函数,所以我们就能通过这个返回的内部函数访问到外部函数内的变量了
function f1(){
var n = 999;
function f2(){
console.log(n);
}
return f2
}
var result = f1();
result();//999
用法
- 读取内部函数的值
- IIFE自执行函数
()()
相当于调用自己,所以就马上执行了
var n = 999;
(function f1(){
console.log(n);
})()
//999
- 封装对象的私有对象和私有方法
- 将外部函数创建的变量值始终保存在内存当中
//代码中f1的内部变量n一直存在内存中,不会在f1调用结束后被自动清除。
function f1(){
var n = 999;
function f2(){
console.log(n++);
}
return f2
}
var result = f1();
result();//999
垃圾回收机制
垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存
内存泄漏
就是不需要某块内存的时候这块内存还存在
垃圾回收算法
引用计数
给每一个对象分配一个引用计数器,对象被创建的初始值为1,被引用一次那么值就+1,反之-1
//hello字符对象被创建,被str1引用,所以值为1
str1 = "Hello"
//被str2引用+1 =2
str2 = str1
//str2改变指向对象,所以值-1=1
str2 = "World"
//str1要是指向别的对象,这个时候hello就会被回收
缺点:无法处理循环引用
这是因为引用计数仅仅根据对象被引用的次数进行计数,而循环引用会导致引用计数始终不为零
let a = {};
let b = {};
a.b = b;
b.a = a;
console.log(a,b)
标记清除
是一种更智能的算法,不需要额外的空间来记录对象引用的情况,在开始阶段遍历所有对象,并且打上标记,在清除阶段遍历对象,把没有被标记的对象视为垃圾进行回收
缺点:
- 遍历和清除的过程当中会暂停程序执行
- 可能存在误判
阅读: