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工作 请设定好自己创建的类的异常信息形式
————————————————————-
