将函数应用于类或通过each()之间的区别

时间:2013-06-18 04:22:26

标签: jquery performance class each

将函数应用于具有类的所有元素或通过每个函数执行此操作会有什么不同吗? 这可能是一个愚蠢的问题,但在我的情况下,可以用两种不同的方式执行代码,所以我想知道它们之间是否有任何性能差异:

$('.my_class').hide(); //for example

$('.my_class').each(function(){
    $(this).hide();
});

2 个答案:

答案 0 :(得分:4)

这些效果相同,但第一种方式更优越,因为它更清洁。您的代码目标应该是:

  1. 正确
  2. 清除
  3. 简明
  4. 快速
  5. 一般情况下,在发现某种问题之前,不要担心速度。有时我们可能会先考虑前三个考虑因素之一以获得速度,但是,在您知道存在性能问题之前这样做会违反整个互联网上的“过早优化”警告。 让你的代码简洁易懂,比挤出最后一秒飞秒的性能更重要

    如果您检查the source code for jQuery 1.10.1,您将在幕后看到,一次调用hide()一个必须更慢,因为而不是隐藏一个函数中的所有元素调用,都在它自己的内部循环中,现在有一个外部循环为每个元素调用一次函数。

    比较一些伪代码:

    /*elements.hide()*/
    
    function hide() {
       for (i = 0; i < l; i += 1) {
          // hide them
       }
    }
    
    /*elements.each(function() {element.hide();}*/
    
    function each() {
       for (i = 0; i < l; i += 1) {
          element[i].hide() { // only one element each time, now
             for (i = 0; i < l; i += 1) {
                //hide item
             }
          }
       }
    }
    

    通过使用第二种方法,你已经采用了一种有效的函数,它本身可以处理许多元素,并强制它运行多次,每次只处理一个元素。

    一般来说,您应该选择最干净的代码。使用jQuery的最大原因之一就是获得干净的代码,这样你就不会有所有讨厌的混乱!任何人都可以编写计算机可以理解的代码,但好的程序员编写 human 可以理解的代码。你的代码很容易理解 - 明天你或明年的其他人,或者甚至五年后的你。不要增加复杂性。

    作为参考,这里是hide的函数定义(这是从短存根调用的):

    function showHide( elements, show ) {
       var display, elem, hidden,
          values = [],
          index = 0,
          length = elements.length;
    
       for ( ; index < length; index++ ) {
          elem = elements[ index ];
          if ( !elem.style ) {
             continue;
          }
    
          values[ index ] = jQuery._data( elem, "olddisplay" );
          display = elem.style.display;
          if ( show ) {
             // Reset the inline display of this element to learn if it is
             // being hidden by cascaded rules or not
             if ( !values[ index ] && display === "none" ) {
                elem.style.display = "";
             }
    
             // Set elements which have been overridden with display: none
             // in a stylesheet to whatever the default browser style is
             // for such an element
             if ( elem.style.display === "" && isHidden( elem ) ) {
                values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
             }
          } else {
    
             if ( !values[ index ] ) {
                hidden = isHidden( elem );
    
                if ( display && display !== "none" || !hidden ) {
                   jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
                }
             }
          }
       }
    
       // Set the display of most of the elements in a second loop
       // to avoid the constant reflow
       for ( index = 0; index < length; index++ ) {
          elem = elements[ index ];
          if ( !elem.style ) {
             continue;
          }
          if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
             elem.style.display = show ? values[ index ] || "" : "none";
          }
       }
    
       return elements;
    }
    

    each

    each: function( obj, callback, args ) {
       var value,
          i = 0,
          length = obj.length,
          isArray = isArraylike( obj );
    
       if ( args ) {
          if ( isArray ) {
             for ( ; i < length; i++ ) {
                value = callback.apply( obj[ i ], args );
    
                if ( value === false ) {
                   break;
                }
             }
          } else {
             for ( i in obj ) {
                value = callback.apply( obj[ i ], args );
    
                if ( value === false ) {
                   break;
                }
             }
          }
    
       // A special, fast, case for the most common use of each
       } else {
          if ( isArray ) {
             for ( ; i < length; i++ ) {
                value = callback.call( obj[ i ], i, obj[ i ] );
    
                if ( value === false ) {
                   break;
                }
             }
          } else {
             for ( i in obj ) {
                value = callback.call( obj[ i ], i, obj[ i ] );
    
                if ( value === false ) {
                   break;
                }
             }
          }
       }
    
       return obj;
    },
    

答案 1 :(得分:1)

直接电话$('.my_class').hide();似乎更快

请参阅this test

此外,第一种方法更清晰易懂