首页 > 网络编程 > JavaScript > 正文

js中的闭包实例展示_javascript技巧

2018-11-10 10:00:53

前言

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

闭包

定义

MDN定义

javascriptkit

词法作用域

闭包的三大特点为:

1、函数嵌套函数

2、内部函数可以访问外部函数的变量

3、参数和变量不会被回收。

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

作用域链的博客

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

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

  • 封装数据
  • 暂存数据

一个典型的闭包案例

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( fnArr[3]() ) // 10

同等演变

假设只有两层循环:

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

您可能感兴趣的文章:

  • javascript深入理解js闭包
  • 一分钟理解js闭包
  • JavaScript 匿名函数(anonymous function)与闭包(closure)
  • 前端开发必须知道的JS之闭包及应用
  • JavaScript闭包 懂不懂由你反正我是懂了
  • JavaScript闭包函数访问外部变量的方法
  • js闭包的用途详解
  • 详谈JavaScript 匿名函数及闭包
  • 一不小心就做错的JS闭包面试题
  • JavaScript中闭包的写法和作用详解
  • 相关标签:JavaScript
  • 本文发布HTML5中文学习网 ,转载请注明出处,感谢您!
  • 相关文章


  • 曝网友假装外国人写投诉信 ofo秒退押金并回函致歉
  • 苹果市值缩水逾2000亿美元 遭多家投行下调目标价
  • Asp.net Core与类库读取配置文件信息的方法_实用技巧
  • asp.net在Repeater嵌套的Repeater中使用复选框详解_实用技巧
  • 利用IIS调试ASP.NET网站程序的完整步骤_实用技巧
  • Asp.Net Core轻松学习系列之配置文件_实用技巧
  • ASP.NET 页生命周期概述(小结)_实用技巧
  • 详解ASP.NET Core WebApi 返回统一格式参数_实用技巧
  • 2018年网络流行语有哪些?2018年十大网络流行语盘点
  • 华为首席财务官孟晚舟被暂扣 深圳市政府要求加方立即放人!
  • 独孤九贱(4)_PHP视频教程

    江湖传言:PHP是世界上最好的编程语言。真的是这样吗?这个梗究竟是从哪来的?学会本课程,你就会明白了。 PHP中文网出品的PHP入门系统教学视频,完全从初学者的角度出发,绝不玩虚的,一切以实用、有用...

    独孤九贱(5)_ThinkPHP5视频教程

    ThinkPHP是国内最流行的中文PHP开发框架,也是您Web项目的最佳选择。《php.cn独孤九贱(5)-ThinkPHP5视频教程》课程以ThinkPHP5最新版本为例,从最基本的框架常识开始,将...

    独孤九贱(1)_HTML5视频教程

    《php.cn原创html5视频教程》课程特色:php中文网原创幽默段子系列课程,以恶搞,段子为主题风格的php视频教程!轻松的教学风格,简短的教学模式,让同学们在不知不觉中,学会了HTML知识。 ...

    ThinkPHP5实战之[教学管理系统]

    本套教程,以一个真实的学校教学管理系统为案例,手把手教会您如何在一张白纸上,从零开始,一步一步的用ThinkPHP5框架快速开发出一个商业项目。

    PHP入门视频教程之一周学会PHP

    所有计算机语言的学习都要从基础开始,《PHP入门视频教程之一周学会PHP》不仅是PHP的基础部分更主要的是PHP语言的核心技术,是学习PHP必须掌握的内容,任何PHP项目的实现都离不开这部分的内容,通...

    作者信息

    kevin

    永远在学习的路上!

    相关教程

  • javascript初级视频教程 javascript初级视频教程
  • jquery 基础视频教程 jquery 基础视频教程
  • javascript三级联动视频教程 javascript三级联动视频教程
  • 独孤九贱(3)_JavaScript视频教程 独孤九贱(3)_JavaScript视频教程
  • 独孤九贱(6)_jQuery视频教程 独孤九贱(6)_jQuery视频教程
  • 热门教程