在高级程序设计里,描述闭包是指有权访问另一个函数作用域中的变量的函数。
而经常创建方式是一个函数里包含另一函数。
而匿名函数就如“匿名”这两个意思一样。
所以匿名函数和闭包不是同一个概念。
在高级程序设计里描述匿名函数的执行环境具有全局性,所以this指向为window。这就是
为什么有时候发现this指向,不是自己所想的对象的问题。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var name="a";
var obj={
name:"b",
showFn:function(){
return (function(){
return this.name;
})();
}
}
console.log(obj.showFn());
</script>
</body>
</html>
打印结果为“a”
测试中可知:this指向window,所以才打印出“a”;
闭包:
简单的例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
name="cde";
function a(){
var name="abc";
function b(){
alert(name);
};
b();
}
a();
</script>
</body>
</html>
然而使用画图更好理解:

而这里的0表示自己的执行环境,1是上级执行环境,2是上上级执行环境,以此类推。
而变量查找是就近原则的,在自己最近的作用域查找到就会停止查找。
而这里活动对象的理解,很重要,因为只有函数在被调用时才是变量对象才是活动的,
才会去查找所要的变量。
如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
function a(){
var name="abc";
var arr=[];
for(var i=0;i<4;i++){
arr[i]=function b(){
alert(i);
};
}
return arr;
}
a()[0]();
a()[1]();
a()[2]();
</script>
</body>
</html>
弹出的结果都是4;
这是因为函数执行时内部函数没有在执行,而是内部函数执行完之后被调用时才执行,所以
这时活动对象上级作用域的变量都是同一一个值了;
还有闭包的执行环境结束了,活动对象也不会被销毁,这就像全局作用域,所以闭包里的变量是不会被
回收的,会一直保存着。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
function a(){
var num=0;
return function b(){
num++;
console.log(num);
}
}
var m1=a();
m1();
m1();
m1();
</script>
</body>
</html>
结果:
1,,2,3
虽然使用闭包要谨慎;
但使用闭包可以避免全局污染的问题。
新扩充理解:
闭包:有权访问另外函数的作用域中的变量的函数
1、函数嵌套函数
2、内部函数可以引用外部函数的参数和变量
闭包内的变量是不会被垃圾回收机制回收
好处:
1、希望一个变量长期驻扎在内存当中
2、避免全局变量的污染
3、私有成员
用法:
模块化代码
内存泄漏就是关闭当前页面,变量还是占据内存,不释放,只有当浏览器关闭时才释放。这样很消耗cpu
测试代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <ul> <li>abc1</li> <li>abc2</li> <li>abc3</li> <li>abc4</li> <li>abc5</li> </ul> <div id="text"></div> <script> var aLi=document.querySelectorAll("ul li"); var t=document.querySelector("#text"); for(var i=0;i<aLi.length;i++){ // 这里的i值都是5 // aLi[i].onclick=function(){ // t.innerHTML=i; // } /*使用闭包的特性解决这个问题 闭包的变量不会被释放,闭包可以访问外部函数的参数和变量 */ //(function a(){})括号括起来的是函数表达式 //因为(function(){})()循环去执行这个,其实是循环创建函数 //所以循环多少次就创建了多少个函数,就有多少个闭包 // aLi[i].onclick=(function(i){ // return function(){ // t.innerHTML=i; // } // })(i) //这也是一种方式,但也是使用了闭包的特性 (function(i){ aLi[i].onclick=function(){ t.innerHTML=i; } })(i) } </script> </body> </html>