js中arguments的用法

今天更新了事件監聽類,沒想到竟然搞出了一個奇怪的問題,着實讓我想了好久也沒想的太明白。。。 問題是這樣的: 我有個名爲createAdapter的類,它的作用是兼容IE,FRIEFOX的監聽事件回調函數的參數傳入,今天稍微改了下該類的代碼,按邏輯來說應該事沒有什麼問題,但卻出現的傳入參數丟失的問題!
原代碼:

createAdapter:function(Dt,UT)
{
return function(Q)
{
if(!Q)
{
Q=window.event;
};
if(Q&&!Q.target)
{
Q.target=Q.srcElement;
};
UT.call(Dt,Q);
};
}


新代碼:

getWindowEvent : function(ca)
{
if(!ca)
{
ca=[];
};
if(!ca[0])
{
ca[0]=LLEvent.getObjWin().event;
};
if(ca[0]&&!ca[0].target&&ca[0].srcElement)
{
ca[0].target=ca[0].srcElement
};
//var la=document.getElementById('debugInfo');
//var lb=la.innerText;
//lb+=ca[0].type+':'+ca[0].srcElement+';';
//la.innerText=lb;
return ca;
},

createAdapter : function(ca,cb)
{
return function()
{
return cb.apply(ca,LLEvent.getWindowEvent(arguments));
};
},

調用測試代碼:

m.onselectstart = LLEvent.testCreateAdapter(u,function(Q){alert(Q);});

使用新createAdapter代碼後出現Q爲undefined錯誤,仔細對比新舊代碼,邏輯上無差別,只是在實現上原代碼壓入封包的參數是創建的一個局部變量,而新代碼是對傳入的arguments參數組加以修改實現。因此初步判斷是使用arguments參數組導致的原因。於是將 getWindowEvent 與 createAdapter代碼合併成一個函數,在兩塊代碼中加入alert檢測參數壓入封包時是否有值,經測試發現壓入封包前有值,封包函數內調用時值丟失。基本確定是因爲arguments的時效性導致的問題。
確定問題所在後,就需要考慮解決方法了,最簡單的就是換回原函數,使用arguments的是爲了實現帶參數的事件回調函數處理,所以最好是在使用arguments的情況下解決問題。於是對新createAdapter進行完全測試發現:
測試代碼1:

function leiliangtest(Q)
{
alert('leiliangtest-->'+Q);
}
var la=LLEvent.testCreateAdapter(window,leiliangtest);
la('leiliang');

測試代碼alert出了我傳入的‘leiliang’字符串
測試代碼2:

m.attachEvent('onselectstart',function(Q){alert(Q);}

測試代碼alert出了我需要的window.event對象

總結上述,使用arguments做封包時要注意時效性,對傳入有值的arguments,修改或直接壓入封包,以普通函數方式調用不會丟失值;對不傳入值,修改添加值後壓入封包,以普通函數方式調用會丟失值,若以2級事件回調函數調用方式調用不會丟失值。
[color=red]
汗啊。。。。。。剛發現ie中使用2級事件回調函數加載方式竟然也是自動傳入window.event的。。。。丟臉啊丟臉啊,更新上述總結:
對傳入有值的arguments,修改或直接壓入封包,調用封包函數不會丟失值;對無值的arguments,修改添加值後壓入封包,調用封包函數值丟失!
[/color]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章