准确来说,闭包是基于正常的垃圾回收处理机制下的。也就是说,一般情况一个函数(函数作用域)执行完毕,里面声明的变量会全部释放,被垃圾回收器回收。但闭包利用一个技巧,让作用域里面的变量,在函数执行完之后依旧保存没有被垃圾回收处理掉。闭包定义MDN定义javascriptkit词法作用域作用域链函数在执行的过程中,先从自己内部找变量如果找不到,再从创建当前函数所在的作用域(词法作用域)去找, 以 此往上注意找的是变量的当前的状态作用域链的博客函数连同它作用域链上的要找的这个变量,共同构成闭包一般情况下使用闭包主要是为了封装数据暂存数据一个典型的闭包案例function car(){ var speed = 0 function fn(){ speed++ console.log(speed) } return fn}var speedUp = car()speedUp() //1speedUp() //2当函数内部没有执行以下的代码时function fn(){ speed++ console.log(speed) }return fn在代码执行完成后,函数内部的局部变量speed就会被销毁,由于全局标量speedUp一直存在(除非关闭当前页面,否则全局变量一直存在),那么函数内部的作用域就没有办法被销毁,里面有东西一直被使用,这点与浏览器的垃圾回收机制相仿,当我们执行speedUp(),他会在函数的词法作用域下去寻找,函数里面又返回了一个fn,因而形成闭包,简单的理解为var speed = 0function fn(){ speed++ console.log(speed)}这一段代码形成一个闭包,如果不return fn,那函数内部的局部变量就会被销毁。我们可以看看上述代码利用立即执行语句和立即执行函数可以怎么演变:function car(){ var speed = 0 function fn(){ speed++ console.log(speed) } return fn}var speedUp = car()//1function car(){ var speed = 0 return function (){ speed++ console.log(speed) }}var speedUp = car()//2function car(speed){ return function (){ speed++ console.log(speed) }}var speedUp = car(3)//3function car(){ var speed = arguments[0] return function (){ speed++ console.log(speed) }}var speedUp = car()//4function car(){ var speed = 0 return function (){ speed++ console.log(speed) }}//5 car可以不写,则为匿名函数 var speedUp = (function car(speed){ return function (){ speed++ console.log(speed) }})(3)闭包的相关案例如下代码输出多少?如果想输出3,那如何改造代码?var fnArr = [];for (var i = 0; i < 10; i ++) { fnArr[i] = function(){ return i };}console.log( fnArr3 ) // 10同等演变假设只有两层循环:var fnArr = []for (var i = 0; i < 2; i ++) { fnArr[i] = (function(j){ return function(){ return j } })(i)}fnArr3//1var fnArr = [] fnArr[0] = (function(j){ return function(){ return j } })(0)}fnArr[1] = (function(j){ return function(){ return j } })(1)}fnArr3//2var a = (function(j){ return function(){ return j } })(0)}var b = (function(j){ return function(){ return j } })(1)}b()//3var a = (function(j){ return function(){ return j } })(0)}function fn2(j){ return function(){ return j }}var b = fn2(1)//4var a = (function(j){ return function(){ return j } })(0)}function fn2(j){ return function(){ return j } return f}var b = fn2(1)//5var a = (function(j){ return function(){ return j } })(0)}function fn2(j){ var j = arguments[0] function f(){ return j } return f}var b = fn2(1)改造后(立即执行语句,演变过程)var fnArr = []for (var i = 0; i < 10; i ++) { fnArr[i] = (function(j){ return function(){ return j } })(i)}console.log( fnArr3 ) // 3var fnArr = []for (var i = 0; i < 10; i ++) { (function(i){ fnArr[i] = function(){ return i } })(i)}console.log( fnArr3 ) // 3var fnArr = []for (let i = 0; i < 10; i ++) { fnArr[i] = function(){ return i } }console.log( fnArr3 ) // 3封装一个 Car 对象var Car = (function(){ var speed = 0; function set(s){ speed = s } function get(){ return speed } function speedUp(){ speed++ } function speedDown(){ speed– } return { setSpeed: setSpeed, get: get, speedUp: speedUp, speedDown: speedDown }})()Car.set(30)Car.get() //30Car.speedUp()Car.get() //31Car.speedDown()Car.get() //3如下代码输出多少?如何连续输出 0,1,2,3,4for(var i=0; i<5; i++){ setTimeout(function(){ console.log(‘delayer:’ + i ) }, 0)}输出结果为:delayer:5(连续输出5个),执行setTimeout时,代码会挂到任务队列中区,待i遍历完成之后执行,而此时i = 5,所以输出delayer:5(连续输出5个)修改后for(var i=0; i<5; i++){ (function(j){ setTimeout(function(){ console.log(‘delayer:’ + j ) }, 0)//1000-1000*j })(i)}或者for(var i=0; i<5; i++){ setTimeout((function(j){ return function(){ console.log(‘delayer:’ + j ) } }(i)), 0) }如下代码输出多少?function makeCounter() { var count = 0 return function() { return count++ };}var counter = makeCounter()var counter2 = makeCounter();console.log( counter() ) // 0console.log( counter() ) // 1console.log( counter2() ) // 0console.log( counter2() ) // 1补全代码,实现数组按姓名、年纪、任意字段排序var users = [ { name: “John”, age: 20, company: “Baidu” }, { name: “Pete”, age: 18, company: “Alibaba” }, { name: “Ann”, age: 19, company: “Tecent” }]users.sort(byName) users.sort(byAge)users.sort(byField(‘company’))解答function byName(user1, user2){ return user1.name > user2.name}function byAge (user1, user2){ return user1.age > user2.age}function byFeild(field){ return function(user1, user2){ return user1[field] > user2[field] }}users.sort(byField(‘company’))写一个 sum 函数,实现如下调用方式console.log( sum(1)(2) ) // 3console.log( sum(5)(-1) ) // 4最后,祝大家早日学有所成,拿到满意offer,快速升职加薪,走上人生巅峰。