如果你想研究一些比较大型的js框架的源码的话,本人建议你从其最初的版本开始研读,因为最初的版本东西少,易于研究,而后的版本基本都是在其基础上不断扩充罢了,所以,接下来我不准备完全解读prototype.js的源码了,而是拿它一些常见的API来解读。

//定时器类,比起window.setInterval函数,该类能够使得回调函数不会被并发调用

    var PeriodicalExecuter = Class.create();//Class类创建的定时器类
PeriodicalExecuter.prototype = {
initialize: function(callback, frequency) {//在原型上定义构造函数
this.callback = callback;//指定回调函数
this.frequency = frequency;//指定执行频率
this.currentlyExecuting = false;//默认不执行 this.registerCallback();
},
//开始执行定时器
registerCallback: function() {
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);//
},
//停止执行
stop: function() {
if (!this.timer) return;//判断不存在的情况
clearInterval(this.timer);//清除定时器
this.timer = null;//赋一个空指针,让人易于理解这是用来准备存放对象的
},
/*
相当于回调函数的一个代理。
在传统的setInterval函数中,时间一到,便强制执行回调函数,而这里加入了currentlyExecuting属性判断,
则如果callback函数的执行时间超过了一个时间片,则阻止其被重复执行。
*/
onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
this.callback(this);
} finally {
this.currentlyExecuting = false;
}
}
}
}

给变量赋值的情况:

赋`undefined`值:表明对象属性或方法不存在,或声明了变量但从未赋值。

赋`null`值:包含 `null` 的变量包含“无值”或“无对象”。换句话说,该变量没有保存有效的数、字符串、`boolean`、数组或对象。可以通过给一个变量赋 `null` 值来清除变量的内容。也表明这个变量是用来存放对象的。

