备忘:递归callee.caller导致死循环

今天网友 Baobao包子 反映QWrap里的QW.EventH.getEvent有可能会产生死循环。
代码如下:

        /** 
         * 获得event对象
         * @method    getEvent
         * @param    {event}        event    (Optional)event对象 默认为调用位置所在宿主的event
         * @param    {element}    element (Optional)任意element对象 element对象所在宿主的event
         * @return    {event}        event对象
         */
        getEvent: function(event, element) {
            if (event) {
                return event;
            } else if (element) {
                if (element.document) {return element.document.parentWindow.event; }
                if (element.parentWindow) {return element.parentWindow.event; }
            }

            if (window.event) {
                return window.event;
            } else {
                var f = arguments.callee;
                do {
                    if (/Event/.test(f.arguments[0])) {return f.arguments[0]; }
                } while (f = f.caller);
            }
        },

 

网友 集鹄 也曾在2011-12-07以一个例子来说过这个死循环的问题:

var getEvent_Count = 0;

function getEvent(e) {
    e = e || window.event;

    if (!e) {
        var c = arguments.callee.caller;
        while (c) {
            if (getEvent_Count++ > 1000) {
                alert('死循环了!');
                return;
            }
            e = c.arguments[0];
            if (e && typeof (e.altKey) == "boolean") { // duck typing
                break;
            }
            c = c.caller;
            e = null;
        }
    }

    return e;
}


function test(n) {
    return n ? test(n - 1) : getEvent();
}

test(2);


造成死循环的原因:caller链中有时会有闭环。例如:一个function的caller有可能等于本身。

 

另:QW.EventH.getEvent 方法并不直接对业务编码的同学开放,目前还没有人踩坑,暂无必要更改实现方法。

 

posted on 2012-06-01 16:38 JKisJK 阅读(...) 评论(...) 编辑 收藏

导航

公告