1,闭包引入

编写以下代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>00_引入</title>
</head>
<body><button>测试1</button>
<button>测试2</button>
<button>测试3</button>
<!--
需求: 点击某个按钮, 提示"点击的是第n个按钮"
-->
<script type="text/javascript">var btns = document.getElementsByTagName('button')//遍历加监听/*for (var i = 0,length=btns.length; i < length; i++) {var btn = btns[i]//将btn所对应的下标保存在btn上btn.index = ibtn.onclick = function () {alert('第'+(this.index+1)+'个')}}*///利用闭包for (var i = 0,length=btns.length; i < length; i++) {(function (j) {var btn = btns[j]btn.onclick = function () {alert('第'+(j+1)+'个')}})(i)}</script>
</body></html>

利用闭包,可以在函数内部引用外部的变量,实现对按钮的绑定。

2,闭包

通过上述代码,可以知道什么是闭包,一个函数嵌套另一个函数,被嵌套的函数引用的外部函数的变量,就形成了闭包。既:

如何产生闭包:当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时, 就产生了闭包
闭包到底是什么:使用chrome调试查看,理解一: 闭包是嵌套的内部函数(绝大部分人)。理解二: 包含被引用变量(函数)的对象(极少数人)。
注意: 闭包存在于嵌套的内部函数中。
产生闭包的条件:函数嵌套。内部函数引用了外部函数的数据(变量/函数)。

