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级事件回调函数调用方式调用不会丢失值。

    汗啊。。。。。。刚发现ie中使用2级事件回调函数加载方式竟然也是自动传入window.event的。。。。丢脸啊丢脸啊,更新上述总结:
    对传入有值的arguments,修改或直接压入封包,调用封包函数不会丢失值;对无值的arguments,修改添加值后压入封包,调用封包函数值丢失!

你可能感兴趣的:(IE)