匿名函数和闭包
匿名函数
匿名函数和普通函数
- 普通函数
function box(){ return 'Lee'; } alert(box());
匿名函数
没有函数名,单独的匿名函数是无法运行的,无法调用
function{ return 'Lee'; }
把匿名函数赋值给变量
var box=function(){ return 'Lee'; }; alert(box);//得到的是一个函数 alert(box());// 得到返回数Lee;
通过自我执行来执行匿名函数
(function (){ alert('Lee'); })();
自我执行匿名函数的传参
(function (age){ return age; })(100);
闭包
概念
闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见的方式,就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。
闭包作用
使用闭包有一个优点,也是其缺点。可以把局部变量驻留在内存中,可以避免使用全局变量。因为全局变量污染导致程序不可预测性,可能引起灾难,所以推荐使用私有的,封装的局部变量。
缺点:闭包作用域返回的局部变量资源不会被立即销毁回收,所以可能占用更多的内存。过多使用闭包会导致性能下降,因此建议在需要的时候才使用闭包。
关于this对象
this对象是在运行时基于函数的执行环境绑定的,如果this在全局范围则为window,如果在对象内部则指向这个对象。闭包却在运行时指向window,因为闭包并不属于这个对象的属性和方法。
可以用下面代码测试一下
var box={ getThis:function(){ return function(){ return this; } } } alert(box.) // alert(box.getThis()) // 返回里面的闭包函数 alert(box.getThis()()) //[object window]
var user='The window'; var box={ user:'The box'; getUser:function(){ //这里作用域的this是box (1) return function(){ //这里作用域的this是window return this.user; (2) } } } alert(box.getUser()()); //打印出‘The window'
如何闭包里面的 this指向的是’The box’
方法一:对象冒充(目前是全局变量,冒充为bo对象)
alert(box.getUser().call(box)); //'The box'
方法二:使用作用域链,将(1)处的作用域给(2)处作用域
var user='The window'; var box={ user:'The box'; getUser:function(){ //这里作用域的this是box (1) var that =this; return function(){ //这里作用域的this是window return that.user; (2) } } } alert(box.getUser()()); //打印出‘The window'
闭包使用
函数里面放一个匿名函数,产生闭包,通过闭包返回局部变量
function box(){ var user='Lee'; return function(){ return user; //通过匿名函数返回box()局部变量 } } alert(box); //整个函数 alert(box()); //里面的小函数 alert(box()()); //Lee
通常调用方法
var b=box(); //得到 里面的 小函数 b();//Lee
实现私有作用域(块级作用域)
作用:
使用了块级作用域后,匿名函数中定义的任何变量,都会在执行结束时被销毁,这种技术经常在全局作用域中被用在函数外部,从而限制向全局作用域添加过多的变量和函数。一般来说,我们应该尽可能减少向全局作用域中添加变量和函数。过多的全局变量和函数很容易导致命名冲突。引用块级作用域,使得每个开发者既可以使用自己的变量,又不必担心搞乱全局作用域。
包含自我执行的匿名函数,可以实现私有作用域。
(function(){ for(var i=0;i<5;i++){ alert(i); // 依次0 1 2 3 4 } })(); alert(i);//undefined i在上面自我执行完之后,会被立即销毁;