https://www.nowcoder.com/test/question/done?tid=15047766&qid=56240#summary
本来以为闭包的知识已经掌握了,但通过最近刷题发现其实只懂个一二,再整理整理吧。
以前了解到的闭包:外部函数内部声明了内部函数,在内部函数中引入了外部函数的局部变量,当外部函数执行完毕后,这个局部变量不会被释放。最典型的应用是利用for循环给li绑定onclick事件(这个问题不用闭包可以用let声明i的方式解决)
for(var i=0;i<aLi.length;i++){
(function(){
aLi[i].onclick = function(){
console.log(i);
}
})(i); //闭包加函数的立即调用
}
2021.1.23
函数定义的作用域与调用处的作用域不是一个,那就形成了闭包,比如在一个A函数中定义了一个B函数,在A以外的作用域下,比如全局作用域中调用B,此时A函数被调用过了,要准备开始进行垃圾回收,但此时B还在作用域内,所以A的这个作用域就需要存在着。
如果把上面的代码写成下面的形式,仍然只会输出 aLi 的长度,不会按照索引顺序输出,在立即执行函数形成的作用域里,没有自己的变量,仍然使用的是遍历的 i,在IIFE里把 i 赋值给函数内变量 j,或者把 i 作为 IIFE 的参数传入,可以正常输出
for(var i=0;i<aLi.length;i++){
(function(){
aLi[i].onclick = function(){
console.log(i);
}
})(); //闭包加函数的立即调用
}
js是解释型语言,包括解释和执行两个阶段:
- 解释阶段:进行词法分析生成一个一个的词法单元、语法分析生成元素逐级嵌套的程序语法结构树AST树、生成计算机可执行的代码指令;
- 执行阶段:创建执行上下文、执行函数代码、垃圾回归
js的作用域是在定义的时候就确定的
var tomorrow = '上班';
function person() {
console.log(tomorrow)
}
function worker() {
var tomorrow = '请假';
person();
}
worker();
这段函数的输出是上班,全局作用域调用了woker函数,worker函数里调用了person函数,在全局作用域下和worker函数里都有tomorrow变量的定义,它会取哪个的值呢?js的作用域是在定义时候形成的,不是调用的时候,所以person使用的是它定义时候的作用域里的tomorrow,打印结果是上班