闭包理解

 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>

 

 

 

posted @ 2020-04-28 09:17  全情海洋  阅读(182)  评论(0编辑  收藏  举报