匿名函数和闭包(上)

http://edu.51cto.com/lesson/id-6389.html

匿名函数:没有名字的函数。

闭包:

闭包是建立在一个匿名函数里面的。

闭包是指 有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式, 是在一个函数内部创建另一个函数,建议非必要时, 不要使用闭包,匿名函数也是差不多。

即,闭包是一个函数,是能够访问别的函数作用域变量的函数,那么内部函数肯定能访问外部函数的变量,但是外部函数不能访问内部函数的变量(外部函数不能访问局部变量) ,若想实现这种访问,此时就用到了匿名函数 ( 闭包 )。所以闭包和匿名函数是什么关系呢?是包含关系,即闭包肯定是个匿名函数。

一、匿名函数

1.普通函数

function box(){

return 'lee';

}

alert(box()); //输出 lee

2.匿名函数

function (){

return 'lee';

}  //单独的匿名函数,无法运行。就算能运行,也无法调用,因为没有名称

3.把匿名函数赋值给变量

var box = function (){

return 'lee';

};

alert(box()); //输出 lee

alert(box);//输出function (){ return 'lee'; } 

4.通过表达式自我执行  通过自我执行来执行匿名函数

(匿名函数)(); 第一个圆括号放匿名函数,第二个圆括号执行

(function (){

alert( 'lee');

})();  //输出 lee

5.不用alert 用返回执行

var box = (function(){

return 'lee';

})();

alert(box);  //输出 lee  把匿名函数自我执行的返回值赋值给变量  区别与3.把匿名函数赋值给变量

6.自我执行后 用alert打印 

alert((function(){

return 'lee';

})());//输出 lee

7.自我执行匿名函数的传参

(function(age){

alert(age);

})(100);//在100的位置传参

 

二、闭包

1.函数里放一个匿名函数

function box(){

return function(){  //闭包 函数里的函数

  return 'lee';

}

}

alert(box);

//输出 

function box(){

return function(){

  return 'lee';

}

}

alert(box());

//输出 

 function(){

  return 'lee';

}

alert(box()());

//输出 lee

2.上述函数的另一种调用

var b = box();

alert(b()); //输出lee

以上1 2 为铺垫,以下正式进入闭包

闭包:是指有权访问另一个函数(如b函数)作用域中的变量的函数(如a函数),创建闭包的常见的方式就是在一个函数(b)内部创建另一个函数(a),通过另一个函数(a)访问这个函数(b)的局部变量。简单来讲,在b函数里创建a函数,a就是闭包,我们可以通过a函数来访问b函数的局部变量。

3.通过闭包可以返回局部变量

function box(){

var age = 100;

}

alert(age);// 报错:age is not defined  因为age是私有的局部变量  外面访问不到  若在函数里面加上 return age;外部可以访问,但是这和闭包没有关系。

以下为正确的 通过闭包返回局部变量

function box(){

var age = 100;

return function(){

  return age;

};

}

alert(box()());//输出100

4.经典的例子  累加

使用闭包有一个优点,也是它的缺点:就是可以把局部变量驻留在内存中,可以避免使用全局变量。(全局变量污染导致应用程序不可预测性,命名冲突,每个模块都可调用必将引来灾难,所以推荐使用私有的,封装的局部变量)。

普通函数的局部变量,调用的时候会存在内存中一会儿,调用完毕,则从内存自动销毁。若使用闭包,可以把局部变量驻留在内存中。

//使用全局变量进行累加

var age = 100;

function box(){

age++;

}

alert(age); //输出100

box();

alert(age);//输出101

box();

alert(age);//输出102  以上实现累加

//使用局部变量进行累加

function box(){

var age=100;

age++;

return age;

}

alert(box());//输出101

alert(box());//输出101  因为每次调用box(),都会初始化age=100

//使用匿名函数实现局部变量驻留内存中从而累加  (真正要讲的是这个)

function box(){

var age=100;

return function(){

age++;

return age;

}

}

var b = box();

alert(b());//输出101

alert(b());//输出102

alert(b());//输出103

如果按照下面的调用,则不能实现累加

alert(box()());//输出101

alert(box()());//输出101  这样调用还是会初始化的。

这里访问不到局部变量age

alert(age);// not defined

PS:由于闭包里作用域返回的局部变量资源不会被立刻销毁回收,所以可能会占用更多的内存,过度使用闭包会导致性能下降,建议在非常必要的时候才使用闭包。

function box(){

var age=100;

return function(){

age++;

return age;

}

}

var b = box();

alert(b());//输出101

alert(b());//输出102

alert(b());//输出103

alert(b);//输出函数,b会一直驻留在内存中,打印b,它就是 function(){age++; return age;}

b = null; //最后不用了,解除引用,等待垃圾回收

alert(b);//b is not a function

posted @ 2014-05-08 15:06  mabel_on_line  阅读(375)  评论(0编辑  收藏  举报