自从Google释出了其Closure的JavaScript库以来,越来越多人希望了解它与Ext JS比起来究竟怎么样。由于我也属于这些想知道的人,所以我希望从我自己的角度来回答此问题,希望并不会由此触动双方的感情。

参考文档http://closure-library.googlecode.com/svn/docs/index.html

Hello World

切入某个库的话,通常都是从"Hello World"程序开始。不太清楚这是不是一个没有用的例子,还是它想告诉你这个库有多么不错。反正我觉得Google Closure的Hello World例子没啥吸引俺的。Hello World例子中是调用一个JavaScript函数来创建一个DOM对象,演示了一个goog.dom.createDom的helper方法。它是通过body标签的load属性调用的,有点难看了嘛。个人认为Ext的Hello World还是蛮不错。它用Ext.onReady的标准方式调用,使得在等待图片和其他资源之前就可以初始化JavaScipt代码。并采用了Ext.Window器件来告诉您Ext器件是如何配置的和启动的,让您了解更多。

Widget部件的基类

UI组件在Ext的对象层次中,以Tree为例子就是:

Ext.util.Observable
 Ext.Component
   Ext.BoxComponent
     Ext.Container
       Ext.Panel
         (Ext.tree.TreePanel)

UI组件在Google Closure的对象层次中

goog.Disposable
 goog.events.EventTarget
   goog.ui.Component
     (goog.ui.tree.BaseNode)

类goog.events.EventTarget应该是等价于Ext JS的Ext.util.Observable类, goog.Disposable 和goog.ui.Component应该是等价于Ext JS的Ext.Component类。而等价于Ext.BoxComponent, Ext.Container和Ext.Panel的类,在 Google Closure的对象层次中就没有找到,这些都是负责处理组件的布局问题的。

布局管理器Layout manager

Ext Js吸引我众多原因之中的一个原因,就是当初YahooUI!没有提供一个强大的布局管理器,而Ext Js是有的,——我便选用了Ext JS。
Google Closure好像就没有布局管理器了,这点我接受不了,因为没有了这玩意我不好干活!Google的意思是这些活儿让你自主发挥,所以你可以继续使用CSS或HTML的表格去布局,然后摆上你Widget部件就可以了。

事件处理Event handling

Google Closure的事件处理方面的逻辑代码编排在events.EventTarget类中,而对应 Ext Js的就放在Ext.util.Observable 类中。我发现,Google的方案好像只能在一个事件名称中指定一个处理函数。Ext的好像更为强大一些,额外地您可以指定函数作用域,延时,单体,缓冲和目标的参数。还有一点Ext让我更讨好的,那就是addListener方法中可用“on”等价之,也就是缩写了。Google Closure侦听事件的名称还是用addEventListener。用 dispatchEvent来触发事件,即等于Ext的fireEvent方法。

API文档

不得不说Ext的文档从感官和可用性来做得比其他开源软件要来的好,所说的开源软件自然也包括了Google Closure的documentation。
Google Closure的文档浏览起来有点怪,例如右下角是放置类的引用,搞得你要不断地滚动着它。而Ext的文档划分为两个面板的设计就似乎更轻松。其实每个类其文档的页面像Ext的那样就好。话说回来,由于我还没有使用Google Closure开发的经验,所以文档的帮助性有多大还是未知。嗯,没错Ext的文档中心还是我当初使用Ext的那样的好。

项目历史与开发者社区

我不知道Google Closure内部用了多久,应该很久吧(以Gmail 05启动开始算)。Ext 大概06年在研发,到现在应该也为数不少人开发人群了吧,有数字透露是500,000 developers (参见这个presentation)。你不能估量Google的边际去到哪,但反观Apple's iPhone vs. Google Android,小弟的结论是没有足够的理由说服自己从一个阵营立刻跳到对方阵营。

压缩混淆器

除了Google Closure库之外,Google还释出了 Closure Tools,其中就有一个compiler作为压缩和混淆JavaScript文件的工具,一并发布。如果应用在ExtJS身上,和我们一贯使用的YUICompressor又有什么区别呢,Ext论坛上的 一张帖子或许会告诉我们答案。
第一轮测试过后,论坛大大"Condor"指出,compiler压缩出来的ext-all-debug.js要比YUICompressor的文件体积小20KB。不清楚YUICompressor的大小是多少,也不知道他是不是想说压缩得很少。对于我来说这是没啥区别的。尽管后来他也说了如果压缩的时候加入更多项目代码进去的话,压缩率就会更理想的说。大家有兴趣的话请关注 这张帖子。

值得一提的是,Firebug的扩展Closure Inspector还可以调试已混淆的JavaScript代码。

Ext GWT vs. Ext JS vs. Google Web Toolkit vs. Google Closure

Google是这样宣传Google Web Toolkit的:“让Java软件开发者更轻松地写出如Google Maps和Gmail的AJAX应用程序”(Java software development framework that makes writing AJAX applications like Google Maps and Gmail easy for developers ...),

现在我就有点奇怪了,宣传Closur的时候,Google说这个库是Google旗下所有诸如Gmail的AJAX程序的底层。我想知道,Google Web Toolkit和Google Closurede关系是不是等同于 Ext GWT与Ext JS的关系,就是GWT运行以其他的应用(Java)来写JS库里面的功能。

另外,在放到浏览器之前,compile你的代码就可以做一次代码检查,也会报告错误,GWT就没有这功能了吧,因为Google Colsure现在是纯Js compile了。(翻译不顺,能者帮忙改)

License

不想多说,跟许多人一样,译者认为协议是Ext的明显诟病之一。所以以下内容不翻译了,————翻了就太枪手所为。
Ext JS is released under a dual license, which let's you use it in a GPL-based open-source application for free or in a closed commercial application for $329 per developer or less with volume discount.
Google Closure is freely available under the Apache License. jQuery creator John Resig apparently would have preferred the MIT license, since he just tweeted "I wish that Google Closure (the lib) was under the MIT license, can't really borrow code from it for jQuery, otherwise."
There are developers that avoid Ext JS because of the costs and license, others may choose Ext JS especially because of it and its commercial support.
The preference and choice is up to the developers and companies.
If you aren't a license expert yet, check out this comparison between the different type of licenses.

Grid widget

ExtJS居于我心目中的首位,很大程度跟这个Grid有关。我在项目中想要的就是仿MS Excel的Grid,我看到Ext JS的 grid,立刻被秒杀了。遗憾地是,Google Closure好像不打算提供这类东东,我唯一能找到可以控制表格数据的就是这个goog.ui.TableSorter类。Grid,,,没有就没有吧,反正AJAX又不是说只准一个库在这儿待着,我找第三方的就是了。

Tree widget

Tree器件往往是人们使用JavaScript库的开始,他们需要一个Tree的控件引入到他们的项目中。不同于Grid的待遇,在Closure里可以找到Tree部件(例子),Ext的例子在这里。太多部件的比较超出了本文的范围,我说的重点是,,,Google Closure里面是有Tree部件的。

范例或演示

Ext被广泛使用的一点,而且又是让人津津乐道的是,它的例子很完整!您完全可以靠这些丰富例子,就地取材很快的建立起一个像样的程序来。Google Closure也提供一批例子,在这儿(点击右边tab的“Demo”)。随着项目的不断研发,应该会有更多的例子加入。

使用率

毫无疑问,Google Closure的使用率明显强于Ext,君不见那么多的Gmail,Google Doc和Google Maps都在用着。同时也不时很对知名的公众网站在使用Ext。首要的原因是Ext更多地是用在内联网的应用程序。Ext绝对是致人印象深刻的客户端,您不妨看看这里。据我所知,使用Ext的实现有这三款的最好,Marketo,Zipwhip和Kohive。三款程序都很好地发挥了Ext的功用。

Default design

Ext JS的默认设计和模板比Google Closure的好很多,是不是?一个问题我经常看见设计师和Mac的用户会不用Ext默认的设计,因为ExtJs的默认设计是模仿的MS Windows的。你可以看看下面的例子,当然也允许你自己修改这些界面的。Ext 3的CSS模块划分更清晰而且有可视的CSS文件帮助您。

单元测试Unit Testing

对于单元测试的技术态度,Google明显强于Ext的态度,这点可以从Closure的命名空间和包管理方面可以看出来,为单元测试做好准备。
当然UI库是否要求单元测试必备尚有争议,但我觉得还是必须有若干的测试的。不过虽然Closure为单元测试创造了条件,但未知其真实测试会是怎么样。

http://blog.csdn.net/zhangxin09/article/details/4828070

文件结构图

说明: 下面我们先看看Google Closure的源文件物理结构图,有个比较直观的了解,后面会具体进一步分析,具体的类,命名空间和物理结构的关系

图例:

分析:

  • goog 是顶级文件夹,它又包含了更多的子文件夹(如:timer、ui)
  • 每个子文件夹下面一般都包含了具体的JS源文件(如:tooltip.js)
  • 有时候子文件夹下面还包含了更下一级的文件夹(如ui下面的editor),而更下一级文件夹又包含了JS源文件
  • 这里大部分深度是两层文件夹,第三层是JS源文件,而最大的深度是三层文件夹,第四层是JS源文件
  • 总的来说,整个组织结构还是比较扁平简单的,没有太复杂的组织规划

