DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> MooTools教程(告訴你為什麼學Mootools)
MooTools教程(告訴你為什麼學Mootools)
編輯:關於JavaScript     

網頁制作poluoluo文章簡介:MooTools是一個簡潔,模塊化,面向對象的JavaScript框架。它能夠幫助你更快,更簡單地編寫可擴展和兼容性強的JavaScript代碼。Mootools跟prototypejs相類似,語法幾乎一樣。但它提供的功能要比prototypejs多,而且更強大。比如增加了動畫特效、拖放操作等等。建議大家可

MooTools是一個簡潔,模塊化,面向對象的JavaScript框架。它能夠幫助你更快,更簡單地編寫可擴展和兼容性強的JavaScript代碼。Mootools跟prototypejs相類似,語法幾乎一樣。但它提供的功能要比prototypejs多,而且更強大。比如增加了動畫特效、拖放操作等等。建議大家可以用它來代替prototypejs。

我為什麼選擇mootools,拋棄了prototype. (mootools 與 prototype 核心代碼分析)

===========================================
前言
===========================================

最近喜歡上了mootools(相見恨晚啊),在公開表示了對他的偏愛.
很多朋友都問我為什麼要移情別戀,其實理由還是蠻多的.

今天在這裡打算列舉出一部分.讓更多的朋友能夠了解一下mootools,也希望有更多的朋友喜歡上他.

文章的標題注定了我會更多的講述 mootools比prototype好的地方,
希望大家不要被我的誤導,以為mootools處處都比prototype好.
mootools還是有一些不足的.

本次對比針對 mootools 1.11版 和 prototype 1.51版,
只比較了一些核心代碼,其他的工具方法,輔助函數不再本文討論之內.

開始前,再次重申一遍:我曾經很愛prototype,而且我將永遠都會用"偉大"來形容它.

好 下面對比正式開始 (
mootools以下簡稱moo.
本文所引用的代碼, 只是起到說明作用,不保證他們都可以被正確的執行.
同時為了使本文簡潔一些,引入的 一些 moo和prototype的代碼也只是片段或是偽代碼.
)

===========================================
一. 類機制
===========================================

js裡的類實際上就是function.
如果不使用任何框架和組件,那麼想創建一個自己類也不是難事,方法如下:

 

 

Java代碼

 

  1. var PersonClass=function(name,gender){   
  2.     this.name=name;   
  3.     this.gender=gender;   
  4.     alert("My name is "+this.name);   
  5. }   
  6.   
  7. var myGirlFriend=new PersonClass('Vickey','female');  

 

var PersonClass=function(name,gender){
	this.name=name;
	this.gender=gender;
	alert("My name is "+this.name);
}

var myGirlFriend=new PersonClass('Vickey','female');

執行 後, 會創建一個PersonClass類的實例myGirlFriend, 並執行function內的語句.
那些語句可以理解為是類的構造函數.

Prototype
現在來看看在prototype的幫助下如何去定義這個類:

 

 

Java代碼

 

  1. var PersonClass = Class.create();   
  2.   
  3. PersonClass.prototype.initialize=function(name,gender){   
  4.     this.name=name;   
  5.     this.gender=gender;   
  6.     alert("My name is "+this.name);   
  7. };   
  8.   
  9. var myGirlFriend=new PersonClass('Vickey','female');   
  10.   
  11. //如果想給類增加屬性和方法時使用    
  12. PersonClass.prototype.XXX=...;   
  13. //或者是使用 prototype提供的    
  14. Object.extend(PersonClass.prototype, {...} );  

 

var PersonClass = Class.create();

PersonClass.prototype.initialize=function(name,gender){
	this.name=name;
	this.gender=gender;
	alert("My name is "+this.name);
};

var myGirlFriend=new PersonClass('Vickey','female');

//如果想給類增加屬性和方法時使用 
PersonClass.prototype.XXX=...;
//或者是使用 prototype提供的 
Object.extend(PersonClass.prototype, {...} );


(關於Object.extend稍後在對比繼承機制時再細說.)

再來看看prototype是實現類機制的核心代碼.

 

 

Java代碼

 

  1. var Class = {   
  2.   create: function() {   
  3.     return function() {   
  4.       this.initialize.apply(this, arguments);   
  5.     }   
  6.   }   
  7. }  

 

