2006 八月 22

prototype 源码解读

摘录snook.ca上的prototype类图


snook.ca 上的prototype类图 1.5.0_pre0 [ http://snook.ca/archives/000531.php]

什么是prototype?

Prototype is a JavaScript framework that aims to ease development of dynamic web applications.Featuring a unique, easy-to-use toolkit for class-driven development and the nicest Ajax library around, Prototype is quickly becoming the codebase of choice for web application developers everywhere.
prototype‘s home [http://prototype.conio.net/]

prototype 参考

Developer Notes for prototype.js [http://www.sergiopereira.com/articles/prototype.js.html]
Developer Notes for prototype.js 中文版 [http://thinhunan.cnblogs.com/archive/2006/04/01/DeveloperNotesForPrototype.html]

prototype 源码解读

Author:
Nick:飞扬轻狂 fallseir.lee
mail & GTalk:fallseir[at]gmail.com
blog:http://feed.feedsky.com/fallseir
Date:20060822
Publish :http://www.writely.com/View.aspx?docid=dg4t629m_2dsbf2g

此篇文档的宗旨
一、学习
二、理解
三、使用
四、扩展

prototype 结构


prototype 结构图

=============================================================

prototype

=============================================================

————————————————————-

2 Prototype

————————————————————-

2.1 Version

版本
d.d.d xxx

examples: in rico
var Rico = {
Version: ‘1.1.2′,
prototypeVersion: parseFloat(Prototype.Version.split(”.”)[0] + “.” + Prototype.Version.split(”.”)[1])
}

if((typeof Prototype==’undefined’) || Rico.prototypeVersion //验证prototype是否存在和版本是否过低
throw(”Rico requires the Prototype JavaScript framework >= 1.3″);

2.2 ScriptFragment

常量
用于匹配脚本块的内容

use in Object:

stripScripts: function() {//去除所有的脚本块
return this.replace(new RegExp(Prototype.ScriptFragment, ‘img’), ”);
},

extractScripts: function() {//获取脚本块内容的数组形式
var matchAll = new RegExp(Prototype.ScriptFragment, ‘img’);
var matchOne = new RegExp(Prototype.ScriptFragment, ‘im’);
return (this.match(matchAll) || []).map(function(scriptTag) {
return (scriptTag.match(matchOne) || [”, ”])[1];
});
},

2.3 emptyFunction()

(fun||Prototype.emptyFunction)(args,…);
提供if操作的简写形式,如果fun不存在将什么都不做

examples:
var fun=function(arg1,arg2){
alert(arg1+arg2);
};
(fun||Prototype.emptyFunction)(”hello “,”world!”); // alert(”hello world!”);
var fun2=null;
(fun2||Prototype.emptyFunction)(”hello “,”world!”); // nothing!

use in Ajax.Request

respondToReadyState: function(readyState) {// Ajax中的响应状态更改事件触发器
var event = Ajax.Request.Events[readyState]; // 获取事件标示
var transport = this.transport, json = this.evalJSON(); //初始化环境

if (event == ‘Complete’) {
try {
(this.options[’on’ + this.transport.status]
|| this.options[’on’ + (this.responseIsSuccess() ? ‘Success’ : ‘Failure’)]
|| Prototype.emptyFunction)(transport, json);//按优先级触发事件 如果处理函数不存在则执行emptyFunction忽略此事件
} catch (e) {
this.dispatchException(e);
}

if ((this.header(’Content-type’) || ”).match(/^text\/javascript/i))
this.evalResponse();
}

try {
(this.options[’on’ + event] || Prototype.emptyFunction)(transport, json);
Ajax.Responders.dispatch(’on’ + event, this, transport, json);
} catch (e) {
this.dispatchException(e);
}

/* Avoid memory leak in MSIE: clean up the oncomplete event handler */
if (event == ‘Complete’)
this.transport.onreadystatechange = Prototype.emptyFunction;
},

dispatchException: function(exception) { // 处理异常
(this.options.onException || Prototype.emptyFunction)(this, exception);
Ajax.Responders.dispatch(’onException’, this, exception);
}
// emptyFunction 充当默认处理方法

2.4 K(x)

(fun||Prototype.K)(value,argx);
提供?:操作的简写形式,如果fun不存在则返回value

use in Enumerable
all: function(iterator) { // 对Enumerable的每一个元素应用iterator方法
var result = true;
this.each(function(value, index) {
result = result && !!(iterator || Prototype.K)(value, index); //如果iterator不存在则返回value的值
//题外 “!!” 这个我理解为强制将返回值转换为boolean值
if (!result) throw $break; // throw $break 将导致each操作被中断 each内部协定,当然$continue将导致进入下一次迭代
});
return result;
},

any: function(iterator) { //K的另一次应用
var result = true;
this.each(function(value, index) {
if (result = !!(iterator || Prototype.K)(value, index))
throw $break;
});
return result;
},
// 个人理解为K是对待一些特殊情况的一般处理方式 和 emptyFunction 的应用方式相似

————————————————————-

3 Class

————————————————————-

3.1 create()

返回一function对象,默认调用initialize方法
var SampleClass=Class.create()
通过此方法创建的对象将提供对构造函数initialize的支持

use in prototype
Ajax.Updater = Class.create();
Ajax.PeriodicalUpdater = Class.create();
//使其支持 协定的构造函数 initialize

————————————————————-

4 Object

————————————————————-

4.1 extend(destination, source)

将source对象的属性和对应的值添加到destination对象中
Object.extend(clientObj,parentObj)
模仿继承source的属性和方法

use in Number …
Object.extend(Number.prototype, {
toColorPart: function() {
var digits = this.toString(16);
if (this // 在Number的原有属性和方法的基础上对Number的原型追加 其他扩展属性和方法
// 用于扩展一个类 或称之为继承 将后一个对象的属性(方法也是属性)追加到前一个对象上([Function].prototype将会导致应用于所有由此fun构造的对象)。

4.2 inspect(object)

检查当前对象的类型 如果object存在inspect方法将返回object中定义的数值表现形式
undefined=’undefined’,null=’null’,object.inspect()||object.toString()
,catch(e)=(’…’ ||throw e);

defined in prototype
String
inspect: function() {
return “‘” + this.replace(/\\/g, ‘\\\\’).replace(/’/g, ‘\\\”) + “‘”;
}
Enumerable
inspect: function() {
return ‘#’;
}
Array
inspect: function() {
return ‘[’ + this.map(Object.inspect).join(’, ‘) + ‘]’;
}
Hash
inspect: function() {
return ‘#’;
}

use in prototype
Selector
parseExpression: function() {
function abort(message) { throw ‘Parse error in selector: ‘ + message; }

if (this.expression == ”) abort(’empty expression’);

var params = this.params, expr = this.expression, match, modifier, clause, rest;
while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:”([^”]*)”|([^\]\s]*)))?\]$/i)) {
params.attributes = params.attributes || [];
params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ”});
expr = match[1];
}

if (expr == ‘*’) return this.params.wildcard = true;

while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
modifier = match[1], clause = match[2], rest = match[3];
switch (modifier) {
case ‘#’: params.id = clause; break;
case ‘.’: params.classNames.push(clause); break;
case ”:
case undefined: params.tagName = clause.toUpperCase(); break;
default: abort(expr.inspect());
}
expr = rest;
}

if (expr.length > 0) abort(expr.inspect());
},
// inspect 用于抛出异常的信息 如果要更好的使prototype工作 请设定好自己创建的类的异常信息形式

————————————————————-

没有评论 »

还没有评论。

RSS方式的评论。 TrackBack URI

发表评论

提示:如果你刚刚提交过评论,但是还没有被显示出来,请点击这里刷新一下: 刷新评论