js闭包的代码示例讲解

如果下载的源码需要作者授权,请更换源码。本站免费分享资源不会增加授权

本篇文章给大家带来的内容是关于js闭包的代码示例讲解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

准确来说,闭包是基于正常的垃圾回收处理机制下的。也就是说,一般情况一个函数(函数作用域)执行完毕,里面声明的变量会全部释放,被垃圾回收器回收。但闭包利用一个技巧,让作用域里面的变量,在函数执行完之后依旧保存没有被垃圾回收处理掉。

闭包

定义

MDN定义

javascriptkit

词法作用域

作用域链

函数在执行的过程中,先从自己内部找变量如果找不到,再从创建当前函数所在的作用域(词法作用域)去找, 以 此往上注意找的是变量的当前的状态

作用域链的博客

函数连同它作用域链上的要找的这个变量,共同构成闭包

一般情况下使用闭包主要是为了

封装数据

暂存数据

一个典型的闭包案例

function car(){  var speed = 0  function fn(){  speed++  console.log(speed)  }  return fn } var speedUp = car() speedUp() //1 speedUp() //2

当函数内部没有执行以下的代码时

function fn(){  speed++  console.log(speed)  } return fn

在代码执行完成后,函数内部的局部变量speed就会被销毁,由于全局标量speedUp一直存在(除非关闭当前页面,否则全局变量一直存在),那么函数内部的作用域就没有办法被销毁,里面有东西一直被使用,这点与浏览器的垃圾回收机制相仿,当我们执行speedUp(),他会在函数的词法作用域下去寻找,函数里面又返回了一个fn,因而形成闭包,简单的理解为

var speed = 0 function fn(){  speed++  console.log(speed) }

这一段代码形成一个闭包,如果不return fn,那函数内部的局部变量就会被销毁。

我们可以看看上述代码利用立即执行语句和立即执行函数可以怎么演变:

function car(){  var speed = 0  function fn(){  speed++  console.log(speed)  }  return fn } var speedUp = car() //1 function car(){  var speed = 0  return function (){  speed++  console.log(speed)  } } var speedUp = car() //2 function car(speed){  return function (){  speed++  console.log(speed)  } } var speedUp = car(3) //3 function car(){  var speed = arguments[0]  return function (){  speed++  console.log(speed)  } } var speedUp = car() //4 function 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( fnArr[3]() ) // 10

同等演变

假设只有两层循环:

var fnArr = [] for (var i = 0; i < 2; i ++) {  fnArr[i] = (function(j){  return function(){  return j  }   })(i) } fnArr[3]() //1 var fnArr = []  fnArr[0] = (function(j){  return function(){  return j  }   })(0) } fnArr[1] = (function(j){  return function(){  return j  }   })(1) } fnArr[3]() //2 var a = (function(j){  return function(){  return j  }   })(0) } var b = (function(j){  return function(){  return j  }   })(1) } b() //3 var a = (function(j){  return function(){  return j  }   })(0) } function fn2(j){  return function(){  return j  } } var b = fn2(1) //4 var a = (function(j){  return function(){  return j  }   })(0) } function fn2(j){  return function(){  return j  }  return f } var b = fn2(1) //5 var 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( fnArr[3]() ) // 3 var fnArr = [] for (var i = 0; i < 10; i ++) {  (function(i){  fnArr[i] = function(){  return i  }   })(i) } console.log( fnArr[3]() ) // 3 var fnArr = [] for (let i = 0; i < 10; i ++) {  fnArr[i] = function(){  return i  }  } console.log( fnArr[3]() ) // 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() //30 Car.speedUp() Car.get() //31 Car.speedDown() Car.get() //3

如下代码输出多少?如何连续输出 0,1,2,3,4

for(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() ) // 0 console.log( counter() ) // 1 console.log( counter2() ) // 0 console.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) ) // 3 console.log( sum(5)(-1) ) // 4
 收藏 (0) 打赏

入群打赏请备注QQ,购买打赏请备注邮箱

支付宝扫一扫赞助

微信钱包扫描赞助

未经5G云允许不得转载:5G云源码分享网 » js闭包的代码示例讲解

评论 抢沙发

评论前必须登录!

立即登录   注册

5G云源码 更专业 更方便

关于5G云联系我们
切换注册

登录

忘记密码 ?

切换登录

注册

我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活