var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
}


通過看代碼不難看出,prototype的Class實際上只是幫助我們抽象出了"類的構造函數".
而當我們在prototype的這種機制下進行類的定義時,實際上帶來的好處是非常有限的.
prototype的Class只是從結構對我們的類進行了重新規劃. 而這樣的規劃意義並不是很大.
而且prototype帶有強制性,即, initialize 是必須要定義的.
實際上這裡存在一個缺陷, Class應該提供一個默認的initialize(一個空函數就好),
或者是在create返回的function裡進行必要的判斷.
(prototype1.6的類機制變化比較大,但是還沒仔細研究過,所以不敢輕易評論).

Mootools

現在來看看在 moo的幫助下如何去定義一個類:

 

 

Java代碼

 

  1. var PersonClass = new Class( {   
  2.     initialize: function(name,gender){   
  3.         this.name=name;   
  4.         this.gender=gender;   
  5.         alert("My name is "+this.name);   
  6.     }   
  7. });   
  8. var myGirlFriend=new PersonClass('Vickey','female');  

 

var PersonClass = new Class( {
	initialize: function(name,gender){
		this.name=name;
		this.gender=gender;
		alert("My name is "+this.name);
	}
});
var myGirlFriend=new PersonClass('Vickey','female');


其中類的 initialize 不是必須的.
如果你想給 PersonClass 增加屬性和方法,你可以在new Class的參數裡直接以 json方式定義.
也可以使用 如下方式

 

 

Java代碼

 

  1. PersonClass.implement ({    
  2.     age:0 ,   
  3.     getName : function() {return this.name;}   
  4. } , {...}, ..... );  

 

PersonClass.implement ({ 
	age:0 ,
	getName : function() {return this.name;}
} , {...}, ..... );


implement支持多個{}.關於implement稍後在對比繼承機制時再細說.

網頁制作poluoluo文章簡介:MooTools是一個簡潔,模塊化,面向對象的JavaScript框架。它能夠幫助你更快,更簡單地編寫可擴展和兼容性強的JavaScript代碼。Mootools跟prototypejs相類似,語法幾乎一樣。但它提供的功能要比prototypejs多,而且更強大。比如增加了動畫特效、拖放操作等等。建議大家可



在來看一下moo類機制的一些核心代碼.

 

 

