了解闭包必须得掌握三个个知识点 一个是 作用域链 一个是 函数生命周期 一个是 JS 引用类型
作用域链:就是多个作用域连接到一起 形成的链式结构(类似于父子级关系,可以是祖孙关系) 这个时候 子级作用域需要一个变量的时候 会先在自身里面找 自身没有就找爹要 爹没有就找爷要 一直找到window(全局)如果window没有就报错
函数声明周期:每一个函数分为两种储存方式: 一个是调用时 ,一个是没调用时 (活着的 , 死着的) 而调用时会创建一个活动对象(函数作用域对象)AO :这个对象就是保存着所有的局部变量 ;当函数执行结束, 这个对象就会随着释放 ,里面的变量也就会随着消失。所以函数重复使用的时候 ,里面的变量每次都是初始值。
引用类型:JS 数据类型在储存方式上分为两种: 一种是原始类型(Number String Boolean Undefined Null) ,一种是引用类型。 所有的引用类型当不再被引用的时候都会被JS的垃圾回收装置 回收掉 ,就是彻底消失内存中不再存在。
不涉及深层内容只讨论闭包的作用的话。闭包就是 :让一个函数的活动对象不被释放。 这样的话 ,函数内部所有的变量将不会消失可以继续使用。
而实现的方法就是 :让这个函数(外层函数)去返回一个新的函数(内层函数,内层函数的保存形式是多种的 可以保存在数组中 但是重点是 内层函数引用外层函数的活动对象) ,内层函数会自动引用外层函数的活动对象 (利用作用域链) 但是内层函数 调用之后会释放掉 从而外层函数也释放了 解决的方法就是 用一个变量去引用 内层函数 这样就形成了闭包。
而至于闭包调用完后变量的存储及自身值的问题,函数声明周期中有提到,更简单的理解就是:emmm,闭包函数有个特殊的小房子来存变量,每次调用的时候将变量取出来,调用完得到他想要的结果后再将这个变量放回去,这个过程中只是使用了变量的值,却没有影响变量本身什么,所以回到小房子里变量还是当初那个变量,不会因为被调用而改变什么。
举个栗子:
var getName=fun(); 可以视为这是第一次函数调用,这时的a值还是10,在此后的 getName();运行中,将它看做仍属于第一次调用,即a的值会因为a++而一直叠加,所以最后三个结果为:10 11 12;
而 var aa=fun();敲重点! 视之为第二次函数调用,此时a的值仍为初始值10,即在第一次调用完后,a=10又原封不动的回到了小房子,安安静静的等第二次调用来领它走,同理:如果还有一行代码再次调用fun(),那么不论aa对a的值做什么,下一次调用时,a仍然等于10.
emmmm,后续有问题再补吧,不过可能性不大。手动滑稽.gif.