//为字符串对象添加方法,和前面为Number添加方法的原理相同

  Object.extend(String.prototype, {
gsub: function(pattern, replacement) {
var result = '', source = this, match;
replacement = arguments.callee.prepareReplacement(replacement); while (source.length > 0) {
if (match = source.match(pattern)) {
result += source.slice(0, match.index);
result += String.interpret(replacement(match));
source = source.slice(match.index + match[0].length);
} else {
result += source, source = '';
}
}
return result;
}, sub: function(pattern, replacement, count) {
replacement = this.gsub.prepareReplacement(replacement);
count = count === undefined ? 1 : count; return this.gsub(pattern, function(match) {
if (--count < 0) return match[0];
return replacement(match);
});
}, scan: function(pattern, iterator) {
this.gsub(pattern, iterator);
return this;
}, truncate: function(length, truncation) {
length = length || 30;
truncation = truncation === undefined ? '...' : truncation;
return this.length > length ?
this.slice(0, length - truncation.length) + truncation : this;
}, strip: function() {
return this.replace(/^\s+/, '').replace(/\s+$/, '');
}, stripTags: function() {
return this.replace(/<\/?[^>]+>/gi, '');
}, stripScripts: function() {
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
}, //提取字符串中的脚本,返回所有脚本内容组成的数组
extractScripts: function() {
//找到所有包括<script>的代码标记
var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
//再对每个脚本删除<script>标记
var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
return (this.match(matchAll) || []).map(function(scriptTag) {
return (scriptTag.match(matchOne) || ['', ''])[1];
});
}, //先提取字符串中的脚本块,再执行这些脚本
evalScripts: function() {
return this.extractScripts().map(function(script) { return eval(script) });
}, //利用浏览器本身的机制对Html字符串进行编码,例如将<转换为&lt;
escapeHTML: function() {
var div = document.createElement('div');
var text = document.createTextNode(this);
div.appendChild(text);
return div.innerHTML;
}, //对Html进行解码
unescapeHTML: function() {
var div = document.createElement('div');
div.innerHTML = this.stripTags();
return div.childNodes[0] ? (div.childNodes.length > 1 ?
$A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
div.childNodes[0].nodeValue) : '';
}, /*
*获取查询字符串数组,例如通过document.location.toQueryParams()就可以得到由键和值组成的哈希表(用对象表示)。
*/
toQueryParams: function(separator) {
var match = this.strip().match(/([^?#]*)(#.*)?$/);
if (!match) return {}; return match[1].split(separator || '&').inject({}, function(hash, pair) {
if ((pair = pair.split('='))[0]) {
var name = decodeURIComponent(pair[0]);
var value = pair[1] ? decodeURIComponent(pair[1]) : undefined; if (hash[name] !== undefined) {
if (hash[name].constructor != Array)
hash[name] = [hash[name]];
if (value) hash[name].push(value);
}
else hash[name] = value;
}
return hash;
});
}, //将字符串转换为字符数组
toArray: function() {
return this.split('');
}, succ: function() {
return this.slice(0, this.length - 1) +
String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
}, //将用"-"连接的字符串驼峰化
//例如:background-color转为backgroundColor
camelize: function() {
var parts = this.split('-'), len = parts.length;
if (len == 1) return parts[0]; var camelized = this.charAt(0) == '-'
? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
: parts[0]; for (var i = 1; i < len; i++)
camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); return camelized;
}, //转换成大写形式
capitalize: function(){
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
}, //转换成下划线形式
underscore: function() {
return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
}, //转化成中划线
dasherize: function() {
return this.gsub(/_/,'-');
}, //将字符串转换为可观察的形式。这里将转义字符写成转义前的字符串形式
inspect: function(useDoubleQuotes) {
var escapedString = this.replace(/\\/g, '\\\\');
if (useDoubleQuotes)
return '"' + escapedString.replace(/"/g, '\\"') + '"';
else
return "'" + escapedString.replace(/'/g, '\\\'') + "'";
}
});

注:i:忽略大小写,g全局匹配,m多行匹配

String对象中的正则表达式法:

方法 含义
match(pattern) 返回pattern中的子串或null
replace(pattern,replacement) 用replacement替换pattern
search(pattern) 返回字符串中pattern开始位置
split(pattern) 返回字符串按指定pattern拆分的数组

all: function(iterator) {
var result = true;
this.each(function(value, index) {
result = result && !!(iterator || Prototype.K)(value, index);
if (!result) throw $break;
});
return result;
}, /*判断枚举对象中的所有元素是否有满足指定迭代器的值(返回true),如果有则返回true,否则返回false
*/
其原理和all方法类似
any: function(iterator) {
var result = false;
this.each(function(value, index) {
if (result = !!(iterator || Prototype.K)(value, index))
throw $break;
});
return result;
},
/*
返回所有枚举元素通过迭代器执行的结果,作为数组返回
*/
collect: function(iterator) {
var results = [];
this.each(function(value, index) {
results.push((iterator || Prototype.K)(value, index));
});
return results;
}, /*返回第一个能够使得迭代器返回true的枚举元素的值,如果没有true,则返回"undefined",即result未被赋值
*/
detect: function(iterator) {
var result;
this.each(function(value, index) {
if (iterator(value, index)) {
result = value;
throw $break;
}
});
return result;
},
/*
返回所有能够使得迭代器返回true的枚举元素,作为数组返回。
*/
findAll: function(iterator) {
var results = [];
this.each(function(value, index) {
if (iterator(value, index))
results.push(value);
});
return results;
}, grep: function(pattern, iterator) {
var results = [];
this.each(function(value, index) {
var stringValue = value.toString();
if (stringValue.match(pattern))
results.push((iterator || Prototype.K)(value, index));
})
return results;
}, include: function(object) {
var found = false;
this.each(function(value) {
if (value == object) {
found = true;
throw $break;
}
});
return found;
},
/**
* Element 就象一个 java 的工具类,主要用来 隐藏/显示/销除 对象,以及获取对象的简单属性。
*
*/
if (!window.Element) {
var Element = new Object();
} Object.extend(Element, {
/**
* 切换 显示/隐藏
*/
toggle: function() {
for (var i = 0; i < arguments.length; i++) {
var element = $(arguments[i]);
element.style.display =
(element.style.display == 'none' ? '' : 'none');//三目运算符判断
}
}, hide: function() {
for (var i = 0; i < arguments.length; i++) {
var element = $(arguments[i]);//将选中的参数赋值给element
element.style.display = 'none';//你懂的
}
}, show: function() {
for (var i = 0; i < arguments.length; i++) {
var element = $(arguments[i]);
element.style.display = '';
}
}, /**
* 从父节点中移除
*/
remove: function(element) {
element = $(element);
element.parentNode.removeChild(element);
}, getHeight: function(element) {
element = $(element);
return element.offsetHeight;
}, /**
* 是否拥有 class 属性值
*/
hasClassName: function(element, className) {
element = $(element);
if (!element)
return;
var a = element.className.split(' ');
for (var i = 0; i < a.length; i++) {
if (a[i] == className)
return true;
}
return false;
}, /**
* 为对象添加 class 属性值
*/
addClassName: function(element, className) {
element = $(element);
Element.removeClassName(element, className);
element.className += ' ' + className;
}, /**
* 为对象移除 class 属性值
*/
removeClassName: function(element, className) {
element = $(element);
if (!element)
return;
var newClassName = '';
var a = element.className.split(' ');
for (var i = 0; i < a.length; i++) {
if (a[i] != className) {
if (i > 0)
newClassName += ' ';
newClassName += a[i];
}
}
element.className = newClassName;
}, // removes whitespace-only text node children
cleanWhitespace: function(element) {
var element = $(element);
for (var i = 0; i < element.childNodes.length; i++) {
var node = element.childNodes[i];
if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
Element.remove(node);
}
}
});
 

prototype.js 源码解读(02)的更多相关文章

  1. prototype.js 源码解读(01)

    prototype.js是一个设计的非常优雅且很有实用价值的js基础类库,其源码非常值得研究.研究它的源码不仅能提升个人水平,而且对你打下坚实的js基础也很有帮助.因本人技术水平有限,该解读仅供参考. ...

  2. js便签笔记(10) - 分享:json2.js源码解读笔记

    1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...

  3. js便签笔记(10) - 分享:json.js源码解读笔记

    1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...

  4. fastclick.js源码解读分析

    阅读优秀的js插件和库源码,可以加深我们对web开发的理解和提高js能力,本人能力有限,只能粗略读懂一些小型插件,这里带来对fastclick源码的解读,望各位大神不吝指教~! fastclick诞生 ...

  5. json2.js源码解读记录

    相关内容:json详细用法.js语法.unicode.正则   json特点--最简单.最小巧的经典js库.   json作者:道克拉斯.克劳福德(Douglas Crockford)--js大牛 出 ...

  6. require.js 源码解读——配置默认上下文

    首先,我们先来简单说一下,require.js的原理: 1.载入模块
 2.通过模块名解析出模块信息,以及计算出URL
 3.通过创建SCRIPT的形式把模块加载到页面中.
 4.判断被加载的脚本,如 ...

  7. 亚马逊左侧菜单延迟z三角 jquery插件jquery.menu-aim.js源码解读

    关于亚马逊的左侧菜单延迟,之前一直不知道它的实现原理.梦神提到了z三角,我也不知道这是什么东西.13号那天很有空,等领导们签字完我就可以走了.下午的时候,找到了一篇博客:http://jayuh.co ...

  8. 前端编译原理 parser.js源码解读

    前面已经介绍了一个jison的使用,在正常开发中其实已经够用下,下面主要是看了下parser.js代码解读下,作为一些了解. 下面以最简单的文法产生的parser做一些代码注释 下面是一些注释,标示了 ...

  9. prototype.js源码

    prototype 1.3.1 版本和之前的 1.2.0 版本有了不少改进,并增加了新的功能: 1. 增加了事件注册管理2. 增加了空间定位的常用函数3. 改善了 xmlhttp 的封装4. 移除了 ...

随机推荐

  1. PHP汉字转拼音的两种方法+PHP提取汉字(中文)方法

    方法一:依据ASCII码转换,GB2312库对多音字也无能为力. GB2312标准共收录6763个汉字,不在范围内的汉字是无法转换.如:中国前总理朱镕基的"镕"字. GB2312中 ...

  2. LabVIEW系列——合并错误(VI)的用法

    Merge Errors.vi的功能:1.按顺序搜索错误输入1,2,3,以及错误数组输入中的错误,输出第一个错误.                        2.如果没有错误,也就是错误状态都为F ...

  3. ServletContext对象--三大域对象

    Servlet三大域对象的应用 request.session.application(ServletContext) ServletContext是一个全局的储存信息的空间,服务器开始就存在,服务器 ...

  4. LAMP环境部署总结

    linux+apche+mysql+php 此次用到的工具有:/etc/init.d/iptables , selinux, useradd, yum,chkconfig,sshd,visudo,cr ...

  5. Android 解决调用系统相册打不开图片 DecodeServices报解码错误

    这是由于系统相册不知道你图片目录是一个相册.打开前需要向系统相册“注册一下”,说白了就是让系统相册知道你这个图片所在的文件夹是个相册. private static void scanImageFil ...

  6. 使用Windows的NAT功能

    使用管理员权限打开命令行控制台. 端口映射相关命令 查看当前机器的端口代理表: netsh interface portproxy show all C:\WINDOWS\system32>ne ...

  7. jQuery模拟页面加载进度条

    因为我们无法通过任何方法获取整个页面的大小和当前加载了多少,所以想制作一个加载进度条的唯一办法就是模拟.那要怎么模拟呢? 我们知道,页面是从上往下执行的,也就是说我们可以大致估算出在页面的某个位置加载 ...

  8. 消息中间件MQ基础理论知识

    欢迎转载,转载请注明出处:http://www.cnblogs.com/lidabnu/p/5723280.html 消息中间件已经流行很长时间,一般情况下,不需要自己来从头研发.设计消息中间件,所以 ...

  9. python中文件类的应用

    python中对文件.文件夹的操作需要涉及到os模块和shutil模块. 创建文件: 1) os.mknod("test.txt") 创建空文件 2) open("tes ...

  10. iOS军火库-好用的ActionSheetView

    GitHub地址 一个自定义的ActionSheetView,支持显示标题,默认选中,使用block回调. 使用说明 [GLActionSheet showWithDataSource:@[@&quo ...