Maison >interface Web >js tutoriel >Un petit problème avec $.extend_jquery

Un petit problème avec $.extend_jquery

WBOY
WBOYoriginal
2016-05-16 15:54:271140parcourir

J'ai travaillé sur le terminal mobile récemment. Comme je connais jQuery et que Zepto fournit la même API que jQuery, j'ai choisi Zepto comme framework de développement.

Comme il s'agit d'un développement mobile, certaines nouvelles API ES5 sont également utilisées, comme forEach. Voici quelques exemples du code que j'ai écrit :

.
list.forEach(function(v) {
 return !!v;
})

Je pensais naïvement que forEach était comme each de jQuery. Tant que ma valeur de retour était fausse, cela interromprait la boucle. J'ai donc écrit beaucoup de code de traversée comme celui-ci (j'étais vraiment trop paresseux pour l'écrire). chaque parcours). Déclarer les variables)

Après avoir écrit pendant un moment, j'ai soudainement découvert que la fonction de rappel de forEach ne peut pas interrompre la boucle, j'ai donc accroché une fonction sur Array.prototype, puis remplacéAll, parfait.

 Array.prototype.foreach = function(fn) {
  var i = 0, len = this.length;

  for (; i < len; ++i) {

    if (fn(this[i], i) === false) {
     break;
    }
   }
 };

Jusqu'à un jour, je voulais faire un peu d'optimisation Considérant que le json que le client doit sauvegarder est trop volumineux (je ne plaisante pas, le maximum peut être de 20M), stringify prend trop de temps et bloquera le UI, j'utilise donc Worker pour ouvrir un fil de discussion en arrière-plan spécifiquement pour stringifier ce json, similaire à ceci :

Copier le code Le code est le suivant :

addEventListener("message", function(e) {
var data = e.data;
données = JSON.stringify(données);
postMessage(données);
}, faux);

posMesage :

Copier le code Le code est le suivant :

travailleur.postMessage(données)

Mais la console affiche le message d'erreur suivant :

Copier le code Le code est le suivant :

Uncaught DataCloneError : échec de l'exécution de "postMessage" sur "Worker" : un objet n'a pas pu être cloné.

Bon sang, pourquoi je ne peux même pas copier un json ? Alors, j'ai commencé à chercher la raison, et j'ai trouvé ce truc dans mon json :

Oh mon Dieu, qu'est-ce que c'est ? Pourquoi ce foreach est-il entré ? J'ai regardé $.extend(true, {}, obj) dans l'éditeur et je n'ai pas pu m'empêcher de me demander. , ça ne pourrait pas être toi. Tu dois causer des ennuis. J'ai donc vérifié le code source de $.extend :

 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 mon Dieu, ce type cause vraiment des problèmes. C'est bien d'utiliser for...in... pour parcourir le tableau, mais sinon if (source[key] !== undefined) target[key] = source [ clé] Les conditions ici peuvent-elles être plus sérieuses ? Ajouter hasOwnProperty à vérifier ne fera pas perdre beaucoup de temps. Avec des larmes coulant sur mon visage

Après avoir été trompé par Zepto, je suis immédiatement allé me ​​plaindre sur jQuery, en espérant que cela puisse me réconforter, mais de façon inattendue :

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

Ce type est aussi else if ( copy !== undefined ) {target[ name ] = copy;} Dis-le-moi, ma chère mère.

Au final, je n'ai eu d'autre choix que d'en écrire un moi-même.

Résumé : lorsque vous souhaitez utiliser $.extend, n'ajoutez pas facilement vos propriétés et méthodes personnalisées à Array.prototype et Object.prototype, sinon vous devrez peut-être trouver des bugs à l'avenir.

Ce qui précède représente l’intégralité du contenu de cet article, j’espère que vous l’aimerez tous.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn