码迷,mamicode.com
首页 > 编程语言 > 详细

理解JAVASCRIPT 闭包

时间:2014-05-18 01:15:57      阅读:380      评论:0      收藏:0      [点我收藏+]

标签:style   blog   class   code   c   java   

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

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

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

什么是闭包呢?

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

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

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

下面随便丢一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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了。

 

bubuko.com,布布扣

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

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

看下面的代码;

1
2
3
4
5
6
7
8
9
10
11
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,只有一个办法,把

1
2
var number=4;
num();

的顺序替换一下^_^。

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

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

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

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

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

其实flag对象是指向window的。

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

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

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

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

非常危险的!慎用闭包。

比如下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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的分页,我没答出来,好好努力吧bubuko.com,布布扣

O(∩_∩)O哈哈~

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

 

 

1
<br><br><br>

理解JAVASCRIPT 闭包,布布扣,bubuko.com

理解JAVASCRIPT 闭包

标签:style   blog   class   code   c   java   

原文地址:http://www.cnblogs.com/kmsfan/p/3734043.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!