JavaScript--闭包
一.闭包的特点,以及闭包与垃圾回收机制的关系
1 <script> 2 /** 3 * 闭包结构的特点 4 * 函数嵌套的函数 5 * 被嵌套的函数有返回值,这个返回值调用了外函数的变量 6 **/ 7 8 9 /** 10 * 垃圾回收机制 11 * 变量创建的时候会占用内存 12 * 垃圾回收机制会被没用到的变量和用完的变量回收(从内存里面删除) 13 * */ 14 15 function fn1() { 16 // 局部变量 17 var data1 = "数据"; 18 function fn2() { 19 return data1; 20 } 21 return fn2; 22 } 23 24 25 // console.log(fn1()); // 输出fn2 26 27 // 这里能输出局部变量里保存的数据,说明垃圾回收机制没有把局部变量回收 28 // 坏处:占用内存(局部变量没有被删除) 29 // 好处:局部变量data1不会污染外部变量 30 console.log(fn1()()); // "数据" 31 </script>
二.非闭包情况例子
1 <script> 2 var arr = [10,20,30]; 3 4 // 平常的for循环i在for的括号内创建 5 /* for (var i = 0; i < arr.length; i++) { 6 arr[i] = function () { 7 console.log(i); 8 } 9 10 } 11 arr[0](); //输出 3*/ 12 13 14 // 这个就相当于在外面创建了一个i变量,在for循环里面使用了而已 15 /* var i = 0; 16 for (; i < arr.length; i++) { 17 arr[i] = function () { 18 console.log(i); 19 } 20 21 }*/ 22 23 // arr[0](); //输出 3 在执行的这一刻,问一下i是多少 24 // alert(i); // 输出3 25 26 27 //--------------------例子2------------------------- 28 console.log(111); 29 var i = 0; 30 // for循环在我们发布的那一刻就已经执行完毕 31 for (; i < 3; i++) { 32 // 定时器其实在for循环完了的最后一刻才执行 33 setTimeout(function () { 34 console.log(i); // 输出3 35 },1000); 36 } 37 38 console.log(222); 39 </script>
三.闭包与非闭包的区别例子
1 <script> 2 // 没有形成闭包,里面的函数没有使用外部的函数变量 3 /* var name = "The Window"; 4 var object = { 5 name: "My Object", 6 getNameFunc:function () { 7 console.log(this); // 得到 object 8 return function () { 9 // 这里的this呢? 10 console.log(this); //在调用的那一刻变成window 11 return this.name; 12 } 13 } 14 }; 15 16 console.log(object.getNameFunc()()); 17 // object.getNameFunc()运行得到function*/ 18 19 //形成闭包,里面的函数使用了外部的函数变量 20 var name = "The Window"; 21 var object = { 22 name: "My Object", 23 getNameFunc:function () { 24 // 把外面的this保存到局部变量that里 25 var that = this; 26 return function () { 27 // 被嵌套的函数调用了局部变量 that 这里形成了闭包, 28 // 所以that变量不会被回收,一直保存着外面的对象。 29 return that.name; 30 } 31 } 32 }; 33 34 console.log(object.getNameFunc()()); 35 </script>