「 涵盖的核心知识点 」
- 变量声明提升(var)
- 块级作用域(let、const)
- JS单线程
- 宏任务(EventLoop)
- 闭包
看一段代码,描述它做了什么?
for(var i = 0; i < 5; i++) {
console.log(i);
}
问题一:上面for循环执行顺序是什么?
- var i = 0; -------- 表达式1;
- i < 5; ------------ 表达式2;
- {console.log(i);}-- 代码块3;
- i++; -------------- 表达式4;
第一次执行:表达式1;表达式2;代码块3;表达式4;
第二次执行:表达式2;代码块3;表达式4;
第三次执行:表达式2;代码块3;表达式4;
...... 直到 (表达式2) 为假结束循环。
问题二:执行的时候做了什么?
//变量声明提升
var i;
for(i = 0; i < 5; i++) {
console.log('内部i',i);//0 1 2 3 4
}
console.log('外层i',i);// 5
//外层打印5的原因?
//因为for循环是同步执行的,所以只有当for循环结束以后才会执行外层console.log('外层i',i),此时i是5。
再来看一段代码
var i;
for(i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);//5 5 5 5 5
}, 10);
}
//打印5的原因?
//因为js是单线程的,一次只能执行一段代码,也就是同步执行,会发生阻塞。那么js引擎在解析js代码的时候遇到宏任务时会把它放入宏任务队列,等待同步任务执行完毕再去执行宏任务。(这里不考虑微任务和多个宏任务)
如何解决上面问题呢?
//方法一 块级作用域:
for(let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);//5 5 5 5 5
}, 10)
}
//方法二 闭包:
for(var i = 0; i < 5; i++) {
(function(j){
setTimeout(() => {
console.log(j);//0 1 2 3 4
}, 10)
})(i);
}
详解块级作用域
当使用let、const时会产生块级作用域,什么是块级作用域?
{
let a = 10;
var b = 20;
}
//console.log(a);//报错 a is not defined
//console.log(b);// 20
//花括号包裹的这个环境就是块级作用域,块级作用域外面无法访问,那么for循环中let定义的i只在当前循环中有效,
// 那在下一次循环时是如何拿到上一次的i值呢?
//js引擎会帮我们记住上一次的值。
补充知识: 暂时性死区? 在let const声明变量xxx之前都属于暂时性死区。
面试for循环有的聊了... 随便记录一下。欢迎各位大佬补充修正...