一个比较完整的类实现实例(toolTip.js)

说明:这里是摘 自Google Cloure Lib中的一个ui类 Tooltip的实现,中间为了简化,把一些重复功能的语句给删减掉了,不影响我们下面对类实现细节的分析

代码:

  1. //Tooltip 类
  2. goog.provide('goog.ui.Tooltip');
  3. goog.provide('goog.ui.Tooltip.State');
  4. goog.require('goog.Timer');
  5. goog.require('goog.array');
  6. goog.ui.Tooltip = function(opt_el, opt_str, opt_domHelper) {
  7. this.dom_ = opt_domHelper || (opt_el ?
  8. goog.dom.getDomHelper(goog.dom.getElement(opt_el)) :
  9. goog.dom.getDomHelper());
  10. goog.ui.Popup.call(this, this.dom_.createDom(
  11. 'div', {'style': 'position:absolute;display:none;'}));
  12. };
  13. goog.inherits(goog.ui.Tooltip, goog.ui.Popup);
  14. goog.ui.Tooltip.activeInstances_ = [];
  15. goog.ui.Tooltip.prototype.className = goog.getCssName('goog-tooltip');
  16. goog.ui.Tooltip.prototype.attach = function(el) {
  17. el = goog.dom.getElement(el);
  18. this.elements_.add(el);
  19. goog.events.listen(el, goog.events.EventType.MOUSEOVER, this.handleMouseOver,false, this);
  20. };

分析: 一个JS源文件包含如下几个部分

  • 自己能提供什么功能(类声明:使用goog.provide方法声明和注册一个类)
  • 提供这些功能需要额外的哪功能的支持(依赖声明:使用goog.require方法声明具体依赖的其它类)
  • 自身功能的具体实现(对象,类成员变量和成员方法声明和实现)
  • GO ON: 下面我们继续详细的分解每一部分的实现方式和细节

命名空间构造和注册(自己能提供什么功能)

说明: 下面是命名空间申明,声明一个js文件能提供哪些类,provide方法就是根据字符串创建一个JS对象,俗称命名空间

代码:

  1. //Tooltip 类声明
  2. goog.provide('goog.ui.Tooltip');
  3. goog.provide('goog.ui.Tooltip.State'); // Enum 形式的对象
  4. // ==========更多的例子============
  5. //[goog/array/array.js]
  6. goog.provide('goog.array');
  7. //[goog/dom/dom.js]
  8. goog.provide('goog.dom');// 命名空间声明,此命名空间下有变量和方法实现
  9. goog.provide('goog.dom.DomHelper');
  10. goog.provide('goog.dom.NodeType');
  11. //[goog/ui/combobox.js]
  12. goog.provide('goog.ui.ComboBox');
  13. goog.provide('goog.ui.ComboBoxItem'); // Combobox的子项类

分析:

  • 一个文件可以当成一个包
  • 一个包中能声明(注册)多个类(多个类之间关系都比较密切[Tooltip 和 Tooltip.State],一般存在直接引用或者逻辑上是包含关系[Combobox和ComboboxItem],一般不超过三个)
  • 结合最上面的文件物理结构,我们可以发现类的命名空间和文件夹结构基本是一一对应的,但却不是完全对应。(如:goog.ui.Tooptip类对应文件结构为goog/ui/tooltip.js,而goog.ui.Tooltip.State就不是了对应goog/ui/tooltip/state.js,所以不是完全对应)
  • 根据第三点,下面会进一步分析google为什么没有直接利用这种对应关系以简化类到源文件的映射….
  • GO ON: 声明完自己能提供什么功能后,下面接着我们需要收集实现这些功能,我们还可以充分利用已经存在和实现的哪些功能,所以就需要加载这些功能所对应的文件包。

直接依赖包加载(提供这些功能需要额外的哪功能的支持)

说明: 声明完成类或者对象后,这里就需要去加载该包直接依赖的其它包了,所谓直接依赖,就是指在代码实现中有直接引用类或者对象的,比如 goog.Timer.clear(this.showTimer),这里就需要使用goog.require(‘goog.Timer’)加载goog.Timer所在的文件包了。

