如果你想研究一些比较大型的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. tabhost中setup()和setup(LocalActivityManager activityGroup)

    如果用系统默认的tabhost时, 直接用getTabhost()初始化,整个类继承tabActivity. 当没有选择系统tabhost默认id时,而是自己定义的id时,必须使用 findViewB ...

  2. 字符集详解 ------------------------ UNICODE +UTF8

    http://my.oschina.net/goldenshaw/blog?catalog=3294521 http://my.oschina.net/goldenshaw/blog?catalog= ...

  3. asp.net网站性能优化2则

    摘要:Web服务器的性能优化有很多资料介绍了,多台主机负载均衡,查询结果的多级缓 存,数据库索引优化等都是常见的优化手段.随着后端优化空间越来越小,现在越来越多 的网站更注重前端性能的优化,就是浏览器 ...

  4. sybase SA密码重置

    sa 密码忘记解决之道: su - sybase cd ASE/install vi RUN_etoh2 在文件的末尾加入 -psa \ 停止原数据库服务 由于密码遗忘,所以只能通过kill进程停止服 ...

  5. CentOS7使用Redis

    使用Python操作Redis 安装pip # yum install python-pip 升级pip # pip install --upgrade pip 安装redis-py库 # pip i ...

  6. Spring Framework jar官方直接下载路径

    SPRING官方网站改版后,建议都是通过 Maven和Gradle下载,对不使用Maven和Gradle开发项目的,下载就非常麻烦,下给出Spring Framework jar官方直接下载路径: h ...

  7. .NET设计模式(7):创建型模式专题总结(Creational Pattern)

    ):创建型模式专题总结(Creational Pattern)    创建型模式专题总结(Creational Pattern) --.NET设计模式系列之七 Terrylee,2006年1月 转载: ...

  8. Powershell profile.ps1 cannot be loaded because its operation is blocked by software restriction policies

    Powershell profile.ps1 cannot be loaded because its operation is blocked by software restriction pol ...

  9. WampServer修改MySQL密码

    WampServer安装后密码是空的,需要设置一下 一般有两种方式: 一是通过phpMyAdmin直接修改: 二是使用WAMP的MySql控制台修改. 第一种: ①在phpMyAdmin界面中点击[用 ...

  10. 解决Oracle clob字段数据过大问题

    select * from user_lobs where table_name='WX_MAIL';--SYS_LOB0001313121C00015$$ MB FROM user_segments ...