Java代碼

 

  1. var Class = function(properties){   
  2.     var klass = function(){   
  3.         return (arguments[0] !== null && this.initialize && $type(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this;   
  4.     };   
  5.     $extend(klass, this);   
  6.     klass.prototype = properties;   
  7.     klass.constructor = Class;   
  8.     return klass;   
  9. };   
  10.   
  11. Class.prototype = {   
  12.     extend: function(properties){   
  13.         var proto = new this(null);   
  14.         for (var property in properties){   
  15.             var pp = proto[property];   
  16.             proto[property] = Class.Merge(pp, properties[property]);   
  17.         }   
  18.         return new Class(proto);   
  19.     },   
  20.     implement: function(){   
  21.         for (var i = 0, l = arguments.length; i < l; i++) $extend(this.prototype, arguments[i]);   
  22.     }   
  23.   
  24. };  

 

var Class = function(properties){
	var klass = function(){
		return (arguments[0] !== null && this.initialize && $type(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this;
	};
	$extend(klass, this);
	klass.prototype = properties;
	klass.constructor = Class;
	return klass;
};

Class.prototype = {
	extend: function(properties){
		var proto = new this(null);
		for (var property in properties){
			var pp = proto[property];
			proto[property] = Class.Merge(pp, properties[property]);
		}
		return new Class(proto);
	},
	implement: function(){
		for (var i = 0, l = arguments.length; i < l; i++) $extend(this.prototype, arguments[i]);
	}

};

代碼的具體原理就不細說了.大家在moo的Class裡看到了 extend 和implement,那下面就來具體說一說moo和prototype的 繼承機制吧.

===========================================
二. 繼承機制
===========================================

Prototype
prototype提供的繼承很簡單.

 

 

Java代碼

 

  1. Object.extend = function(destination, source) {   
  2.   for (var property in source) {   
  3.     destination[property] = source[property];   
  4.   }   
  5.   return destination;   
  6. }  

 

Object.extend = function(destination, source) {
  for (var property in source) {
    destination[property] = source[property];
  }
  return destination;
}

他只是把source裡的屬性賦給destination,同時會覆蓋destination裡的同名屬性.
他可以用於對象,也可以用於類,當要實現類的繼承時,destination要使用 MySubClass.prototype.

prototype的繼承機制可以說是非常薄弱的.

Mootools

moo提供了三種繼承機制:

首先他也提供了簡單的繼承機制:
Objcet.extend (注意,不是上面代碼中 Class 裡的 extend)
他的代碼如下

 

 

Java代碼

 

  1.   
  2. var $extend = function(){   
  3.     var args = arguments;   
  4.     if (!args[1]) args = [this, args[0]];   
  5.     for (var property in args[1]) args[0][property] = args[1][property];   
  6.     return args[0];   
  7. };   
  8. Object.extend = $extend;  

 

var $extend = function(){
	var args = arguments;
	if (!args[1]) args = [this, args[0]];
	for (var property in args[1]) args[0][property] = args[1][property];
	return args[0];
};
Object.extend = $extend;


他的使用方法和 prototype 完全一樣.

但是大家可能注意到了 這句 if (!args[1]) args = [this, args[0]]; 這句的純在使得下面的代碼寫法成為可能.

 

 

Java代碼

 

  1. var myObjcet={....};   
  2. myObjcet.extend=$extend;   
  3. myObjcet.extend(objA);   
  4. myObjcet.extend(objB);   
  5. myObjcet.extend(objC);  

 

var myObjcet={....};
myObjcet.extend=$extend;
myObjcet.extend(objA);
myObjcet.extend(objB);
myObjcet.extend(objC);

簡單的一句話,讓extend的用法增加了更多的靈活性,不得不贊一個了!!!

網頁制作poluoluo文章簡介:MooTools是一個簡潔,模塊化,面向對象的JavaScript框架。它能夠幫助你更快,更簡單地編寫可擴展和兼容性強的JavaScript代碼。Mootools跟prototypejs相類似,語法幾乎一樣。但它提供的功能要比prototypejs多,而且更強大。比如增加了動畫特效、拖放操作等等。建議大家可



下面說說重點, moo的類裡的extend和 implement
先說 implement,之前已經說了一些了

 

 

Java代碼

 

  1. var MyClassA = new Class();   
  2. MyClassA.implement( { methodA : function() {... } }  );  

 

var MyClassA = new Class();
MyClassA.implement( { methodA : function() {... } }  );

執行後 MyClassA 將擁有 methodA.

implement用來向類中添加屬性和方法(會覆蓋同名屬性和方法),相當於
Object.extend (MyClassA.prototype , {... } )
但是Object.extend 不支持多個source,implement可以,示例如下:
MyClassA.implement( objA , objB, objC ... );

下面來看看moo的Class.extend.
moo的Class.extend才是我們期待的真正的"類繼承",看一下官方的示例

 

 

Java代碼

 

  1. var Animal = new Class({   
  2.     initialize: function(age){   
  3.         this.age = age;   
  4.     }   
  5. });   
  6. var Cat = Animal.extend({   
  7.     initialize: function(name, age){   
  8.         this.parent(age); //will call the previous initialize;   
  9.         this.name = name;   
  10.     }   
  11. });  

 

		var Animal = new Class({
			initialize: function(age){
				this.age = age;
			}
		});
		var Cat = Animal.extend({
			initialize: function(name, age){
				this.parent(age); //will call the previous initialize;
				this.name = name;
			}
		});

看那個parent() !!!!
通過moo的Class.extend實現的繼承提供一個關鍵的方法 parent().
使用他你可以調用父類中的同名方法,好像java裡的super一樣.
這個示例已經可以說明一切了.

關於prototype和moo的類機制和繼承機制的對比就到這裡,孰優孰劣大家心裡應該有數了吧.

===========================================
三.抽象對象
===========================================

再來看一看"抽象對象". 這個雖然對於開發人員來說用處不大,但還是對比一下吧,小細節也能看出作者的用心.

Prototype
prototype的抽象對象很簡單
var Abstract = new Object();
具體的意義不大.

Mootools
moo的的抽象對象相對更完善一些.

 

 

Java代碼

 

  1. var Abstract = function(obj){   
  2.     obj = obj || {};   
  3.     obj.extend = $extend;   
  4.     return obj;   
  5. };  

 

var Abstract = function(obj){
	obj = obj || {};
	obj.extend = $extend;
	return obj;
};


支持自定義抽象(以參數形式傳入),同時會為抽象對象自動添加extend方法.

===========================================
四. 關於 $()
===========================================

Prototype
prototype的$大家都比較熟悉了, 工作原理就是
通過id取得一個頁面元素(或者直接傳入一個頁面元素對象),然後給他增加一些prototype提供的方法和屬性,來方便開發人員對頁面元素的使用.

Mootools
moo在這方面做的差不多.
不同的主要有兩點, 首先moo為頁面元素增加的方法和屬性與prototype的不同(這個稍後會介紹),另外一個不同是moo的$兼具了對象管理的一個功能.
他引入了一個  Garbage 類, 來對頁面元素進行一個統一的管理和回收(主要是回收).
可以更好的減少js(或浏覽器)造成的內存洩露等問題.

具體的大家可以看一下代碼,在這裡就不詳細說明了.

網頁制作poluoluo文章簡介:MooTools是一個簡潔,模塊化,面向對象的JavaScript框架。它能夠幫助你更快,更簡單地編寫可擴展和兼容性強的JavaScript代碼。Mootools跟prototypejs相類似,語法幾乎一樣。但它提供的功能要比prototypejs多,而且更強大。比如增加了動畫特效、拖放操作等等。建議大家可



===========================================
五.關於 Array Enumerable Hash
===========================================

prototype 和 moo 都提供了集合迭代方法 (each)
這個網上已經有一篇不錯的對比文章,我就不在這裡重復了
http://blog.fackweb.cn/?p=50.

moo的 forEach/each方法: function(fn, bind){..}
那個bind 結合代碼 和 上面那篇文章, 大家應該可以很好的看出來prototype和moo的不同與優劣.

prototype裡面有 Enumerable 的概念,moo沒有.
但是我個人一直覺得 Enumerable 比較雞肋.
在實際開發中,很少使用.
Enumerable的功能完全可以 用普通json對象 或者是 Hash來實現.
moo的作者也許同樣這麼認為.所以 不再 設置一個 雞肋的 Enumerable類.
但是請大家放心, Enumerable 能做的事情, 在moo裡也能完成.

可以理解為

moo的 Array +  Hash +{} 完全可以接替 prototype的 Array + Enumerable + Hash +{}
當然對於一些工具方法兩者提供的都不太一樣,不好比較,但是那些方法都是附屬品.
我們完全可以自己來實現,所以不在這次的比較范疇之內.

===========================================
六. 關於 Element
===========================================

兩者的 Element 從作用上看類似.都是一種對頁面元素的包裝,為頁面元素添加了一些諸如 addEvent remove style之類的方法.
但是大家通過看代碼可以發現 moo的實現明顯更簡潔 更OO.

同時還有一個關鍵的不同,prototype又提取出了一個Form對象,裡面包含了很多表單相關的方法.
同時還衍生出了 serializeElements Method 等等很多類和方法,代碼瞬間變得異常復雜和難以琢磨.

而moo中沒有Form對象,在moo中,Form本身就是一個Element 他沒什麼特別的,這樣的思想類似components模式
普通Element具備的方法 Form 都應該具備, Form具備的方法 Element也都應該包含.form 和 其他頁面元素沒什麼不同.
form元素只是一個包含了 input select textarea等子元素,同時擁有action target等屬性而已.
一個p 一個span 一個td... 同樣可以包含input select textarea子元素,同樣可以擁有.action target屬性.
浏覽器處理他們的方式可能不同,但是在moo面前,大家完全平等.

其實prototype裡 form和普通頁面元素幾乎也是平等的,但是問題就是,既然是平等的,又何必硬生生的造出Form以及那麼多的衍生物呢?

===========================================
七.Ajax
===========================================

Prototype
prototype的ajax實現主要是靠一個 Ajax類 來實現.(但是這個類形同虛設,大家更多的是和 Ajax.Request 類打交道.

先來看一個prototype下一個簡單的ajax提交實例:

 

 

Java代碼

 

  1. var myAjax = new Ajax.Request( url,{parameters: myData , onComplete: callBackFunction } );  

 

var myAjax = new Ajax.Request( url,{parameters: myData , onComplete: callBackFunction } );


其中 myData 可以是字符 : "name=Vickey&gender=female";
也可以是對象 { name : Vickey, gender : female }

Mootools
moo首先在將ajax機制分層.提取出了一個基類:XHR.
目前XHR有兩個子類, 一個是 Ajax ,另一個是Json.Remote.

在moo下一個簡單的ajax提交實例:

 

 

Java代碼

 

  1. var myAjax =new Ajax(url, {data : myData , onComplete: callBackFunction  }).request();  

 

 var myAjax =new Ajax(url, {data : myData , onComplete: callBackFunction  }).request();


大家可以看到request成為了Ajax對象的一個方法,這樣的設計顯然是更合理更自然 也更OO的.

而且關鍵的一點是,你可以提前創建好你需要的ajax對象.在需要發出請求時再發出請求.

 

 

Java代碼

 

  1. var myAjax =new Ajax(...);   
  2. ....   
  3. myAjax.request();  

 

 var myAjax =new Ajax(...);
.....
 myAjax.request();


同時還有一個重要特性, request是支持參數的,這個參數就是你要提交的數據.

也就是說,你可以在new Ajax時不指定數據或者指定一個默認數據.
在提交的時候可以提交另一個data.如.

myAjax.request(yourData);

其中data可以是字符串,可以是對象, 也可以是一個頁面元素.

要用ajax提交一個form 或者一個 p下的所有表單元素,只是改變一下 myData.
var myData= $("formID");  // var myData= $("pID");
然後就和普通的ajax提交完全一樣了.

myAjax.request(myData);

當然還有更oo的方式 :
myData.send({onComplete: callBackFunction });

用後一種方式的時候要保證提交的元素有action屬性,沒有你就賦一個 myData.action=url.
prototype裡如何實現這一功能呢??

Prototype
Form.request($("formID") ,{ onComplete: callBackFunction });

當然prototype裡也可以類似moo的做法 , 只要讓myData=$("formID").serialize(true) 就可以了.
但是這一個小小的不同,反映出了設計上的差距.

Mootools
moo的Json.Remote類,簡單,但是很實用:

 

 

Java代碼

 

  1. var jSonRemoteRequest = new Json.Remote( url , {onComplete:callBackFunction }).send({name: 'Vickey',gender: 'female' });  

 

	var jSonRemoteRequest = new Json.Remote( url , {onComplete:callBackFunction }).send({name: 'Vickey',gender: 'female' });


這個類和Ajax類的本質區別是,
他提交的是一個序列化後的 json字符串("{name: 'Vickey',gender: 'female' } "),而不是把 json對象轉化成QueryString ("name=Vickey&gender=female");

===========================================
結束語
===========================================

寫這篇文章不是要批評prototype,以我現在的水平還沒那個資格.
只是和mootools對比後, prototype在設計上的不足立刻就顯現了出來.

雖然prototype新版本變化很多,很多我上面提到的一些不足都改正了,而且也加入了很多以前不具備的新的特性.
但是prototype現在的發展停留在:"修補不足,增加功能"的階段,而沒有從設計上進行深層次的重構,所以我不認為他在mootools面前有足夠的底氣.

至於jquery我沒有深入研究過,但是它的設計覺得完全是prototype風格的, 注意,我說的是設計風格,而不是代碼風格.
代碼上他可能寫的更精妙,更有趣,但是設計上依然是prototype風格:薄弱的類機制,靠簡單的extend支撐起整個系統.
JQuery在很多方面很出色,但是歸根結底他和prototype走在一條路上,只是在有些方面他走的更快.

mootools並非完美無缺,但是至少現在他美的地方比prototype更多,缺的地方比prototype更少.

所以,我選擇mootools. 你呢??

不要聽評論,不要看介紹, 只要看看他們的源代碼, 同時動手用他們寫些東西, 你的答案自然會浮現出來.

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved