Home » 中文 » Google代码欣赏 » 用匿名函数避免命名冲突 « google.loader 代码欣赏 | Symbol表的启发 »

用匿名函数避免命名冲突

相关帖子
作者:Jian Shuo Wang 发表于: 2007-05-15 00:05


本文是google.loader 代码欣赏系列的第二部分。

第一个匪夷所思的地方,可能就是这一段了

if (!google.loader) {
google.loader = {};
google.loader.ServiceBase = "http://www.google.com/uds";
google.loader.ApiKey = "internal";
google.loader.KeyVerified = true;
google.loader.LoadFailure = false;
google.loader.AdditionalParams = "";
(function() {
//大量的函数定义,变量声明以及函数的执行(整整100多行)
})()
}
基本上就是说,它写了一个这样的语法:
(function(){})()
就算是看得懂,这么绕来绕去,除了炫耀之外,又有意义呢?

匿名函数

先撇开Google的代码,看一下JavaScript其实是支持这种形式的行数定义的:

function(msg){ alert(msg); }("hello world");
这其实是两步:第一步,定义了一个函数,相当于:
var abc = function(msg) { alert(msg);}
第二步,立刻执行它:
abc("hello world");
把两个语句拼接在一起,然后去掉abc这个函数的名字,就成了现在的语法形式。

结合前面的

google.loader = {};
一起看,其实在这里是定义了google.loader这个对象的一个匿名的成员函数,并且立刻执行了这个成员函数(就是说完成里面的一些列初始化的时候需要干的事情)。

匿名函数的用处

虽然可以理解这里是个匿名函数,但是为什么要这么做呢?

我猜想(请注意,所有这里想的都是一个猜想,并且可能是众多原因之中的一种而已,欢迎大家补充),最主要的考虑是避免命名冲突。

因为这段JavaScript作为Google的其他的各项服务的入口,是会被全球很多的网页引用的。像任何的JavaScript引用(包括PHP的引用),如果被引用的代码和外面的代码一不小心用了同样的名字,就不可避免的发生命名冲突。对于小范围的代码或许还可以用起很怪异的名字的方法企图避免,而对于Google这样的应用,靠运气就有些说不过去。如果是一个匿名函数,外面将永远无法直接访问它(总不能写一个这样的一个没有函数名的调用吧:())。从这一点来说,不可能有命名冲突。

封装

另外的一个好处,有可能是为了更好的封装。比如在这个函数里面,有很多的函数定义,比如

q(); p(); m(); g(); i()
还有大量的变量:
var j; var h; var l;
等等。在JavaScript里面没有简单的private这样的定义私有函数或者私有函数的方法。如果调用者可以随心所欲的访问到这些中间的(随时可能变化,甚至移除)成员。对于这么一个开肠破肚,一览无余的对象,从一个API提供者的角度来看(和使用者的角度来看),的确是个挺恐怖的事情。

如果放在一个匿名的函数里面,外界就再也没有办法直接访问到里面的函数了。内部的逻辑被完美的封装了起来。这样一来,这些函数和变量多么的安全!

安全是安全了,但是定义了这么多的函数,仅仅是为了不被外界访问吗?显然不是,所以接下来要做的事情,就是把这些函数输出出去,也就是google_exportSymbol,或者说是函数g()要做的事情。

且听下回分解。

注:接下来,或许还要说说: 输出函数供开发者使用, JavaScript中的面向对象, prototype的扩展方式, Undocumented的神秘参数, 编译后的JavaSscript好比汇编语言,和 Symbol表的启发。


Posted by Jian Shuo Wang at May 15, 2007 12:04 AM

相关贴子:
评论

(function(){})()为最常用的限定变量作用域的方法...
干净的全局空间是很多jslib现在所倡导的..

javascript的变量作用域是function,而不是其他的类c语言的block.

Posted by: Longwosion on May 15, 2007 01:16 AM

呵呵,这篇我喜欢。
最近还有一篇谈到平台的我也喜欢。

Posted by: Aether on May 15, 2007 02:36 AM

