jQuery的click()函数如何比addEventListener()快得多?

时间:2012-11-15 23:18:53

标签: javascript javascript-events event-handling jquery

我确定我们都见过site for vanilla-js(最快的JavaScript框架); D和我只是很好奇,确切地说,在添加活动时,纯JavaScript比jQuery快多少点击的处理程序。所以我前往jsPerf测试它,我是quite surprised by the results

jQuery超过纯粹的JavaScript超过 2500%

我的测试代码:

//jQuery
$('#test').click(function(){
  console.log('hi');
});

//Plain JavaScript
document.getElementById('test').addEventListener('click', function(){
  console.log('hi');
});

我无法理解这是怎么发生的,因为似乎最终jQuery最终必须使用与普通JavaScript一样的完全相同的功能。 有人可以解释为什么会发生这种情况吗?

2 个答案:

答案 0 :(得分:10)

正如您在jQuery.event.add的这个片段中看到的,它只创建了一次eventHandle。
查看更多:http://james.padolsey.com/jquery/#v=1.7.2&fn=jQuery.event.add

 // Init the element's event structure and main handler, if this is the first
events = elemData.events;
if (!events) {
    elemData.events = events = {};
}
eventHandle = elemData.handle;
if (!eventHandle) {
    elemData.handle = eventHandle = function (e) {
        // Discard the second event of a jQuery.event.trigger() and
        // when an event is called after a page has unloaded
        return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply(eventHandle.elem, arguments) : undefined;
    };
    // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
    eventHandle.elem = elem;
}

这里我们有addEventListener:

    // Init the event handler queue if we're the first
    handlers = events[type];
    if (!handlers) {
        handlers = events[type] = [];
        handlers.delegateCount = 0;

        // Only use addEventListener/attachEvent if the special events handler returns false
        if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
            // Bind the global event handler to the element
            if (elem.addEventListener) {
                elem.addEventListener(type, eventHandle, false);

            } else if (elem.attachEvent) {
                elem.attachEvent("on" + type, eventHandle);
            }
        }
    }

答案 1 :(得分:8)

我认为这是因为内部jQuery实际上只需要为其自己的内部处理程序调用{​​{1}} 一次。设置完成后,只需将回调添加到简单列表中即可。因此,对addEventListener()的大多数调用只会做一些簿记和.click()(或类似的事情)。