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

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

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

    posts - 495,comments - 227,trackbacks - 0
    1、關(guān)于javascript的apply和call函數(shù)

    prototype.js中用了大量的apply和call函數(shù),不注意會造成理解偏差。
    官方解釋:應(yīng)用某一對象的一個方法,用另一個對象替換當(dāng)前對象。
    apply與call的區(qū)別是第二個參數(shù)不同。apply是? 數(shù)組或者arguments 對象。而call是逗號隔開的任何類型。

    apply,call方法最讓人混淆的地方也是apply,call的特色。但最好不要濫用。
    能改變調(diào)用函數(shù)的對象。如下例,函數(shù)中用到this關(guān)鍵字,這時候this代表的是apply,call函數(shù)的第一個參數(shù)。

    <script src="prototype1.3.1.js"></script>
    <input type="text" id="myText"? value="input text">
    <script>
    ?? function Obj(){
    ?????? this.value="對象!";
    ?? }
    ?? var value="global 變量";
    ?? function Fun1(){
    ?????? alert(this.value);
    ?? }
    ?? window.Fun1();
    ?? Fun1.apply(window);
    ?? Fun1.apply($('myText'));
    ?? Fun1.apply(new Obj());
    </script>

    2、關(guān)于閉包
    prototype.js在Class.create,bind等中用到j(luò)avascript的閉包特色。但整體上prototype.js對于強大的閉包特性用的不多。大家可以參閱我翻譯的篇文章了解閉包
    3、讓我比較反感的兩個方法
    (1)
    var Class = {
    ? create: function() {
    ??? return function() {
    ????? this.initialize.apply(this, arguments);
    ??? }
    ? }
    }
    很討厭用別的語言的風(fēng)格來寫javascript。用這個方法構(gòu)造自定義類? 并沒有覺得有多方便,減少代碼行數(shù),只會讓人難理解,多定義一個initialize方法。
    其實討厭這條有些牽強,不過修改Object的原型對象就有點過分了。
    (2)Object.prototype.extend
    ? 先不過你取個extend的名字會讓熟悉java的人引起的歧義。修改Object的prototype就說不過去了。不知道作者是怎么考慮的。當(dāng)你for in循環(huán)對象是,麻煩就來了。可能有人會問你for in干嗎。 我一個項目中既用了DWR,也用了prototype.js,dwr返回的javascript對象都多了個exetend屬性,還得特殊處理。
    ? 以前我比較過dojo和prototype.js中繼承的實現(xiàn),現(xiàn)在我明白個道理。對于javascript這種沒有靜態(tài)類型檢查,語法寬松的語言來講,如果你選擇了某個js類庫,那你也必須適應(yīng)作者寫javascript的風(fēng)格。prototype.js的作者對extend的使用爐火純青,如果我們不當(dāng)它只是個屬性拷貝的函數(shù)的話,多讀讀prototype.js的代碼是好的。
    4、關(guān)于函數(shù)的綁定
    ? 類庫提供了Function.prototype.bind? Function.prototype.bindAsEventListener兩個方法。首先我們從概念上解釋一個這兩個方法。
    任何一個函數(shù)都可以調(diào)用這兩個方法;參數(shù)的是javascript對象或網(wǎng)頁上元素對象;返回類型是個函數(shù)對象。
    本來我就是個函數(shù),返回還是函數(shù),到這兩個函數(shù)有什么不同呢。看實現(xiàn)代碼,關(guān)鍵還是apply\call函數(shù)的代碼。其實這里只是轉(zhuǎn)化了一下方法調(diào)用的對象。

    <script src="prototype1.3.1.js"></script>
    <input type=checkbox id=myChk name="asf" value=1> Test
    <script>
    ??? var CheckboxWatcher = Class.create();
    ??? CheckboxWatcher.prototype = {
    ?????? initialize: function(chkBox, message) {
    ??????????? this.chkBox = $(chkBox);
    ??????????? this.message = message;
    ??????????? this.chkBox.onclick = this.showMessage.bindAsEventListener(this);
    ?????? },
    ?????? showMessage: function(evt) {
    ????????? alert(this.message + ' (' + evt.type + ')');
    ?????? }
    ??? };
    new CheckboxWatcher('myChk','message!!!!');
    //$('myChk').onclick=function(){};
    </script>
    這是 https://compdoc2cn.dev.java.net/ 上舉的例子,個人感覺沒什么意思,反而讓我對bind,bindAsEventListener有些反感。(javascript就是這樣,明明大家都知道的語法,但寫出來的代碼差別確很大)
    看下面代碼:

    <script src="prototype1.3.1.js"></script>
    <input type=checkbox id=myChk name="chk" value=1> Test
    <script>
    function Class(){
    ??? this.name="class";
    }
    Class.prototype.getName=function(){
    ??? alert(this.name);
    }
    var obj=new Class();
    //$('myChk').onclick=obj.getName;
    $('myChk').onclick=obj.getName.bind(obj);
    //$('myChk').onclick=obj.getName.bind($('myChk'));
    </script>

    從上面代碼可以看出bind/bindAsEventListener只是包裝了一下apply/call方法,改變方法的調(diào)用對象。如例子,你可以把obj.getName方法轉(zhuǎn)化成任何對象調(diào)用,并且把方法讓表單元素觸發(fā)。(bind和bindAsEventListener之間只是返回函數(shù)的參數(shù)不同)
    這兩個方法也可以用在對象之間的方法重用,實現(xiàn)類似繼承方法的概念。看以下代碼,其實是比較無聊的。

    <script src="prototype1.3.1.js"></script>
    <script>
    function Class1(name){
    ??? this.name=name;
    }
    Class1.prototype.getName=function(){
    ??? alert(this.name);
    }
    function Class2(name){
    ??? this.name=name;
      this.getName=Class1.prototype.getName.bind(this);
    }
    var obj1=new Class2("yql");
    obj1.getName();
    var obj2=new Object();
    obj2.name="zkj";
    obj2.fun=Class1.prototype.getName.bind(obj2);
    obj2.fun();
    </script>


    我從來沒讀過prototype.js的擴展項目代碼,也不知道bind..的最佳實踐,一起挖掘吧。但你絕對不要把bind/bindAsEventListener從綁定的詞義上來理解,可能會讓你更加迷惑。從apply/call理解本質(zhì)。應(yīng)用某一對象的一個方法,用另一個對象替換當(dāng)前對象。

    5、關(guān)于事件的注冊

    <script src="prototype1.3.1.js"></script>
    <input type=checkbox id=myChk name="chk" value=1> Test
    <script>
    Event.observe(myChk, 'click', showMessage, false);
    //$('myChk').onclick=showMessage;
    //$('myChk').onclick=showMessage.bind();
    $('myChk').onclick=showMessage.bind($('myChk'));
    function showMessage() {
    ????? alert(this.value);
    }
    </script>

    執(zhí)行上面代碼,你就能明白Event.observe與bind/bindAsEventListener之間的區(qū)別:
    (1) 顯然Event.observe有限制,只能處理簡單的函數(shù),并函數(shù)中不能有this之類的東西。
    (2)Event.observe內(nèi)部用到addEventListener/attachEvent。能把多個函數(shù)加到一個觸發(fā)事件(window.onload)。bind是覆蓋。

    6、關(guān)于事件監(jiān)聽最佳實踐
    很顯然prototype.js提供的事件注冊方法不是很完善。那看看dojo的時間注冊吧(中文版),更加復(fù)雜,估計很多人像我一樣,對于dojo暫時持觀望態(tài)度。
    如果你看過的前篇關(guān)于閉包的介紹,可能見過以下代碼。
    看以下代碼前我想表述一個觀點,任何網(wǎng)頁中元素,瀏覽器都會為你創(chuàng)建一個對象()。(我覺得)這些對象與你建立javascript對象區(qū)別是它們有事件監(jiān)聽,會響應(yīng)鼠標(biāo)鍵盤的事件。如果你用了以下代碼,那么把事件監(jiān)聽代碼很好的轉(zhuǎn)化到你的javascript代碼中。

    function associateObjWithEvent(obj, methodName){
    ??? return (function(e){
    ??????? e = e||window.event;
    ??????? return obj[methodName](e, this);
    ??? });
    }
    function DhtmlObject(elementId){
    ??? var el = getElementWithId(elementId);
    ??? if(el){
    ??????? el.onclick = associateObjWithEvent(this, "doOnClick");
    ??????? el.onmouseover = associateObjWithEvent(this, "doMouseOver");
    ??????? el.onmouseout = associateObjWithEvent(this, "doMouseOut");
    ??? }
    }
    DhtmlObject.prototype.doOnClick = function(event, element){
    ??? ... // doOnClick method body.
    }
    DhtmlObject.prototype.doMouseOver = function(event, element){
    ??? ... // doMouseOver method body.
    }
    DhtmlObject.prototype.doMouseOut = function(event, element){
    ??? ... // doMouseOut method body.
    }

    posted on 2006-12-27 10:11 SIMONE 閱讀(502) 評論(0)  編輯  收藏 所屬分類: JavaScript
    主站蜘蛛池模板: 免费无码一区二区三区蜜桃大| 亚洲国产精品无码久久98| 四虎影视在线永久免费看黄| 99在线观看免费视频| 国产97视频人人做人人爱免费| 亚洲日韩精品无码AV海量| 97久久精品亚洲中文字幕无码| 亚洲精品国自产拍在线观看| 永久免费bbbbbb视频| 全免费毛片在线播放| 免费无码又爽又刺激高潮视频| 中文字幕不卡免费视频| 美女裸体无遮挡免费视频网站| 亚洲欧美日韩国产成人| 亚洲毛片基地4455ww| 亚洲国产成人在线视频| 亚洲天堂男人天堂| 久久91亚洲精品中文字幕| 亚洲日韩精品一区二区三区无码 | 午夜亚洲AV日韩AV无码大全| 亚洲午夜日韩高清一区| 免费在线观看黄网| 免费a级毛片无码av| 国产午夜免费秋霞影院| 国产成人在线免费观看| 成人免费无码精品国产电影| 午夜一区二区免费视频| 免费看AV毛片一区二区三区| 欧美好看的免费电影在线观看| 99在线精品视频观看免费| 亚洲免费观看网站| 97热久久免费频精品99| 在线观看免费人成视频| 国产精品视频免费一区二区| 成人免费无码大片a毛片软件| 黄色成人网站免费无码av| 好吊妞788免费视频播放| 在线播放高清国语自产拍免费 | 亚洲精品伊人久久久久| 亚洲一卡2卡3卡4卡5卡6卡| 亚洲日韩国产二区无码|