prototype.js 源碼解讀(02)

若是你想研究一些比較大型的js框架的源碼的話,本人建議你從其最初的版本開始研讀,由於最初的版本東西少,易於研究,然後的版本基本都是在其基礎上不斷擴充罷了,因此,接下來我不許備徹底解讀prototype.js的源碼了,而是拿它一些常見的API來解讀。javascript

 



//定時器類,比起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; } } } }

給變量賦值的狀況:java




賦`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多行匹配node

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); } } });
相關文章
相關標籤/搜索