Posted on 2007-05-18 03:24
sunbaby 閱讀(467)
評論(0) 編輯 收藏 所屬分類:
其它
http://hi.baidu.com/zys0202/blog/item/fec7945294de330e0df3e349.html
javascript apply()方法通過一個例子說明apply()的用法://針對各種瀏覽器建立一個http request的對象function getHttpRequest(){ http_request = null; if (window.XMLHttpRequest) { http_request = new XMLHttpRequest(); } else if (window.ActiveXObject) { http_request = new ActiveXObject("Microsoft.XMLHTTP"); } return http_request;}var ajax_request;functiong getPerson(){ ajax_request = getHttpRequest(); //建立一個http request ajax_request.onstatechange = handleResponse; //指定回調函數 ajax_request.open("GET", "http://myhost.com/sample.xml", null); ajax_request.send();} function handleResponse(){ if(ajax_request.readyState != 4) return; if(ajax_request.status == 200){ var xml = ajax_request.responseXML; /* 對獲得的xml的處理 */ }} 調用的時候可以直接在頁面里調用getPerson(); 這個函數會建立一個httpRequest對象,然后發送請求,在請求返回的時候會自動調用handleResponse函數來完成操作。在簡單的環境上,上述代碼會工作得很好,但是如果在一個頁面中要執行多次這種操作就比較麻煩了,需要寫多個函數,看一下上面的定義:var ajax_request; 表示這是個全局變量,多次請求的時候每個請求都要用到這個對象,ajax又是異步的,無法事先確定哪個請求先返回。 如果把ajax_request作為函數內的局部變量呢?那樣如果在handleResponse里能看到ajax_request對象就可以解決這個問題了??梢钥紤]把ajax_request作為一個參數傳遞給handleResponse,現在的問題是,對handleResponse的調用是自動的,怎么能在參數列表中添加這個參數呢?我們想到了this變量,在javascript中,所有的東西都是對象,this表示當前對象,在函數中this就表示當前的函數。javascript提供了一種可以改變this的方法——apply()。javascript對apply的解釋是:使用指定對象替換當前對象并調用函數。比如: function test_apply(){ alert(this);}test_apply.apply(document, []); 就表示調用函數test_apply,并用document對象來替換test_apply中的this。 回到剛剛的問題,為了修改當前對象,需要在指定handleResponse的時候就修改this對象。ajax_request.onstatechange是一個函數的句柄,只要我把一個函數的句柄賦值給它就可以了,同時函數也是一種對象,Function對象,因此我們為函數對象添加一個方法:Function.prototype.setThis(){ var curr_function = this; var to_this_object = arguments[0]; return function(){ currFunc.apply(to_this_object, []); };} 下面,修改getPerson為:functiong getPerson(){ var tmp_request = getHttpRequest(); //建立一個http request tmp_request.onstatechange = handleResponse.setThis(tmp_request); //指定回調函數 tmp_request.open("GET", "http://myhost.com/sample.xml", null); tmp_request.send();} 修改handleResponse為:function handleResponse(){ if(this.readyState != 4) return; if(this.status == 200){ var xml = this.responseXML; /* 對獲得的xml的處理 */ }}即可。具體的變化就在于tmp_request.onstatechange = handleResponse.setThis(tmp_request); 因為handleResponse是一個函數,因此它具有Function新添加的方法setThis,下面來看setThis方法:var curr_function = this; //獲得當前的函數本身var to_this_object = arguments[0]; //獲得要指定的新的this對象return function(){ currFunc.apply(to_this_object, []); }; 這里的返回值是一個函數,即當tmp_request的onstatechange事件的時候會觸發這個函數,該函數中只有一句currFunc.apply(to_this_object, []);即用to_this_object替換當前對象并調用currFunc,在這里currFunc即代表了handleResponse,因此調用handleResponse,因為已經修改了其this對象,因此在handleResponse中用this即代表了tmp_request對象。用這種方法可以減化代碼,并使代碼更具可重用性。源文地址:http://www.cublog.cn/opera/showart.php?blogid=21787&id=140549附注:應用某一對象的一個方法,用另一個對象替換當前對象。apply([thisObj[,argArray]])參數thisObj可選項。將被用作當前對象的對象。argArray可選項。將被傳遞給該函數的參數數組。說明如果 argArray 不是一個有效的數組或者不是 arguments 對象,那么將導致一個 TypeError。如果沒有提供 argArray 和 thisObj 任何一個參數,那么 Global 對象將被用作 thisObj, 并且無法被傳遞任何參數。