[TOC]

闭包:
当内部函数被保存到外部时,将会生成闭包。闭包会导致原有的作用域链不释放,造成内存泄漏。
内存泄漏:
内存被占用,可用的内存变少。
指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束!

闭包实例:

b被返回并保存在demo中,且b用到了a中的变量。因此该函数是闭包

实例2:

分析

  1. 整体分析后发现这是一个闭包,a函数执行完毕时,a中的aAO链断裂,b中产生的aAO链并没有断开,这里的aAO其实是同一个,只是生成了两个指针(指向)
  2. 第一次执行demo时,会在b函数内部bAO找num变量,发现没有,顺着b的scope-chain找到aAO中有num(此时num=100),将其加1,所以打印101,
  3. 第一个demo执行完毕,将其自身的bAO链断裂。但是b中的aAO并没有断裂
  4. 执行第二个demo时,重新建立bAO,找num变量没找着,就顺着scope-chain开始找aAO的num,发现此时aAO中的num为101,将其加一,所以第二次打印102。

立即执行函数:

  • 立即执行函数的两种方式。(执行完后立即被销毁)
    • ( function () {} () ) // 推荐第一种
    • ( function () {} )()
  • 只有表达式才可以被执行符号执行:
    • 函数表达式:var a = function () {}() // 正常执行该函数,但是需要注意执行完后打印a显示undefined
    • 函数声明:function a(){} // SayntaxError 语法错误
  • 若函数声明后边的执行括号里传参数,机器不会报错,他会理解成两条语句:
    | | | —- |

实例

分析:

  1. test函数开始执行时(初始化时),testAO对象和GO中是这样的:
    | | | —- |

  2. test执行完时,testAO的变化,执行test()时,变量只有两个arr和i(for循环是块级作用域,js没有该作用域,只有函数作用域),当经过for循环时,不断往arr数组里赋值,但此时函数并没用执行,只是将函数体push进arr里,(这时function匿名函数的域中会有两条链,一个指向testAO,一个指向GO)当i==10时,arr停止赋值,for循环结束,将arr返回,test函数执行结束,自己指向的testAO链断掉,但是匿名函数没有断掉 | | | —- |


  3. 当分别执行arr里的函数时(闭包),此时function匿名函数的执行期上下文里没有i,顺着作用域链自定而下找到testAO有i,此时i等于10,因此打印出十个10。

就想打印1,2,3,……9咋解决?

  1. 利用this
  2. 利用let的特性(块级作用域)
  3. 立即执行函数(闭包问题闭包解决)

扩展:(作者code秘密花园)
变量的赋值可以分为三个阶段:

  • 创建变量,在内存中开辟空间
  • 初始化变量,将变量初始化为undefined
  • 真正赋值

关于letvarfunction

  • let 的「创建」过程被提升了,但是初始化没有提升。
  • var 的「创建」和「初始化」都被提升了。
  • function 的「创建」「初始化」和「赋值」都被提升了。

如有错误,欢迎指出~