一、闭包
1.定义:有权访问另一个函数作用域中的变量的函数
缺点:
闭包比其他函数占用公用内存,不可过量使用
2.闭包有哪些
(1)通过作用域链在全局环境中查找变量x,f1就是闭包
var x=1
function f1(){
alert(x)
}
f1()
(2)嵌套在f1中的f2函数就是闭包
-----即访问上层函数的作用域的内层函数
function f1(){
var x=1
function f2(){
alert(x)
}
f2()
}
(3)f2在f1函数的作用域中声明,在全局作用域中被调用,f2是闭包
---即指在函数声明时的作用域以外的地方被调用的函数,需要通过
将该函数作为返回值或者参数传递,叫闭包
function f1(){
var x=1
function f2(){
alert(x)
}
return f2
}
f1()()
作为参数传递:
function f1(){
var x=1
function f2(){
alert(x)
}
f3(f2)
}
function f3(n){
n()
}
f1()
3.闭包的特性
(1)自闭特性
---闭包内部声明的变量,外部无法访问,除非闭包主动向外界提供接口
var x=1
function f1(){
alert(x)
var a=2
}
f1()
alert(a) //报错
(2)包裹特性
【1】普通函数调用完毕系统会自动注销函数,释放资源
【2】闭包结构当外部函数被调用之后,闭包结构依然被保存在系统中,
从而 实现包裹数据的目的
function f1(){
var x=2
var y= function f2(){
return x
}
return y
}
var c=f1()
alert(c) //f2
m=c()
alert(m) //1
4、闭包应用
(1)使用闭包,能够跟踪动态环境中数据的实时变化
function f1(){
var a=1
var b=function f2(){
return a
}
a++ //a=2
a=a+12 a=2+12=14
return b
}
var c=f1()()
alert(c) //14
(2)b,c,d是三个闭包 闭包不会因为外部环境的注销而消失
当f1执行完毕,并没有被销毁,因为闭包引入的变量a,而继续存在
function f1(){
var a=1
b=function(){alert(a)}
c=function(){alert(++a)}
e=function(){alert(a)}
d=function(x){alert(a=x)}
b() //1
c() //2
e() //2
d(5) //5
}
f1()
5、闭包的底层原理
作用域链:
(1)当某个函数被调用时,会创建一个执行环境和响应的作用域链,同时初始化函数的活动对象
(2)在作用域链中,该函数处于作用域链的第一层,函数的的外部函数的作用域处于第二位,外部的外部处于第三位...
直到函数的终点为全局的执行环境
(3)作用域的查找为由下至上,由低至高逐级向上查找
function f1(a,b){
if(a<b){
return -1
}else{
return 1
}
}
var r=f1(2,3)
function f1(arg1){
return function(a,b){
var v1=a[arg1]
var v2=b[arg1]
if(v1<v2){
return -1
}else{
return 1
}
}
}
f2=f1("age")
var r=f2({"age":23},{"age":34})
6.闭包重点
function f1(){
var a=[]
for(var i=0;i<3;i++){
a[i]=function(){return i}
}
return a
}
var b=f1()
alert(b)
方法一、
<div>aaaaaaaaaaaaaa</div>
<div>bbbbbbbbbbbbbb</div>
<div>cccccccccccccc</div>
<script>
//getElementsByTagName 获取标签名
// function f1(){
// var arr=document.getElementsByTagName("div")
// for(var i=0;i<arr.length;i++){
// // arr[i].onclick=function(){
// // alert(i)
// // }
// arr[i].onclick=(function(m){
// return function(){alert(m)}
// })(i)
// }
// }
// f1()
</script>