yunshichen

我相信人生是值得活的,尽管人在一生中必须遭受痛苦,卑劣,残酷,不幸和死亡的折磨,我依然深信如此.但我认为人生不一定要有意义,只是对一些人而言,他们可以使人生有意义. ---J 赫胥黎

Javascript 杂谈一:全局作用域和闭包

    在网上看到一篇很好的文章,就是就写了这篇翻译&杂谈。

    在编程时你需要取得某些变量或者方法时才能继续你的开发工作,而程序编译器通常会将这些方法封装到一个个作用域。当你进入作用域,你才能取得该作用域的变量或方法。所以在某种意义上说,作用域(scope)非常重要。

    在js中,所有的变量/方法都是对象,这当然也包括作用域。最全局的作用域就是window。以下这个小程序可以让你很清楚的看到这点:
 
<html>
<script>
var a="test a";
window.b
="test b";
function c(){
    alert(
"test c");
}
alert(
"a is:"+window.a);
alert(
"b is:"+window.b);
window.c();
</script>
</html>

    js存在名为作用域链的东东(scope chain) ,假设scopeA定义在scopeB中,scopeB定义在window中,那么当你访问某个变量a的时候,js现在当前作用域寻找,如果没有找到就到上层作用域寻找,周而复始,最后在window进行查找,如果再查找不到,就抛出异常.

    多数程序语言对于作用域和变量的实现都是这样子的。似乎不用特别考究。

    奇特的是在js内,函数内部还可以嵌套函数,所以你一定要对上述作用域的概念了然于胸。例如下面的例子:

<html>
<script>
var A = new function(){
    
var a ="test a";
    
function change(){
        alert(a);
        a
="value changed";
    };
    
this.visible=function(){
        alert(a);
    }
}

A.visible();
A.change();
</script>
</html>

    你可以看到,visible方法可以访问而change则不能。于是这种方式就模拟了某些“OO”语言如Java,C++的OO功能:数据封装。并且,上述代码是js中创建singleton对象的方式。

    在上述代码中,change称为闭包(closure),因为它能够访问位于本作用域外的属性或方法。然而,恕我直言,这种函数能访问外层作用域的变量或函数的方式在C++或者Java中不是很平常的事情?为什么会有个专门的名词呢?我暂时没有弄清楚,或者以后会认真读读js规范:Javascript's specification
  
    很好的一篇文章:Getting Funky With Scopes and Closures

    当然还有Douglas Crockford 的主页
 

 


posted on 2008-08-21 22:16 Chenyunshi 阅读(476) 评论(2)  编辑 收藏 引用 所属分类: Web development

评论

# re: Javascript 杂谈一:全局作用域和闭包 2008-08-24 11:56 戴尔

给存起来了,以后要是能变成一本电子书就好了。  回复  更多评论   

# re: Javascript 杂谈一:全局作用域和闭包 2008-11-14 12:08 dd

你理解有误,并不是能够访问本作用域以外的内容就成为闭包。js的闭包是由函数实现的,因此当调用一个函数对象(外部对象)结束时,由于该函数对象内部的另一个对象(内部对象)仍然被某个其他的对象所引用,这时候外部对象被系统垃圾回收,而内部对象并没有被回收,这时候这个内部对象仍然能够访问外部对象中应该已经被释放的内容。这时候,这个内部对象被称为形成了一个闭包。  回复  更多评论   

只有注册用户登录后才能发表评论。
<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

常用链接

留言簿(7)

随笔分类

随笔档案

文章分类

相册

搜索

最新评论

阅读排行榜

评论排行榜