本文是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表的启发。
(function(){})()为最常用的限定变量作用域的方法…
干净的全局空间是很多jslib现在所倡导的..
javascript的变量作用域是function,而不是其他的类c语言的block.
呵呵,这篇我喜欢。
最近还有一篇谈到平台的我也喜欢。
写的不错,期待下回分解~~
JS的匿名函数。。
得去学习一下
(function(){})()的目的是变量私有化.
命名空间现在的做法一般是下面这样做.
var com = {};
com.google = {};
com.google.reader = {
};
当然将上面的过程可以做个封装函数.
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
}
这个方法就是上面描述的封装函数,嘿嘿.
还有一个目的应该是单件模式吧。
恩,看到这一篇了。
哈哈,偶经历过AS1的Coder来看,确实感觉非常亲切!!!
感谢jianshuo老师带来的精彩分析~~
匿名函数在访问域的控制上用处比较大,如果用JS做平台,现在的YUI这个开源项目做的不错,不论是社区还是代码文档,而且Yahoo的首页也是基于YUI来做,直接和GWT竞争的。感觉YUI更出色一些。
其实 javascript这样的应用总是觉得象看你前一片文章别人说过的一样,好像是经过程序优化压缩过的?
不过即使是这样,分析出这么多东西也是受教了。
javascript 我觉得最大的特点需要我们考虑的就是让它 人尽其用,而不是乱用。 比如我最近接手的一个项目就是改善一个网站的环境。
http://www.babyone.com.cn/
在我接手前,首页就一个js 加载 flash 的脚本。 根本对内页没有任何链接。
一通修改,现在看起来似乎满意了一点,有兴趣的可以打开察看源代码来了解我改了些什么哈。
一通修改,babyone这个网站还是一看就知道没什么前途……那改了是要干吗呢……
傻x 那个东西叫做js的闭包机制