理解“闭包”

理解闭包,首先要理解作用域,作用域即变量起作用的范围。而在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

posted @ 2021-01-13 20:50  周周的一周  阅读(116)  评论(0)    收藏  举报