一、视频
闭包视频讲解:蛋老师视频
二、未闭包
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i++);
}, 4000)
}
console.log(i);//5
//输出结果为:5,5,6,7,8,9
{
var i = 0
setTimeout(() => {
console.log(i++);
}, 4000)
}
{
var i = 1
//放入任务队列,等待同步任务执行后,再根据延迟时间执行
setTimeout(() => {
console.log(i++);
}, 4000)
}
{
var i = 2
//放入任务队列,等待同步任务执行后,再根据延迟时间执行
setTimeout(() => {
console.log(i++);
}, 4000)
}
{
var i = 3
//放入任务队列,等待同步任务执行后,再根据延迟时间执行
setTimeout(() => {
console.log(i++);
}, 4000)
}
{
var i = 4
//放入任务队列,等待同步任务执行后,再根据延迟时间执行
setTimeout(() => {
console.log(i++);
}, 4000)
}
{
var i = 5
// i<5不成立,不继续执行
}
// 执行全局console.log(i),输出i等于5
// 4000ms延迟时间到,此时var=5(var没有块级作用域,除了function函数),所以输出5次 console.log(i++)
// 输出5,6,7,8,9
注:
1.setTimeout是异步,先放到任务队列,同步执行完后,任务队列里面再根据时间执行;
2.var没有块级作用域,所以for循环之后,i的值变为5,所以全局先输出5
3.匿名函数可以访问到外部i的值
三、采用闭包
for (var i = 0; i < 5; i++) {
(function (x) {
setTimeout(function () {
console.log(x++);
}, 400)
})(i)
}
console.log(i);//5
输出结果:5 0,1,2,3,4
{
var i = 0
//i=0放入形参中,再执行里面的延迟函数,之后放入任务队列,等待同步任务执行后,再根据延迟时间执行
(function (x) {
setTimeout(function () {
console.log(x++);
}, 400)
})(i)
}
{
var i = 1
//i=1放入形参中,再执行里面的延迟函数,之后放入任务队列,等待同步任务执行后,再根据延迟时间执行
(function (x) {
setTimeout(function () {
console.log(x++);
}, 400)
})(i)
}
{
var i = 2
//i=2放入形参中,再执行里面的延迟函数,之后放入任务队列,等待同步任务执行后,再根据延迟时间执行
(function (x) {
setTimeout(function () {
console.log(x++);
}, 400)
})(i)
}
{
var i = 3
//i=3放入形参中,再执行里面的延迟函数,之后放入任务队列,等待同步任务执行后,再根据延迟时间执行
(function (x) {
setTimeout(function () {
console.log(x++);
}, 400)
})(i)
}
{
var i = 4
//i=4放入形参中,再执行里面的延迟函数,之后放入任务队列,等待同步任务执行后,再根据延迟时间执行
(function (x) {
setTimeout(function () {
console.log(x++);
}, 400)
})(i)
}
{
var i = 5
// i<5不成立,不继续执行
}
// 执行全局console.log(i),输出i等于5,因为此时var=5,并且var不支持块级作用域
//调用任务队列里面的
/*(function (x) {
setTimeout(function () {
console.log(x++);
}, 400)
})(i)*/
// 依次输出0,1,2,3,4