一、变量作用域
要理解闭包,就要理解javascript 变量作用域。
变量作用域:全局作用域和局部作用域两种。
<script type="text/javascript"> var a=33; function myfun(){ alert(a); } myfun(); </script>
上面: 函数内部可以读取全局变量a。//33
<script type="text/javascript">
function myfun(){
var a=1; //定义了局部变量
console.log('我是局部变量a的值'+a);
}
myfun();
console.log('我是全局变量的a,但我不认识'+a);
</script>
结果为:
另外当函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
<script type="text/javascript"> function myfun(){ n=22; console.log(n); } myfun(); console.log(n); </script>
结果为:
总结:
● 定义在function里面的变量,叫做局部变量,只在function里面有定义声明,出了function没有定义的。
● 定义在全局范围内的,没写在任何function里面的,叫做全局变量,都认识。
原理:全局变量在定义时,不需要任何特殊结构,就会直接生成一个新的变量,在任何位置查找变量都有定义。局部变量定义在函数内部,函数如果不执行,相当于内部的代码没写,局部变量等于从未定义过,在函数执行时,会在函数作用域内部立即定义了一个变量,使用完之后,变量立即被销毁。所以在外部永远找不到局部变量定义。
二、函数的参数,会默认定义这个函数的局部变量
在函数内部使用的自己的变量,尽量定义为局部变量。
<script type="text/javascript"> function fun(a,b){ a=3; b=4; console.log(a+b); } fun(); console.log(a); </script>
结果为:
三、全局变量的作用
全局变量有自己独特的用途:累加、传递。
累加:函数每执行一次,都要求变量在原来基础上发生变化。
全局变量挺有用的,有两个功能:
功能1:通信,共同操作传递同一个变量
<script type="text/javascript"> var num=0; function add(){ num++; } function remove(){ num--; } add(); add(); add(); remove(); remove(); add(); add(); console.log(num); //3 </script>
功能2:累加,重复调用函数的时候,不会重置
<script type="text/javascript"> var num=0; function myfun(){ num++; console.log(num); } myfun();//1 myfun();//2 myfun();//3 </script>
如果num定义在函数里,每次执行函数就会把num重置为0:
<script type="text/javascript"> function myfun(){ var num=0; num++; console.log(num); } myfun(); //1 myfun();//1 myfun();//1 </script>
function 大{ function 小{ } 小(); //可以运行 } (); //不能运行,因为小函数定义在了大函数里面,离开大函数没有作用域。
如何从外部读取局部变量?
闭包:当在函数内部定义了其他函数时,就创建了闭包。
闭包函数是什么,就是:函数内包含子函数,并且最终return子函数。
而闭包函数的最大价值在于:可以在函数外部(子函数),直接读取该函数的局部变量。
<script type="text/javascript"> function outer(){ var a=33; function inner(){ console.log(a); } return inner; //outer 返回了inner } var inn=outer(); //inn 就是inner的函数了 inn();//执行inn,全局作用域下没有a的定义,但是函数闭包,能够把定义声明的函数的作用域一起记忆住,输出33 </script>
闭包2:匿名函数闭包
<script type="text/javascript"> var inner; function outer(){ var a=250; var b=430; // 全局变量inner 此时改变为了一个函数 // 这个函数此时立即生成闭包,记住此时所处的环境 a是250 inner=function(){ console.log(a); console.log(b); } } outer(); var a=300; var b=200; inner();// 一个函数在执行的时候,找闭包里面的变理,不会理会当前的作用域 </script>
使用闭包的注意点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的