代码 :

  1. //Tooltip 依赖包加载
  2. goog.require('goog.Timer');
  3. goog.require('goog.array');
  4. // 类,依赖和文件之间的关系实现
  5. goog.addDependency('ui/tooltip.js', ['goog.ui.Tooltip','goog.ui.Tooltip.State'], ['goog.Timer', 'goog.array', 'goog.dom']);
  6. goog.addDependency('ui/tree/treenode.js', ['goog.ui.tree.TreeNode'],['goog.ui.tree.BaseNode']);
  7. goog.addDependency('useragent/useragent.js', ['goog.userAgent'],['goog.string']);
  8. 。。。。。。

分析:

  • 这里理论上可以加载任意多个直接依赖的文件包
  • 这里只是实现了包对包的依赖,并且这里使用的是异步加载机制,所以无法实现同步调用机制,即方法对包的依赖
  • googleClosure 提供一张很大的表达来存储类及其类所依赖的其它类,以及该类对应的物理文件路径
  • 再结合上面的物理文件结构和类声明部分,就大概知道为什么这里采用了非常庞大的一张表来存储类与JS源文件的映射关系,因为上面说的它的类名和文件夹结构不是完全对应的,如果完全对应的话,我们就不需要一张这么大的表来指明这种映射了,直接根据对应规则即可得到类的物理文件路径
  • 当然,有一张映射表,物理文件结构会更灵活一些,比如这里的多个关系比较密切的类可以申明到一个文件中

构造函数实现

说明: 这里很简单,就是使用最原始也最符合js本身实现的一种方式声明一个类

代码:

  1. //Tooltip 构造函数
  2. goog.ui.Tooltip = function(opt_el, opt_str, opt_domHelper) {
  3. this.dom_ = opt_domHelper || (opt_el ?
  4. goog.dom.getDomHelper(goog.dom.getElement(opt_el)) :
  5. goog.dom.getDomHelper());
  6. goog.ui.Popup.call(this, this.dom_.createDom(
  7. 'div', {'style': 'position:absolute;display:none;'}));
  8. };

分析:

  • 直接使用最原生的方式,简单直接明了,不从形式上去模仿Java后者其它后端语言,个人比较推荐
  • 参数规范
    • a.所有参数直接使用单个变量形式,不使用把可选参数放到一个options对象中
    • b.针对可选参数,在前面opt_前缀,标识此参数是可选参数
  • 使用call形式调用父类构造函数进行初始化,这里就能实现把父类实例对象的数据绑定到当前子类实例对象上,至于父类方法的绑定请继续看下面的继承声明和实现

继承声明和实现

说明: 上面是JS类构造函数的实现,其中有调用父类构造函数的实现,下面就如何继承父类进行分析,搞清楚这里就能明白父类方法绑定到子类的实现方式

代码:

  1. //Tooltip 继承实现
  2. goog.inherits(goog.ui.Tooltip, goog.ui.Popup);
  3. // 继承方法实现
  4. goog.inherits = function(childCtor, parentCtor) {
  5. /** @constructor */
  6. function tempCtor() {};
  7. tempCtor.prototype = parentCtor.prototype;
  8. childCtor.prototype = new tempCtor();
  9. childCtor.superClass_ = parentCtor.prototype;
  10. childCtor.prototype.constructor = childCtor;
  11. };

分析:

  • 通过设置子类的prototype,引入一个含有空构造函数的tempCtor类,实现父类纯方法的继承
  • 通过增加一个superClass变量指向父类的prototype,实现父类方法的直接调用,而不用担心子类重写了父类的方法,类似java的super调用
  • 通过增加constructor变量指向子类自己,实现Js原生数据类型的 constructor 引用
  • GO ON: 上面把一个包文件的结构部分基本分析清楚了,下面我们再继续分析一下一个类具体成员变量和成员方法的声明和实现的细节处理

属性声明

说明: 再接再励,继续分析类成员变量的声明和实现,这个基本比较简单,没什么难度,主要是需要说明一些书写规则和业内规范

代码:

  1. //Tooltip 成员变量
  2. goog.ui.Tooltip.activeInstances_ = [];
  3. goog.ui.Tooltip.prototype.className = goog.getCssName('goog-tooltip');
  4. // 更多
  5. goog.ui.PopupBase.DEBOUNCE_DELAY_MS = 150;

分析:

  • 常量使用全大写,单词之间使用下划线分割
  • 很少的公有变量
  • 私有变量在后面添加下划线标识
  • 使用getter和setter访问私有变量
  • 没有保护权限的变量

方法实现

说明: 成员方法和成员变量基本一致

代码:

  1. //Tooltip 成员方法
  2. goog.ui.Tooltip.prototype.attach = function(el) {
  3. el = goog.dom.getElement(el);
  4. this.elements_.add(el);
  5. goog.events.listen(el, goog.events.EventType.MOUSEOVER, this.handleMouseOver,false, this);
  6. };

