2010-12-15 9 views
9

aktualisieren Added jsfiddle - siehe unten auf die PostjQuery Unterschied in der Leistung ohne „jeder“

Im Moment habe ich eine Funktion, die alle deaktivierten Felder auf dem Bildschirm reaktiviert. Während es ziemlich schnell läuft (< 1ms nach Firebug-Profiler), bin ich in dem Prozess die Javascript von aufzuräumen alle in meinen Bildschirmen und rechnete diese spezielle Funktion schien ein wenig überflüssig zu sein:

function enableDisabledFields() { 
    $('[disabled]').each(function(i) { 
     $(this).removeAttr('disabled'); 
    }); 
} 

ich unter war der Eindruck, dass diese 3 Zeilen könnte wie folgt ersetzt werden, und ich erwartete, wenn nicht besser als mindestens gleich Leistung.

function enableDisabledFields() { 
    $('[disabled]').removeAttr('disabled'); 
} 

Anscheinend liege ich falsch. Der erste führt viel besser und ich verstehe nicht ganz warum. Selbst das Hinzufügen zusätzlicher Selektoren wie: Eingabe macht keinen Unterschied (und macht es sogar noch schlimmer).

Kann jemand meine Verwirrung klären? Vielen Dank.

Bearbeiten Ich sollte hinzufügen, dass wir eine alte Version von jQuery verwenden - 1.3.1 glaube ich.

Edit2 Hier sind einige Links jsFiddle. Bitte beachten Sie, dass ich Firebugs Profiler (, von dem ich denke, dass es der Fall zu sein scheint,) falsch interpretiere.

Option 1: http://jsfiddle.net/kcut7/

Option 2: http://jsfiddle.net/ZgZpU/

+1

Gibt es eine Chance, dass Sie ein paar Seiten auf http://jsfiddle.net/ einrichten können? –

+0

Wenn Sie "viel besser" sagen, welche Zahlen erhalten Sie für beide? – Ben

+0

beide macht das gleiche richtig ?? – kobe

Antwort

4

In jQuery 1.3.1 dies auf die aktuellen Versionen etwas anders implementiert:

v1.4.4

removeAttr: function(name, fn) { 
    return this.each(function(){ 
     jQuery.attr(this, name, ""); 
     if (this.nodeType === 1) { 
      this.removeAttribute(name); 
     } 
    }); 
}, 

v1.3.1

jQuery.each({ 
    removeAttr: function(name) { 
     jQuery.attr(this, name, ""); 
     if (this.nodeType == 1) 
      this.removeAttribute(name); 
    } 
}, function(name, fn){ 
    jQuery.fn[ name ] = function(){ 
     return this.each(fn, arguments); 
    }; 
}); 

Die Funktionalität ist mehr oder weniger die gleichen, beide verwenden .each() in allen Fällen um die Liste zu verarbeiten. Die Definition jeder hat sich nicht grundlegend überhaupt geändert:

// args is for internal usage only 
each: function(object, callback, args) { 
    var name, i = 0, 
     length = object.length, 
     isObj = length === undefined || jQuery.isFunction(object); 

    if (args) { 
     if (isObj) { 
      for (name in object) { 
       if (callback.apply(object[ name ], args) === false) { 
        break; 
       } 
      } 
     } else { 
      for (; i < length;) { 
       if (callback.apply(object[ i++ ], args) === false) { 
        break; 
       } 
      } 
     } 

    // A special, fast, case for the most common use of each 
    } else { 
     if (isObj) { 
      for (name in object) { 
       if (callback.call(object[ name ], name, object[ name ]) === false) { 
        break; 
       } 
      } 
     } else { 
      for (var value = object[0]; 
       i < length && callback.call(value, i, value) !== false; value = object[++i]) {} 
     } 
    } 

    return object; 
}, 

Also nur eine Schleife mit .call() viel.

Ich denke, die einzige Erklärung, wie zu einer Geschwindigkeitssteigerung mit einer zusätzlichen äußerte .each() Schleife die Datenstruktur Größe sein würde, dass viel auf ein einziges Element reduziert, bevor du durch viele Schichten von Anrufen weitergegeben werden, was wahrscheinlich ist Erstellen von lokalen Datenkopien auf jeder Ebene. Wenn Sie die gesamte Liste übergeben, um mit viel mehr Overhead zu arbeiten, müssten Sie vielleicht die Heap-Nutzung profilieren, um sie zu ermitteln.

+1

Pro-ness Alert! : D – Fred