写的不错,期待下回分解~~

Posted by: xin2l on May 15, 2007 11:11 AM

JS的匿名函数。。

得去学习一下

Posted by: 伤口 on May 15, 2007 11:49 AM

(function(){})()的目的是变量私有化.
命名空间现在的做法一般是下面这样做.
var com = {};
com.google = {};
com.google.reader = {
};
当然将上面的过程可以做个封装函数.

Posted by: 滴水 on May 15, 2007 05:20 PM

function g(c,a){
var b=c.split(/\./);
var d=window;
for(var e=0;e d=d[b[e]]
}
d[b[b.length-1]]=a
}
这个方法就是上面描述的封装函数,嘿嘿.

Posted by: 滴水 on May 15, 2007 05:24 PM

还有一个目的应该是单件模式吧。

Posted by: spyer on May 16, 2007 02:07 AM

恩,看到这一篇了。
哈哈,偶经历过AS1的Coder来看,确实感觉非常亲切!!!
感谢jianshuo老师带来的精彩分析~~

Posted by: awflasher on May 16, 2007 05:56 PM

匿名函数在访问域的控制上用处比较大,如果用JS做平台,现在的YUI这个开源项目做的不错,不论是社区还是代码文档,而且Yahoo的首页也是基于YUI来做,直接和GWT竞争的。感觉YUI更出色一些。

Posted by: lionheart163 on May 16, 2007 10:19 PM

其实 javascript这样的应用总是觉得象看你前一片文章别人说过的一样,好像是经过程序优化压缩过的?

不过即使是这样,分析出这么多东西也是受教了。

javascript 我觉得最大的特点需要我们考虑的就是让它 人尽其用,而不是乱用。 比如我最近接手的一个项目就是改善一个网站的环境。

http://www.babyone.com.cn/

在我接手前,首页就一个js 加载 flash 的脚本。 根本对内页没有任何链接。

一通修改,现在看起来似乎满意了一点,有兴趣的可以打开察看源代码来了解我改了些什么哈。

Posted by: 笑容 on October 31, 2007 05:59 PM

一通修改,babyone这个网站还是一看就知道没什么前途……那改了是要干吗呢……

Posted by: 回笑容 on April 15, 2008 06:43 PM
Post a comment
大名: (广告性质签名将被删除)

邮件地址: (嘘!我不会告诉别人的)

URL: (optional)

评论:


别着急,可能要等待多达30秒钟注意:不欢迎“沙发”,“收藏”,“受益”,“瞎扯”等等简单的不表达任何思想的留言
记住我的信息?

<-- 请只按一次
TrackBack URL for this entry: http://home.wangjianshuo.com/scripts/mtcn/mt-tb.cgi/302
新的文章通知我:
以往的帖子
人是盲目乐观的 | 15 comment(s) | March 30, 2008
浦东第二航站楼T2和北京第三航站楼 | 7 comment(s) | March 27, 2008
人性的悲剧性和对罪人的爱 | 23 comment(s) | March 25, 2008
上海交通大学励志讲坛第二十期记录稿 | 8 comment(s) | March 20, 2008
宏观的思考问题 - 第二部分 | 10 comment(s) | March 19, 2008
智力题 - 第二部分 | 21 comment(s) | March 12, 2008
镜子为什么翻转左右却不可以翻转上下 | 24 comment(s) | March 09, 2008
智力题 | 23 comment(s) | March 08, 2008
Jeff Immelt语录 | 2 comment(s) | March 05, 2008
规定的作用 | 4 comment(s) | March 04, 2008
小宝受委屈了 | 23 comment(s) | February 28, 2008
blogger,blog还是BSP的商业模式 | 4 comment(s) | February 26, 2008
本站隐私政策 | 2 comment(s) | February 23, 2008
测试是不是应该太强 | 10 comment(s) | February 21, 2008
关于歧视 | 13 comment(s) | February 20, 2008
• 阅读 全部文章
© 2002 - 2003 Jian Shuo Wang. All right reserved. Terms and Conditions.
Edit