JS高级学习历程-5
【闭包】
定义:闭包就是一个函数
条件:一个函数去嵌套另外一个函数,里边的函数就是闭包
function f1(){
function f2(){
}
}
特点:闭包函数有权访问父级环境的变量信息。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>14-闭包</title> 6 <script type="text/javascript"> 7 //简单闭包 8 //以下f1函数,只要执行完毕,name和addr变量就被销毁了 9 function f1(){ 10 var name="tom"; 11 var addr="beijing"; 12 function f2(){ 13 console.log(AO.name+"--"+AO.addr); 14 } 15 return f2; 16 } 17 18 //ff是f2函数的引用,因此调用ff函数的效果与调用f2函数效果一致 19 var ff = f1(); 20 21 //name和addr由于f1函数执行完毕,会被销毁 22 //ff()函数执行后也可以访问到name和addr的信息 23 //原因:name和addr在 24 25 //name和addr由于f1函数声明好之后,已经“固定”为f2执行环境内部AO的属性了 26 //和外部环境的变量没有直接交互关系。 27 28 //name和addr由于f1函数执行完毕,本身的作用域链被销毁 29 //但是f2函数内部的AO并没有被销毁,还有ff来指引它 30 31 ff(); //tom--beijing 32 </script> 33 </head> 34 <body> 35 36 </body> 37 </html>
1 案例-闭包计数器
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>15-闭包-计数器</title> 6 <script type="text/javascript"> 7 //①传统计数器 8 var num=0; 9 function add_num(){ 10 return ++num; 11 } 12 console.log(add_num()); //1 13 console.log(add_num()); //2 14 console.log(add_num()); //3 15 console.log(add_num()); //4 16 //函数销毁就不能调用 17 //当前计数器不好的地方是计数基数容易被污染,导致计数错误 18 num=100; 19 console.log(add_num()); //101 20 21 // 22 23 </script> 24 </head> 25 <body> 26 27 </body> 28 </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 2 <html> 3 <head> 4 <title>16-闭包-计数器</title> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 6 <meta name="description" content="" /> 7 <meta name="keywords" content="" /> 8 9 <script type="text/javascript"> 10 11 //②闭包计数器 12 13 function f1(){ 14 var num =0; 15 function f2(){ 16 return ++num; 17 } 18 return f2; 19 } 20 var add_num = f1(); 21 22 console.log(add_num()); //1 23 console.log(add_num()); //2 24 //由于计数器基数是f1函数内部的局部变量 25 //这样在外部就由于作用域链的关系不可能修改f1内部的num变量信息 26 num = 200; 27 console.log(add_num()); //3 28 29 </script> 30 31 <style type="text/css"> 32 </style> 33 </head> 34 35 36 <body> 37 38 </body> 39 </html>
总结:
1.作用域链
在js里边有环境,每个函数都是一个环境,最外部是window环境
每个环境的内部都有AO的活动对象
AO对象把当前环境可以访问的变量信息保存为本身的属性
环境是否有权访问一个变量信息,直接通过AO就可以知道
作用:
① 内部环境可以访问外部环境的变量信息,反之不可以
② 变量访问顺序是“先声明、后使用”
① 变量的作用域是定义时候决定的,不是运行时
2.闭包
闭包就是一个函数