1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>01_理解闭包</title> 6 </head> 7 <body> 8 <!-- 9 1. 如何产生闭包? 10 * 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时, 就产生了闭包 11 2. 闭包到底是什么? 12 * 使用chrome调试查看 13 * 理解一: 闭包是嵌套的内部函数(绝大部分人) 14 * 理解二: 包含被引用变量(函数)的对象(极少数人) 15 * 注意: 闭包存在于嵌套的内部函数中 16 3. 产生闭包的条件? 17 * 函数嵌套 18 * 内部函数引用了外部函数的数据(变量/函数) 19 --> 20 <script type="text/javascript"> 21 function fn1 () { 22 var a = 2 23 var b = 'abc' 24 function fn2 () { //执行函数定义就会产生闭包(不用调用内部函数) 25 console.log(a) 26 } 27 // fn2() 28 } 29 fn1() 30 31 function fun1() { 32 var a = 3 33 var fun2 = function () { 34 console.log(a) 35 } 36 } 37 fun1() 38 </script> 39 </body> 40 </html>
常见的闭包
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>02_常见的闭包</title> 6 7 </head> 8 <body> 9 <!-- 10 1. 将函数作为另一个函数的返回值 11 2. 将函数作为实参传递给另一个函数调用 12 --> 13 <script type="text/javascript"> 14 // 1. 将函数作为另一个函数的返回值 15 function fn1() { 16 var a = 2 17 function fn2() { 18 a++ 19 console.log(a) 20 } 21 return fn2 22 } 23 var f = fn1() 24 f() // 3 25 f() // 4 26 27 // 2. 将函数作为实参传递给另一个函数调用 28 function showDelay(msg, time) { 29 setTimeout(function () { 30 alert(msg) 31 }, time) 32 } 33 showDelay('ag', 2000) 34 35 </script> 36 </body> 37 </html>
闭包的作用
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>03_闭包的作用</title> 6 7 </head> 8 <body> 9 <!-- 10 1. 使用函数内部的变量在函数执行完后, 仍然存活在内存中(延长了局部变量的生命周期) 11 2. 让函数外部可以操作(读写)到函数内部的数据(变量/函数) 12 13 问题: 14 1. 函数执行完后, 函数内部声明的局部变量是否还存在? 一般是不存在, 存在于闭中的变量才可能存在 15 2. 在函数外部能直接访问函数内部的局部变量吗? 不能, 但我们可以通过闭包让外部操作它 16 --> 17 <script type="text/javascript"> 18 function fn1() { 19 var a = 2 20 function fn2() { 21 a++ 22 console.log(a) 23 // return a 24 } 25 function fn3() { 26 a-- 27 console.log(a) 28 } 29 return fn3 30 } 31 var f = fn1() 32 f() // 1 33 f() // 0 34 </script> 35 36 </body> 37 </html>
闭包的生命周期
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>04_闭包的生命周期</title> 6 7 </head> 8 <body> 9 <!-- 10 1. 产生: 在嵌套内部函数定义执行完时就产生了(不是在调用) 11 2. 死亡: 在嵌套的内部函数成为垃圾对象时 12 --> 13 <script type="text/javascript"> 14 function fn1() { 15 //此时闭包就已经产生了(函数提升, 内部函数对象已经创建了) 16 var a = 2 17 function fn2 () { 18 a++ 19 console.log(a) 20 } 21 return fn2 22 } 23 var f = fn1() 24 f() // 3 25 f() // 4 26 f = null //闭包死亡(包含闭包的函数对象成为垃圾对象) 27 </script> 28 </body> 29 </html>
闭包的应用_自定义JS模块
方式1;
html文件
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>05_闭包的应用_自定义JS模块</title> 6 </head> 7 <body> 8 <!-- 9 闭包的应用2 : 定义JS模块 10 * 具有特定功能的js文件 11 * 将所有的数据和功能都封装在一个函数内部(私有的) 12 * 只向外暴露一个包信n个方法的对象或函数 13 * 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能 14 --> 15 <script type="text/javascript" src="myModule.js"></script> 16 <script type="text/javascript"> 17 var module = myModule() //实例化 18 module.doSomething() 19 module.doOtherthing() 20 </script> 21 </body> 22 </html>
js文件
1 function myModule() { 2 //私有数据 3 var msg = 'My at' 4 //操作数据的函数 5 function doSomething() { 6 console.log('doSomething() '+msg.toUpperCase()) 7 } 8 function doOtherthing () { 9 console.log('doOtherthing() '+msg.toLowerCase()) 10 } 11 12 //向外暴露对象(给外部使用的方法),返回多个数据用对象封装 13 return { 14 doSomething: doSomething, 15 doOtherthing: doOtherthing 16 } 17 }
方法二;
html文件
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>05_闭包的应用_自定义JS模块2</title> 6 </head> 7 <body> 8 <!-- 9 闭包的应用2 : 定义JS模块 10 * 具有特定功能的js文件 11 * 将所有的数据和功能都封装在一个函数内部(私有的) 12 * 只向外暴露一个包信n个方法的对象或函数 13 * 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能 14 --> 15 <script type="text/javascript" src="myModule2.js"></script> 16 <script type="text/javascript"> 17 myModule2.doSomething() 18 myModule2.doOtherthing() 19 </script> 20 </body> 21 </html>
js文件
1 (function () { //利用匿名函数立即执行 2 //私有数据 3 var msg = 'My atguigu' 4 //操作数据的函数 5 function doSomething() { 6 console.log('doSomething() '+msg.toUpperCase()) 7 } 8 function doOtherthing () { 9 console.log('doOtherthing() '+msg.toLowerCase()) 10 } 11 12 //向外暴露对象(给外部使用的方法) 13 window.myModule2 = { 14 doSomething: doSomething, 15 doOtherthing: doOtherthing 16 } 17 })()
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>07_面试题1</title> 6 </head> 7 <body> 8 9 <script type="text/javascript"> 10 //代码片段一 11 var name = "The Window"; 12 var object = { 13 name : "My Object", 14 getNameFunc : function(){ 15 return function(){ 16 return this.name; 17 }; 18 } 19 }; 20 alert(object.getNameFunc()()); // the window 相当于function()调用,所以this为window 21 22 23 //代码片段二 24 var name2 = "The Window"; 25 var object2 = { 26 name2 : "My Object", 27 getNameFunc : function(){ 28 var that = this; 29 return function(){ 30 return that.name2; 31 }; 32 } 33 }; 34 alert(object2.getNameFunc()()); // my object that引用的是外部函数的this,外部函数的this就是object2调用的, 35 36 37 38 </script> 39 </body> 40 </html>