分類  >  Web前端 >

MooTools源碼分析1 —— Native

tags:    時間:2013-12-10 11:10:07
MooTools源碼分析一 —— Native
轉自: http://mooui.com/blog/view.aspx?id=1

// 框架名,對象 var MooTools = { 	'version' : '1.2dev', // 里程碑版本 	'build' : '1519' // trac系統每次change的版本號 }; /*  * Native 是對內置或將之作為內置的對象的包裝化  */ var Native = function(options) { 	/* 	 * 這種寫法隨處可見,根據ECMA規範,||運算會自動將兩側表達式轉化為布爾值, 	 * 僅當表達式為0/undefined/null/false時為假,而且||的特性是當前表達式為false時才會執行后表達式, 	 * 用在這裡的目的是使沒傳參時設置options的默認值,以避免下面的代碼出錯 	 */ 	options = options || {}; 	// 繼續上面的寫法,設默認值為一空方法,用於add中執行implement的後續操作 	var afterImplement = options.afterImplement || function() { 	}; 	// 方法靜態化標記,為真時實例方法將被複制到類名下作為靜態方法,此時靜態方法的第一個參數會被作為實例方法內的this執行 	var generics = options.generics; 	// 用!==比較,當且僅當generics為false時為false,其它值按true處理,這是比較提高可靠性的一種處理方式 	generics = (generics !== false); 	// 用於對內置對象包裝時的原對象 	var legacy = options.legacy; 	// Prototype風格的初始化方法 	var initialize = options.initialize; 	// 是否保護原對象的原型方法,以免被繼承的同名方法覆蓋 	var protect = options.protect; 	// 指定類名,以用於$type方法的取值 	var name = options.name; 	// 又是||的寫法,在不提供初始化方法時直接使用內置的對象作為原型 	var object = initialize || legacy; 	// 設置構造器 	object.constructor = Native; 	// 用於$type方法的取值 	object.$family = { 		name : 'native' 	}; 	// 繼承legacy 	if (legacy && initialize) 		object.prototype = legacy.prototype; 	object.prototype.constructor = object; 	if (name) { 		// 全部用小寫,可以避免大小寫敏感,當然可以換成大寫,只是大寫不美觀、不直觀 		var family = name.toLowerCase(); 		// 寫在原型鏈上 		object.prototype.$family = { 			name : family 		}; 		// 類型化,現在可以使用object.type(object1)判斷object與object1是否同一家族/類型 		Native.typize(object, family); 	} 	// 總的為對象添加方法的處理 	var add = function(obj, name, method, force) { 		// 僅當不指定對象受保護,或指定強制覆蓋或原對象原型中不存在該方法時添加 		if (!protect || force || !obj.prototype[name]) 			obj.prototype[name] = method; 		// 方法靜態化,此時的靜態方法的第一個參數會被作為實例方法中的this執行 		if (generics) 			Native.genericize(obj, name, protect); 		// 後續處理 		afterImplement.call(obj, name, method); 		return obj; 	}; 	// implement靜態方法 	object.implement = function(a1, a2, a3) { 		if (typeof a1 == 'string') 			return add(this, a1, a2, a3); 		for (var p in a1) 			add(this, p, a1[p], a2); 		// 返回當前對象可以使方法支持鏈式寫法,如object.implement(...).implement(...),jQueryer的最愛 		return this; 	}; 	// 實現方法別名的靜態方法 	object.alias = function(a1, a2, a3) { 		if (typeof a1 == 'string') { 			a1 = this.prototype[a1]; 			if (a1) 				add(this, a2, a1, a3); 		} else { 			// 使alias支持object.alias({a : 'a1', b : 'b1'});這樣的多個方法進行別名處理 			for (var a in a1) 				this.alias(a, a1[a], a2); 		} 		// 使支持鏈式寫法 		return this; 	}; 	return object; }; // 用於同時對多個對象進行擴展實現,子對象須被Native化,或者實現了名為implement的靜態方法 Native.implement = function(objects, properties) { 	for (var i = 0, l = objects.length; i < l; i++) 		objects[i].implement(properties); }; // 方法靜態化 Native.genericize = function(object, property, check) { 	if ((!check || !object[property]) && typeof object.prototype[property] == 'function') 		object[property] = function() { 			// 將arguments數組化,一種技巧.(注:arguments並非數組而只是一個類似數組的對象) 			var args = Array.prototype.slice.call(arguments); 			// 將第一個參數作為原來實例方法的this指向 			return object.prototype[property].apply(args.shift(), args); 		}; }; // 使類支持類型比較,閉包使用技巧 Native.typize = function(object, family) { 	if (!object.type) 		object.type = function(item) { 			return ($type(item) === family); 		}; }; // 用於同時對多個對象進行別名操作 Native.alias = function(objects, a1, a2, a3) { 	for (var i = 0, j = objects.length; i < j; i++) 		objects[i].alias(a1, a2, a3); }; /*  * 模塊化寫法   * 因為js中的變數作用域只存在於function和with中,此處使用模塊化寫法避免全局變數污染,就地執行匿名方法  * 使Boolean/Native/Object支持類型比較操作  */ (function(objects) { 	for (var name in objects) 		Native.typize(objects[name], name.toLowerCase()); })({ 	'boolean' : Boolean, 	'native' : Native, 	'object' : Object }); /*  * 模塊化寫法   * 對下列內置類型進行Native化包裝,使之支持類型化,別名,繼承等  */ (function(objects) { 	// 其實new Native跟Native的結果應該是一樣的,但是有時為了安全起見,用new能避免很多無法考慮的數據引用 	for (var name in objects) 		new Native({ 			name : name, 			initialize : objects[name], 			protect : true 		}); })({ 	'String' : String, 	'Function' : Function, 	'Number' : Number, 	'Array' : Array, 	'RegExp' : RegExp, 	'Date' : Date }); /*  * 模塊化寫法   * 讓數組和字元串的實例方法靜態化(因為數組和字元串的應用比較多) 現在可以使用Array.pop  */ (function(object, methods) { 	for (var i = 0, l = methods.length; i < l; i++) 		Native.genericize(object, methods[i], true); 	// 雖然是匿名方法,但是仍然可以通過arguments.callee找到指向,這裡return使(function(){})()()()()的寫法成為可能 	return arguments.callee; })(Array, ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 		'slice', 'toString', 'valueOf', 'indexOf', 'lastIndexOf'])(String, ['charAt', 'charCodeAt', 		'concat', 'indexOf', 'lastIndexOf', 'match', 'replace', 'search', 'slice', 'split', 		'substr', 'substring', 'toLowerCase', 'toUpperCase', 'valueOf']);

推薦閱讀文章

Bookmark the permalink ,來源:互聯網