prototype 剖析(1)


这篇文章不是用来说明怎么用prototype,不是教程,而是作为一个理论研究,看网络上都是写Prototype的使用,而没有多少人去解释这些设计与实现,给予后来的人以提示和学习。感觉实在是有必要写写了。但一直没有机会写,一来是觉得自己的水平还欠缺,二来是没有太多的时间来写文,三是表述起来比较困难,因为毕竟在框架中交互实现的地方太多,设计依赖也有很多。很难定下来如何描述谁先谁先。如何将这些设计与实现描述出来,且让人容易理解我在说什么,能够不将整个框架说得过于主观,这些都是比较头疼的问题。这次能有这一个机会来让我描述一下这个框架的设计,纯属偶然,没有太多时间来准备,因此,我没有写过多的细节,如果有遗漏之处,还请指出。

概要
Prototype是一个优雅的框架,在何处优雅,它带给我们什么启示?为何我们要学习它?下面我将从Type(类型),Hack,Closure(闭包),Context(上下文),Lazy function pattern(惰性函数模式)和Design(设计)客观的看来prototype。

总览、Design设计
假设你已经明天了怎么样去实现模块,了解了上面Prototype的实现,如果让你来编写一个框架,是否你能够胜任呢?是否能够写得比Prototype 好呢?很抱歉,这个问题我不能回答。不管答案怎么样,学习一下总没坏事,下面我们来讨论一下Prototype的是如何将他的代码组织起来的。

1)Object. 这是Prototype实现检测和扩展的核心,全部是静态方法。它提供了全局范围内的验证。
2)Enumerable. 它是全部可列举对象的核心所在。比如: Array, Hash, Object, Element对象的迭代实现。他们都要实现一个接口。_each方法,每个对象的each都是通过本对象中实现的each来实现的。以下图可以大概表示他们的层次关系




其它的对象的迭代实现都是扩展自Enumerable这个对象。_each方法是接口,所有的对象都要实现这个方法,Enumerable则象是基类对象。

3)inheritance. 在新版Prototype中,实现了新的Class.Create的方式,是代替原来的extend object方案,实现起来复杂得多,大量动态的调用了其它类型方法。
主要思路是用原型继承的方式实现继承,但在实现中用了N个闭包。N>=3层。包括实现$supper这个方法,与传统OO不同的是,这个$ supper方法,是作为参数传入子类中(且为第一个参数)才有效。(Prototype的方法是基于Alex Arnell写的plugin)
4)Template. 模板类提供了基于json数据的调用。比如一个字符串用Template可以作
Copy Code(拷贝代码)-Run HTML(运行代码)-Save Code(另存代码)
var s = "#{name}'s website is #{uri}";
var a = new Template(s);
var o = { name: 'never-online', uri: 'http://www.never-online.net/blog' };
a.evaluate(o);
//得到 never-online's website is http://www.never-online.net/blog
而这个evaluate方法依赖String中的原型方法gsub。

5)Selector. 基于yui-ext的selector。这个的思路比较多,只是大略的了解了DOMquery(yui-ext)的思路,就是compileMatch里采用组装字符串,形成function,动态解析selector。几个selector都是一点是一样的,都有一个cache数组存储临时数据。
6)Event. 在新版Prototype中,有一句评论是这么说的。从原来最差的Event模式,到了最好的Event模式。管理事件都是基于可列举对象的基类,比如在用于事件中的pluck,without等,在实现Event事件里,用了不少的"private"方法,而最后返回的只有几个方法,包括 observe, fire和stopObserving。我们也可以简洁的用图来表示





7)Ajax. 大概的图就是下面这样,感觉实现得还不错的(对于扩展来说)





8)Chaining stuff. 这个在jquery上面用得是最多的,当时jquery出现,推广该框架的时候就是用鼓励和使用Chaining, 这也成为jquery的代表了.
实际上Chaining就是一个循环. chaining是很有用的, 它可以用一种自然语言的方式来编程,而非命令式编式,但会消耗效率,因为迭代器使用过多.Prototype也用了部分链,这个链是从Element开始的,详细的实现我就不说了,原理也是很简单的:
$(id).observe('onclick',handler)就是一个例子,将Event继承到Element上即可

阅读更多
换一批

没有更多推荐了,返回首页