<script type="text/javascript">function fn1 () {var a = 2var b = 'abc'function fn2 () { //执行函数定义就会产生闭包(不用调用内部函数)console.log(a)}// fn2()}fn1()function fun1() {var a = 3var fun2 = function () {console.log(a)}}fun1()
</script>

3,常见的闭包

JavaScript常见的闭包有两种:一是将函数作为另一个函数的返回值,二是将函数作为实参传递给另一个函数调用。

<script type="text/javascript">// 1. 将函数作为另一个函数的返回值function fn1() {var a = 2function fn2() {a++console.log(a)}return fn2}var f = fn1()f() // 3f() // 4// 2. 将函数作为实参传递给另一个函数调用function showDelay(msg, time) {setTimeout(function () {alert(msg)}, time)}showDelay('atguigu', 2000)
</script>

需要注意的是,闭包不会随着外部函数的调用结束而消失,它仍然存在于内存中,可多次调用内部函数。

4,闭包的生命周期

产生: 在嵌套内部函数定义执行完时就产生了(不是在调用,函数提升)
死亡: 在嵌套的内部函数成为垃圾对象时

<script type="text/javascript">function fn1() {//此时闭包就已经产生了(函数提升, 内部函数对象已经创建了)var a = 2function fn2 () {a++console.log(a)}return fn2}var f = fn1()f() // 3f() // 4f = null //闭包死亡(包含闭包的函数对象成为垃圾对象)
</script>

5,闭包的应用场景:自定义js模块

方式一:编写一个js文件,将功能封装在闭包中,对外提供公共访问方法。

js文件的代码:

function myModule() {//私有数据var msg = 'My atguigu'//操作数据的函数function doSomething() {console.log('doSomething() '+msg.toUpperCase())}function doOtherthing () {console.log('doOtherthing() '+msg.toLowerCase())}//向外暴露对象(给外部使用的方法)return {doSomething: doSomething,doOtherthing: doOtherthing}
}

html代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>05_闭包的应用_自定义JS模块</title>
</head>
<body>
<!--
闭包的应用2 : 定义JS模块* 具有特定功能的js文件* 将所有的数据和功能都封装在一个函数内部(私有的)* 只向外暴露一个包信n个方法的对象或函数* 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能
-->
<script type="text/javascript" src="myModule.js"></script>
<script type="text/javascript">var module = myModule()module.doSomething()module.doOtherthing()
</script>
</body>
</html>

方式二:使用window对外提供访问方

js文件的代码:

(function () {//私有数据var msg = 'My atguigu'//操作数据的函数function doSomething() {console.log('doSomething() '+msg.toUpperCase())}function doOtherthing () {console.log('doOtherthing() '+msg.toLowerCase())}//向外暴露对象(给外部使用的方法)window.myModule2 = {doSomething: doSomething,doOtherthing: doOtherthing}
})()

html代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>05_闭包的应用_自定义JS模块2</title>
</head>
<body>
<!--
闭包的应用2 : 定义JS模块* 具有特定功能的js文件* 将所有的数据和功能都封装在一个函数内部(私有的)* 只向外暴露一个包信n个方法的对象或函数* 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能
-->
<script type="text/javascript" src="myModule2.js"></script>
<script type="text/javascript">myModule2.doSomething()myModule2.doOtherthing()
</script>
</body>
</html>

6,闭包的弊端以及解决方式

缺点:函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长,容易造成内存泄露
解决:能不用闭包就不用或者及时释放闭包

function fn1() {var arr = new Array[100000]function fn2() {console.log(arr.length)}return fn2}var f = fn1()f()
f = null //让内部函数成为垃圾对象-->回收闭包

7,闭包面试题解析

<script type="text/javascript">//代码片段一var name = "The Window";var object = {name : "My Object",getNameFunc : function(){return function(){return this.name;};}};alert(object.getNameFunc()());  //?  the window//代码片段二var name2 = "The Window";var object2 = {name2 : "My Object",getNameFunc : function(){var that = this;return function(){return that.name2;};}};alert(object2.getNameFunc()()); //?  my object
</script>

【JavaScript高级05】JavaScript第二大神兽:闭包相关推荐

  1. 尚硅谷JavaScript高级教程(javascript实战进阶)学习笔记

    前言 这个是我学习过程中的笔记,分享给大家,希望对大家有用. 学习内容是尚硅谷JavaScript高级教程(javascript实战进阶),这里是视频链接. 我在前面有两篇对于web前端HTML和CS ...

  2. 攻下《JavaScript高级程序设计》——第二章 在HTML中使用JavaScript

    从上一章我们知道了,JavaScript是一种专门为网页交互而设计的脚本语言,那么,它就免不了和HTML打交道,所以在设计JavaScript的时候,Netscape首要面临的就是,怎么让HTML和J ...

  3. javaScript系列 [05]-javaScript和JSON

    本文输出和JSON有关的以下内容 JSON和javaScript JSON的语法介绍 JSON的数据类型 JSON和XMLHTTPRequest JSON的序列化和反序列化处理 1.1 JSON和ja ...

  4. 阅读JavaScript高级程序设计(第二版)笔记

    第一章js简介 JavaScript诞生在1995年,当时负责进行输入型验证. JavaScript是一种专为与网页交互而设计的脚本语言,分为 : 1. ECMAScript核心语言功能. 2.文档对 ...

  5. 读javascript高级程序设计03-函数表达式、闭包、私有变量

    一.函数声明和函数表达式 定义函数有两种方式:函数声明和函数表达式.它们之间一个重要的区别是函数提升. 1.函数声明会进行函数提升,所以函数调用在函数声明之前也不会报错: test(); functi ...

  6. [JavaScript高级程序设计]JavaScript介绍

    1.历史 1995年出生,提供浏览器中的输入验证功能: 如今,与浏览器窗口及其内容所有的交互功能,成为一门功能全面的编程语言: 特性:闭包.匿名函数等 2.内容 3.与ECMAScript ECMA- ...

  7. JavaScript高级程序设计-JavaScript API

    javascript API javascript API Encoding API 1. 文本编码 2. 文本解码 File API & Blob API File 类型 FileReade ...

  8. JavaScript 高级程序设计第二章

    第二章 教材: JavaScript 高级程序设计 目录 第二章 一. script元素 1. 介绍 2. 标签位置 2.1. 推迟执行脚本---defer属性 2.2. 异步执行脚本---async ...

  9. 读javascript高级程序设计-目录

    javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/> 本笔记是为了方便日后查阅,仅作学习交 ...

最新文章

  1. php 返回字符串给aja,解决ajax异步请求返回的是字符串问题
  2. EasyRTMP CPU占用问题调优(一)
  3. docker搜索镜像
  4. HDU 1087 [Super Jumping! Jumping! Jumping!]动态规划
  5. 聚合数据接口,提供开放API
  6. 微信支付phpv3给我们留下的坑
  7. c++歌手类代码_安卓资源ID修改-游戏发行-切包过程中的R类和Public.xml
  8. [SNMP超详解]:简介、抓包分析与编程实战
  9. 虚拟服务器io,IO虚拟化:虚拟直接连接VMDc技术解析
  10. 【WPS技能】xlsx表格根据单元格的值改变行背景色
  11. Pintech品致钳形交直流电流探头的主要功能
  12. 有关一道身份证的python编程题
  13. React报错:Too many re-renders
  14. 雷电模拟器dnconsole命令汇总
  15. rabbitMQ修改默认端口
  16. 详细介绍CoinList 2022 年夏季种子项目, web3概念最亮眼!
  17. 刷了 1000 多道算法题,一点小小的心得!
  18. mybatis 整合spring之mapperLocations配置的问题
  19. week3note函数
  20. 是否似曾相识?每个开发人员都犯过的15个错误

热门文章

  1. 一周cp未能连接到服务器,AppSight - 一周CP-拒接闲聊只走心
  2. vue框架和react框架的区别以及各自的应用场景
  3. mysql 导入数据库sql语句_mysql中导入数据与导出数据库sql语句
  4. html做下拉列表效果
  5. 【转】USB--设备、配置、接口、端点
  6. 一个通知中心中台系统设计简介
  7. 什么是原型对象、实例、原型链讲解(简单易懂,不墨迹)
  8. fping 与 ping 功能对比及使用
  9. 计算机自动设置开机,电脑可以设置系统自动开机吗
  10. win10用cortana搜索不到已安装应用怎么办