PS:先声明,本文道理适用于函数。而面向对象部分的作用域与之类似
javascript的作用域是以函数为界限的。
比如:
1 function fun(){ 2 var a = 3; 3 }
上面代码中的第2行,在函数fun中对变量a声明并进行初始化,那么变量a的作用域变在函数fun中,意味着对fun函数中,对a的使用是全局性的。
比如:
1 fun fun(){ 2 var a=3; 3 var b=function(){ 4 alert(a) 5 } 6 7 b(); 8 }
运行以上代码会发现,第4行中使用alert函数显示a的值,a在函数b中并没有进行声明,但是代码照常执行,正确的显示出a的值。
好了,现在我们引入闭包的概念(个人理解):
在javascript中,一个作用域中的子作用域可以使用父级作用域下的同等级的已经声明过的变量(PS:函数也是变量);
好吧,如果觉得上面那句话有点难理解,我们进行一个比喻:
下面这个解释要将以下概念做转换:
人-----------------------》函数
房间---------------------》作用域
物品---------------------》变量
现在故事开始(PS:这个世界中所有人都超小气):
某天,小明的父亲为了办公方便买了一个笔记本电脑。
第二天,小明想用这个电脑写代码,于是小明把电脑暂时拿到他的卧室。
第三天,小明的姐姐想用这个电脑查考研资料,于是她把这个电脑暂时拿到她的卧室。
.
.
.
过了一段时间,小明自己攒钱给自己买了一台顺手的。
第二天,姐姐想用小明的电脑,但是小明怕姐姐乱用弄坏他的电脑,于是小明告诉她,你不能用我的。想用电脑去
用父亲的那台。姐姐于是只能去找爹。
好了,故事完毕!!!
在上面的故事中,小明和姐姐还有那台父亲新买的电脑,都是父亲的属性。小明和姐姐的房间是他们各自的作用域,而爹的作用域是整个家。
所以小明和姐姐都可以用爹的电脑,而小明的电脑是小明个人的属性,它的作用域仅限于小明的卧室,虽然小明的卧室也是家(父亲的作用域)的
一部分,但是小明不允许父亲进入他的房间,同样姐姐也不允许父亲进入她的房间,于是他们各自的属性被牢牢的封闭在各自的作用域中,父亲和
姐姐都没法去用小明个人的东西。但是父亲的电脑是父亲的属性,所以它的作用域为整个家,所以整个家都可以用。
函数将变量的作用域牢牢封闭于自身,以至于其属性对外部为不可见状态,但对内部的子作用域全部可见。这便是闭包(对外封闭,对内开放)
原文:http://www.cnblogs.com/zhangkaiqiang/p/4928231.html