Heim > Web-Frontend > js-Tutorial > Hauptteil

Ein kleines Problem mit $.extend_jquery

WBOY
Freigeben: 2016-05-16 15:54:27
Original
1114 Leute haben es durchsucht

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;
})

Nach dem Login kopieren

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;
    }
   }
 };

Nach dem Login kopieren

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:

Code kopieren Der Code lautet wie folgt:

addEventListener("message", function(e) {
var data = e.data;
data = JSON.stringify(data);
postMessage(data);
}, false);

posMessage:

Code kopieren Der Code lautet wie folgt:

worker.postMessage(data)

Aber die Konsole gibt die folgende Fehlermeldung aus:

Code kopieren Der Code lautet wie folgt:

Nicht erfasster DataCloneError: „PostMessage“ konnte nicht auf „Worker“ ausgeführt werden: Ein Objekt konnte nicht geklont werden.

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
 }

Nach dem Login kopieren

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) &#63; src : [];

          } else {
            clone = src && jQuery.isPlainObject(src) &#63; 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;
};

Nach dem Login kopieren

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.

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage