Ich arbeite seit kurzem am mobilen Endgerät. Da ich mit jQuery vertraut bin und Zepto die gleiche API wie jQuery bereitstellt, habe ich Zepto als Entwicklungsframework ausgewählt.
Da es sich um eine mobile Entwicklung handelt, werden auch einige neue ES5-APIs verwendet, wie zum Beispiel forEach. Hier sind einige Beispiele des Codes, den ich geschrieben habe:
list.forEach(function(v) { return !!v; })
Ich dachte naiv, dass forEach genau wie jQuery ist und die Schleife unterbrochen wird. Also habe ich eine Menge Traversal-Code wie diesen geschrieben (ich war wirklich zu faul, ihn zu schreiben). (jeder Durchlauf). Variablen deklarieren)
Nachdem ich eine Weile geschrieben hatte, stellte ich plötzlich fest, dass die Rückruffunktion von forEach die Schleife nicht unterbrechen kann, also habe ich eine Funktion an Array.prototype gehängt und dann All ersetzt, perfekt.
Array.prototype.foreach = function(fn) { var i = 0, len = this.length; for (; i < len; ++i) { if (fn(this[i], i) === false) { break; } } };
Bis ich eines Tages etwas optimieren wollte, da der JSON, den der Client speichern muss, zu groß ist (ich mache keine Witze, das Maximum kann 20 MB betragen), ist Stringify zu zeitaufwändig und wird das blockieren UI, also verwende ich Worker, um einen Thread im Hintergrund zu öffnen, der speziell diesen JSON in Strings umwandelt, ähnlich wie hier:
posMessage:
Aber die Konsole gibt die folgende Fehlermeldung aus:
Was zum Teufel, warum kann ich nicht einmal einen JSON kopieren? Also habe ich nach dem Grund gesucht und dieses Ding in meinem JSON gefunden:
Oh mein Gott, was zum Teufel ist das? Ich habe mir $.extend(true, {}, obj) im Editor angesehen und musste mich wundern , du könntest es nicht sein. Du musst Ärger verursachen. Also habe ich den Quellcode von $.extend überprüft:
function extend(target, source, deep) { for (key in source) if (deep && (isPlainObject(source[key]) || isArray(source[key]))) { if (isPlainObject(source[key]) && !isPlainObject(target[key])) target[key] = {} if (isArray(source[key]) && !isArray(target[key])) target[key] = [] extend(target[key], source[key], deep) } else if (source[key] !== undefined) target[key] = source[key] } // Copy all but undefined properties from one or more // objects to the `target` object. $.extend = function(target){ var deep, args = slice.call(arguments, 1) if (typeof target == 'boolean') { deep = target target = args.shift() } args.forEach(function(arg){ extend(target, arg, deep) }) return target }
Oh mein Gott, dieser Typ macht wirklich Ärger. Es ist in Ordnung, for...in... zum Durchlaufen des Arrays zu verwenden, aber sonst if (source[key] !== undefiniert) target[key] = source [Schlüssel] Können die Bedingungen hier schwerwiegender sein? Das Hinzufügen von hasOwnProperty zur Überprüfung wird nicht viel Zeit verschwenden. Mit Tränen, die mir übers Gesicht strömen
Nachdem ich von Zepto betrogen wurde, ging ich sofort zu jQuery, um mich zu beschweren, in der Hoffnung, es könnte mich trösten, aber unerwartet:
jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } // extend jQuery itself if only one argument is passed if ( length === i ) { target = this; --i; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; };
Dieser Typ ist auch else if ( copy !== undefiniert ) {target[ name ] = copy;} Sag es mir einfach, meine liebe Mutter.
Am Ende blieb mir nichts anderes übrig, als selbst eines zu schreiben.
Zusammenfassung: Wenn Sie $.extend verwenden möchten, fügen Sie Ihre benutzerdefinierten Eigenschaften und Methoden nicht einfach zu Array.prototype und Object.prototype hinzu, da Sie sonst möglicherweise in Zukunft Fehler finden müssen.
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, er gefällt Ihnen allen.