关于闭包面试题
1. for 循环 setTimeout 500ms 打印出 1-10
看到这个我能想到:js 单线程、for 循环嵌套定时器,for 为主线程,setTimeout 定时器开始时 for 已结束,所以会直接写会打印出 10 个 11
for (var i = 1; i < 11; i++) {
setTimeout(function () {
console.log(i); //10个11
}, 500)
}
for 循环里定义的 i 变量暴露在全局作用域内,于是 10 个定时器共享了同一个作用域里的同一个变量,要想打印 1-10,可以把 var
换成let
,利用 let 的有自己作用域的特点,或者用闭包
去实现,去新建一个作用域
for (let i = 1; i < 11; i++) {
setTimeout(function () {
console.log(i);
}, 500)
}
for (var i = 1; i < 11; i++) {
var a = function () {
var j = i;
setTimeout(function () {
console.log(j);
}, 500)
}
a();
}
补充:
- 一般会出现异步情况的:
网络请求
,定时器
、事件监听
等 - let、const 存在
块级作用域
,var 只存在于函数作用域,存在变量提升
,const 定义的是常量
,一旦被定义无法重新赋值。
2.jq 有哪些地方用到了闭包,或者说你平时见过哪些闭包?
- 闭包产生的原因:由于
函数作用域的封闭性
,函数外部并不能访问函数内部的变量。所以我们一般需要访问函数内部变量时才用到他。 - 我理解的闭包:
- 在函数里面声明函数,子函数可以继承父函数的局部变量(反过来不行)
保护变量不受外界污染,这样可以使父函数内部的变量持久保存。 - 可以模拟全局变量,在面向对象编程时模拟成员私有属性,但是因为闭包太消耗内存,一般能不用就不用。