理解JAVASCRIPT 闭包

最近去面试了一家企业,结果非常灰心丧气,于是周末给自己定了一个目标

学好一门,学精通一门。不求多,只求懂。

最近看到一个概念“闭包”。

什么是闭包呢?

简单一点就是:看得到多和看得到少的区别。

上面这句话是我自己总结的,或许不太准确。

你能看到的多少这句话该如何理解呢?

下面随便丢一段代码:

var name="Peter";

function outer()

{

  var name="Tom";

  function inner()

  {

    return this.name;
  }   return inner;  //返回函数inner,作为OUTER的一个返回值 } var flag=outer(); alert(flag()); //Peter

 大家也许会比较的疑惑,为什么返回的是Peter而不是Tom?

是不是认为编程的就近原则?

答案是:你还没有很好的理解闭包。

下面的一张图可以帮助大家理解一下,定义了一个flag对象,然后公共的函数是inner的父函数outer,

其实执行的是inner函数,因为outer函数返回对INNER函数的一个引用。

然后alert就是执行这个函数inner了。

理解JAVASCRIPT 闭包

我们要理解为什么是Peter而不是Tom,还需要了解一下闭包的作用域链。

那么,什么是作用域链呢?

看下面的代码;

function num()
{
var number=0; //结果为4
//number=0; //结果为1 number++;
}
var number=4;
num(); alert(number);

  如果运行上述代码,在function内加var 和不加var的区别是很大的。

这就是文章下面要提到的JAVASCRIPT链式结构;

如果不声明var,那就表示这是一个全局变量,记住这一点概念很重要。

而在函数内部加了var以后,试想一下,外面的这个number和里面的number就没有任何的关系了,

所以最后的结果是4,是全部的number起作用。

如果没加var关键字,那么number就是属于window下的,默认this指向window(this.number),

外层的var=4会被自动替换成1.

如果想alert的值为4,只有一个办法,把

var number=4;
num();

的顺序替换一下^_^。

闭包的特性之一,就是可以在函数外部通过对象调用到函数内部的局部变量。

就好像是C#中,私有的变量,必须通过getter,setter方法来进行调用一样。

说白了,闭包,就是和上面说的可以类比。

再回到上面的问题,为什么name是window的而非function内部的局部变量的呢?

大家有没有发现 var flag=outer()这句话。

其实flag对象是指向window的。

而这个outer函数其实是返回了一个inner的引用。

所以,inner里的this.name(等同于outer().name)也被变成了一个window对象的引用。

所以,闭包不仅可以在外面访问函数内部的变量,

还可以改变内部变量的值,所以这一点大家要注意了,

非常危险的!慎用闭包。

比如下面的代码

name="Peter";

var obj={

name:"yang",

innerFunc:function()

  {

return function()

{

 return this.name;

}

  }

}

alert(obj.innerFunc()()); //Peter

通过外面可以改变里面局部变量的值,让其指向全局变量。

所以这就相当于形成了一个setter方法。

大家使用闭包的时候一定要小心啊。

另外最后再补充一下:

JAVASCRIPT的链式原理:

1.内部函数B形式参数,实际参数,函数,内部变量。

2.内部函数B的原型prototype

3.外部函数A的形式参数,实际参数,函数,内部变量。

4.WINDOW对象,活动对象(链式的顶端)

另外还有一点要注意,就是在闭包的时候,因为外部可以调用到内部函数的变量,并且是Writable的,所以内部

函数变量是一个“可持久的”,就是可以不受JAVASCRIPT的垃圾回收机制的影响。

而内部函数的变量根据链式原理对于外部的变量也是可持久的,这就造成了内,外的变量都具有可持久性,

这就形成了闭包,不过造成了这些变量越积越多,在内存中,从而影响程序的效率。

这个时候,就要在函数调用结束后删掉一些不必要的变量,否则严重的会造成内存泄漏。

好了,写完了,话说那个人问我怎么写JQUERY的分页,我没答出来,好好努力吧理解JAVASCRIPT 闭包

O(∩_∩)O哈哈~

祝大家周末愉快,我是新手,有写得不合理的地方,请多多指正。


上一篇:基于html5 canvas和js实现的水果忍者网页版


下一篇:MVC3项目依赖文件错误解决