<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    jasmine214--love

    只有當你的內心總是充滿快樂、美好的愿望和寧靜時,你才能擁有強壯的體魄和明朗、快樂或者寧靜的面容。
    posts - 731, comments - 60, trackbacks - 0, articles - 0

    MooTools vs Prototype 核心源碼比較

    Posted on 2010-07-20 11:44 幻海藍夢 閱讀(465) 評論(0)  編輯  收藏 所屬分類: JSAjax

    原文:http://cssrainbow.cn/articles/resources/595.html

    MooTools是一個簡潔,模塊化,面向對象的JavaScript框架。它能夠幫助你更快,更簡單地編寫可擴展和兼容性強的 JavaScript代碼。

    Mootools跟prototypejs相類似,語法幾乎一樣。

    但它提供的功能要比prototypejs多,而且更強大。 比如增加了動畫特效、拖放操作等等。

    建議大家可以用它來代替prototypejs。

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

    原文作者:小胖兒的大城

    原文鏈接地址:http://www.javaeye.com/topic/122425

    前言

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

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

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

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

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

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

    一. 類機制

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

    1
    2
    3
    4
    5
    6
    														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的幫助下如何去定義這個類:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    														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是實現類機制的核心代碼.

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

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

    Mootools

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

    1
    2
    3
    4
    5
    6
    7
    8
    														var PersonClass =newClass({
    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方式定義.
    也可以使用 如下方式

    1
    2
    3
    4
    5
    6
    7
    PersonClass.implement({
    age:0,
    getName :function(){
    returnthis.name;
    }
    },{...}, .....
    );

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    														var
    														Class
    														=
    														function
    														(properties){
    var klass =function(){
    return(arguments[0]!==null&amp;&amp;this.initialize&amp;&amp; $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 =newthis(null);
    for(var property in properties){
    var pp = proto[property];
    proto[property]=Class.Merge(pp, properties[property]);
    }
    returnnewClass(proto);
    },
    implement:function(){
    for(var i =0, l = arguments.length; i &lt; l; i++)
    $extend(this.prototype, arguments[i]);
    }
    };

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

    二. 繼承機制

    Prototype
    prototype提供的繼承很簡單.

    1
    2
    3
    4
    5
    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)
    他的代碼如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    														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]]; 這句的純在使得下面的代碼寫法成為可能.

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

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

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

    1
    2
    3
    4
    														var MyClassA =newClass();
    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才是我們期待的真正的"類繼承",看一下官方的示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    														var Animal =newClass({
    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的的抽象對象相對更完善一些.

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

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

    四. 關于 $()

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

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

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

    五.關于 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等屬性而已.
    一個div 一個span 一個td… 同樣可以包含input select textarea子元素,同樣可以擁有.action target屬性.
    瀏覽器處理他們的方式可能不同,但是在moo面前,大家完全平等.

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

    七.Ajax

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

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

    1
    2
    3
    4
    5
    6
    7
    														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提交實例:

    1
    2
    3
    4
    5
    6
    7
    														var myAjax =new Ajax(
    url,
    {
    data : myData ,
    onComplete: callBackFunction
    }
    ).request();

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

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

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

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

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

    myAjax.request(yourData);

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

    要用ajax提交一個form 或者一個 div下的所有表單元素,只是改變一下 myData.
    var myData= $("formID");? // var myData= $("divID");
    然后就和普通的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類,簡單,但是很實用:

    1
    2
    3
    4
    5
    6
    														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. 你呢??

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

    主站蜘蛛池模板: 美女视频黄视大全视频免费的| 最新久久免费视频| 国产成人精品曰本亚洲79ren| 免费萌白酱国产一区二区三区| 亚洲人成777在线播放| 免费国产在线观看老王影院| 毛片免费在线观看| 亚洲精品无码少妇30P| 亚洲av伊人久久综合密臀性色| 毛片免费全部播放一级| 中文精品人人永久免费| 久久精品国产亚洲αv忘忧草| 亚洲A∨午夜成人片精品网站 | 免费精品国产自产拍在| 在线播放国产不卡免费视频| 亚洲国产精品久久人人爱| 国产啪亚洲国产精品无码| 啦啦啦高清视频在线观看免费 | 国产免费av片在线看| 99麻豆久久久国产精品免费| 亚洲最大无码中文字幕| 亚洲天堂久久精品| av在线亚洲欧洲日产一区二区| 国国内清清草原免费视频99| 巨胸喷奶水视频www免费视频| 在线亚洲高清揄拍自拍一品区| 亚洲欧洲国产精品香蕉网| 国产青草视频在线观看免费影院| 最近中文字幕高清免费中文字幕mv| 一本一道dvd在线观看免费视频| 日本亚洲免费无线码| 亚洲精品中文字幕乱码影院| 国产综合亚洲专区在线| 国产免费小视频在线观看| 日本免费一区二区在线观看| 日本一区午夜艳熟免费| 一级毛片免费观看不收费| 亚洲国产aⅴ成人精品无吗| 亚洲宅男精品一区在线观看| 亚洲邪恶天堂影院在线观看| 久久被窝电影亚洲爽爽爽|