理解闭包,首先要理解作用域,作用域即变量起作用的范围。而在js中是没有块即作用域的概念的,除了函数中定义的变量外,都是全局作用域。
for(var i=0;i<4;i++){
setTimeout(function(){
console.log(i);
},200);
} //4 4 4 4
解决办法:
for(var i=0;i<4;i++){
(function(j){
setTimeout(function(){
console.log(j);
},200);
})(i)
} //0 1 2 3
作用域链就是变量在作用域中寻找值,自身找不到就向外层作用域查找。
这里还有个概念是执行环境(execution context)
执行环境始终是this关键字的值,它是拥有当前所执行代码的对象的引用,函数的每次调用都会创建一个新的执行环境。当执行流进入一个函数时,函数的执行环境就会被推入环境栈顶端,执行结束后环境栈将其弹出并销毁,把控制权还给之前的执行环境。
在函数的执行过程中会创建作用域链,而在函数执行结束,对应的执行环境和变量对象都会被销毁,而闭包的存在,使得其中的变量能继续被其他函数引用访问
有两种形成闭包的情况。
第一,函数作为返回值
如上代码,bar函数作为返回值,赋值给f1变量。
第二,函数作为参数被传递
如上代码中,fn函数作为一个参数被传递进入另一个函数,赋值给f参数。执行f(15)时,max变量的取值是10,而不是100。
这里要注意 自由变量跨作用域取值时,要去创建这个函数的作用域取值,而不是“父作用域”
使用闭包可以封装变量,使其私有化,但同时闭包会造成内存的大量消耗,导致内存泄漏
参考文档
https://www.cnblogs.com/wangfupeng1988/p/3994065.html
https://juejin.cn/post/6844903781709119501#heading-1
原文:https://www.cnblogs.com/zhouyyBlog/p/14274378.html