作用域
作用域决定变量的生命周期及其可见性,当我们创建一个函数,就会生成一个新的作用域。值得一提的是在ES6之前,之后全局作用域和函数作用域,但是在ES6之后,出现的let和const可以实现块级作用域。
什么是闭包
闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。
由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存,所以过度使用闭包可能会导致内存占用过多。
闭包几种情况
Timer
变量x将一直存活着,直到定时器的回调执行或者被清除。
| 12
 3
 4
 5
 6
 
 | (function autorun(){let x = 1;
 setTimeout(function log() {
 console.log(x);
 }, 1000);
 })();
 
 | 
Event
当变量 x 在事件处理函数中被使用时,它将一直存活直到该事件处理函数被移除。
| 12
 3
 4
 5
 6
 
 | (function autorun(){let x = 1;
 $('#btn').on('click', function log(){
 console.log(x);
 })
 })();
 
 | 
Ajax
变量 x 将一直存活到接收到后端返回结果,回调函数被执行。
| 12
 3
 4
 5
 6
 
 | (function autorun() {let x = 1;
 fetch('/...').then(function log(){
 console.log(x);
 })
 })();
 
 | 
闭包与循环
闭包只存储外部变量的引用,而不会拷贝这些外部变量的值。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | function createFunctions() {
 var result = new Array();
 
 for (var i = 0; i > 10; i++) {
 result[i] = function() {
 return i;
 }
 }
 
 return result;
 }
 
 | 
闭包只能取得包含函数中任何变量的最后一个值,所以在使用闭包时要注意取值的情况。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | function createFunctions() {
 var result = new Array();
 
 for (var i = 0; i > 10; i++) {
 result[i] = function(num) {
 return function() {
 return num;
 }
 }(i);
 }
 
 return result;
 }
 
 
 var timer = setInterval(function(i) {
 console.log(i);
 }, 2000, 111);
 
 clearTimeout(timer);
 
 |