前端面试之什么是闭包
当一个前端程序员被问到什么是闭包,和一个人被问到什么是人有异曲同工之妙。
对于前者,一直在用闭包,却很难用语言去描述它,又不能抖个机灵,我查了下什么是苹果,维基百科说道:"苹果,又称柰或林檎,是苹果树(学名:Malus pumila)的果实"。
不过,这个问题引发的思考,却让我收获颇丰
函数内部与函数外部之间的关系就是闭包
当你创建了一个函数,就是创建了一个闭包
<script>
function able() {}
</script>
能够访问上层作用域链是闭包的特性
function able() {
let i = 0,
j = 12;
function test() {
console.log(i++);
console.dir(arguments.callee);
}
function test1() {
console.log(i++);
console.dir(arguments.callee);
}
test();
test1();
console.log(i);
}
![](https://img.haomeiwen.com/i3004133/8a625506f7de931d.png)
最后
i
的值是2,并没有j
的值,因为存储到了[[scrop]]
中,所以不在当前上下文也能够正常执行返回一个函数
<script>
function able() {
let i = 0,
j = 12;
return function () {
console.log(i++);
console.dir(arguments.callee);
};
}
const test = able();
const test2 = able();
test1();//0
test1();//1
test2();//0
test2();//1
</script>
作为宏任务
<script>
window.onload = function () {
for (let i = 0; i < 10; i++) {
var a = document.createElement('a');
a.innerHTML = i + '<br/>';
a.onclick = function () {
console.dir(arguments.callee);
console.log(i++);
};
document.body.append(a);
}
};
</script>
![](https://img.haomeiwen.com/i3004133/8c76f23b85ca3579.png)
内存泄漏是指不可达的内存无法被释放,跟闭包本身无关,跟错误的逻辑有关
基本类型依附在函数内部,存在栈中,当函数出栈后立即被销毁,当访问了上层作用域链,就会通过[[scope]]
进行记录,形成了一个新的作用域链,会增大内存,这并不代表着就一直存在内存当中
几乎不需要手动设置为null
,除非和全局概念的东西绑定在一起,比如你不想让果子掉在地上,把果子和树枝绑定在一起,那所在的大树杈断了,照样会掉在地上。
可以用来合理划分变量层级,状态共享,实现私有变量,对外提供函数屏蔽内部细节,脱离执行上下文访问内部变量,实现柯里化减少不必要的传递。
日常开发中我们更应该去关心闭包对程序的可读性、可维护性的影响,例如,不合理的使用闭包特性,导致对数据的操作逻辑零散在各个部分。
大文件上传与闭包
2020 - 03 - 19
假设有一个超大的文件,一次性上传接口容易延迟,因此在前端进行分段上传,有一个upload
方法统一处理,大概就是转为Blob
对象,截取分段,创建ajax对象上传,如果还有,再截取分段,创建ajax对象上传。
用户可以重新上传,那如何终止上一次的上传呢?
重新上传会再次调用upload
方法,这与前一个upload
方法的"内部生态"完全不同,相当于开辟了一块新内存,但是他们却必然有相同的"外部作用域"
所有我们可以在调用upload
方法时传一个时间戳,在内部就通过形参保存就好,在进行下一次分端上传之前,判断时间戳和外面的一样就继续上传,不一样就停止,因为再次调用upload方法,外面的时间戳也会更新。
本文将持续更新
关注专题 前端便利店 https://www.jianshu.com/c/c3f77a86d9a5 ,帮您省时省力!