多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
**闭包的定义:闭包是指有权访问另外一个函数作用域中的变量的函数** 闭包就是一个函数A内部有另一个函数B,函数B可以访问到函数A的变量和方法,此时函数B就是闭包 **闭包存在意义** 在Js中,闭包存在的意义就是让我们可以间接访问到函数内部的变量**(函数内部变量的引用也会在内部函数中,不会因为执行完函数就被销毁,但过多的闭包会造成内存泄漏)** #### 闭包的三个特性 * **闭包可以访问当前函数以外的变量** ``` function getOuter(){ var data = 'outer' function getDate(str){ console.log(str + data) // 访问外部变量 'data' } return getDate('I am') } getOuter() // I am outer ``` * **即使外部函数已经返回,闭包仍能访问外部函数定义的变量** ``` function getOuter(){ var date = '815'; function getDate(str){ console.log(str + date); //访问外部的date } return getDate; //外部函数返回 } var today = getOuter(); today('今天是:'); //"今天是:815" today('明天不是:'); //"明天不是:815" ``` * **闭包可以更新外部变量的值** ``` function updateCount(){ var count = 0; function getCount(val){ count = val; // 更新外部函数变量 console.log(count); } return getCount; //外部函数返回 } var count = updateCount(); count(815); //815 count(816); //816 ``` ### 闭包原理 >js解释器在遇到函数定义的时候,会自动把函数和他可能使用的变量(包括本地变量和父级和祖先级函数的变量(自由变量))一起保存起来。 也就是构建一个闭包,这些变量将不会被内存回收器所回收,只有当内部的函数不可能被调用以后(例如被删除了,或者没有了指针),才会销毁这个闭包, 而没有任何一个闭包引用的变量才会被下一次内存回收启动时所回收。 #### 经典面试题:循环中使用闭包解决var定义的问题(循环输出0-5,结果却是一堆6?) ``` for (var i = 0; i <= 5; i++) { setTimeout(function () { console.log(i) }, 1000 * i) } // 6,6,6,6,6,6 for(var i = 1;i <= 5; i++){ (function(j){ setTimeout( () => { console.log(j) },j * 1000) })(i) } // 0,1,2,3,4,5 // Tips:通过let定义i也能够解决,因为let具有块级作用域 ```