分析:

  • 使用prototype声明方法
  • 私有方法和私有变量保持一致,在后面添加下划线标识
  • 公有方法直接声明
  • 没有保护权限的方法

http://ued.sohu.com/article/611

google closure相关推荐

  1. 在项目中使用Google Closure Compiler

    现在的Web项目总是离不开大量JavaScript,而JS文件的体积也越来越大,也越来越影响页面的感知性能(Perceived Performance).因此,我们会对JS文件进行压缩,一方面是使用G ...

  2. 使用Google Closure DepsWriter生成JS依赖文件(二)

    使用ClosureBuilder 可以压缩JS文件,减小JS的大小.但是,当使用未压缩的源码时,需要使用到goog.require()来匹配需要的命名空间并且在页面中追加<script>标 ...

  3. 使用Google App Engine、Google Closure Library与Clojure编写HTML5应用

    上周,Freiheit.com的CTO Stefan Richter在慕尼黑举办的Google开发者日上谈到了他对于使用HTML 5与Google App Engine编写富Internet应用的愿景 ...

  4. JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法

    网上搜索了,目前主流的Js代码压缩工具主要有Uglify.YUI Compressor.Google Closure Compiler,简单试用了UglifyJS 和Google Closure Co ...

  5. 利用google closure依赖工具配置

    为什么80%的码农都做不了架构师?>>>    为什么需要引入google closure 这边有一篇文章简单介绍了为什么要引入google closure,有兴趣的可看看这里. 什 ...

  6. Google Closure Complier的使用

    参考老赵的这篇 俺觉得GC最精华的还是它的高级压缩功能,只不过用起来用点麻烦: 最好的是不需要引用第三方类库, 如果需要用得加上编译参数 也不需要提供给第三方 不要将js写到html中 html里面不 ...

  7. Google公开其JavaScript工具:Closure Compiler

    Google Code官方博客今日开源了一个Google内部使用的JavaScript工具:Closure Compiler.这个工具在Google的Gmail,Google文档和Google地图中都 ...

  8. 学了编译原理能否用 Java 写一个编译器或解释器?

    16 个回答 默认排序​ RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...

  9. Sublime Text 3 常用插件以及安装方法(转)

    http://www.cnsecer.com/460.html 安装Sublime Text 3插件的方法: 朋友们,小站活着不容易,全靠广告费养着了,如果本文对你有帮助.麻烦动下手点下页面的广告吧, ...

最新文章

  1. Sparse low rank approximation
  2. 【New】SAPUI5开发环境配置步骤
  3. mysql 4.0.21 下载_W2K下安装 MYSQL 4.0.21 手记
  4. javascript省市三层联动,修改
  5. mfc exe 在繁体系统 乱码_成都市招标文件编制及备案系统使用技巧问答
  6. Springboot校园二手市场实战开发
  7. 设置下载安装 桌面_电脑C盘快满了不要慌,别只知道清垃圾,这些设置也要改...
  8. 空间点到空间直线的距离求解
  9. 2019IDEA破解安装
  10. 为什么在计算机里打开U盘会闪退,U盘闪退怎么办?
  11. matlab simulink 例子,simulink实例超实用
  12. SQL Server 2014下载及安装教程
  13. Java程序监控工具
  14. 会议论文与期刊论文的写作差异
  15. 定时器计数器实验C语言程序,实验二 单片机定时器和计数器编程
  16. linux下 C语言perror函数的作用
  17. GameFramework篇:StarForce资源热更新讲解(二:具体操作步骤)
  18. Http的多线程下载
  19. Python干掉了98%的办公软件
  20. String的inturn()的运用

热门文章

  1. 「镁客·请讲」红茶移动金辉:以”eSIM技术和服务提供商”为定位,解决手机通信、物联网的诸多痛点...
  2. 高防服务器里的软件硬件防火墙你了解吗
  3. 15拆分成3个不同的自然数_小学二年级奥数训练题之分拆
  4. Linux下创建可执行bin安装文件
  5. 题目 2016: 新生的入队仪式
  6. SCI论文投稿经验分享——如何在投稿前准备好需要的材料
  7. 小目标检测的数据增强------Stitcher和Mosaic效果对比
  8. 有视频下载链接, 如何在浏览器上直接倍速观看?
  9. 为何在设置-安全中选择图案解锁后,《电源按钮即时锁定》按钮取消选中无效
  10. PLC控制与继电器控制有什么区别