42 votes

extension profonde (comme jQuery) pour nodeJS

Je me bats avec des copies profondes d'objets dans nodeJS. ma propre étendue est la merde. le trait de soulignement est plat. il y a des variantes d’extension plutôt simples ici sur stackexchange, mais aucune n’est même proche de jQuery.extend (true, {}, obj, obj, obj) .. (la plupart sont en fait terribles et bafouent les avantages du code asnyc.)

D'où ma question: existe-t-il une bonne copie en profondeur pour NodeJS? Est-ce que quelqu'un a porté jQuery?

27voto

Raynos Points 82706

Il a déjà été porté. nœud-étendre

Remarque le projet n'a pas de tests et n'a pas beaucoup de popularité, donc à utiliser à vos propres risques.

Comme mentionné, vous n'aurez probablement pas besoin profond d'exemplaires. Essayez de changer vos structures de données si vous avez seulement besoin peu profondes des copies.

Quelques mois plus tard

J'ai écrit un petit module au lieu de cela, vous recommandons l'utilisation de xtend. Il ne s'agit pas d'une mise en œuvre contenant jQuery bagages ni de bugs, comme le node-mesure.

15voto

jcolebrand Points 11824

Vous voulez jQuery, alors utilisez-le:

 function extend() {
    var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false,
        toString = Object.prototype.toString,
        hasOwn = Object.prototype.hasOwnProperty,
        push = Array.prototype.push,
        slice = Array.prototype.slice,
        trim = String.prototype.trim,
        indexOf = Array.prototype.indexOf,
        class2type = {
          "[object Boolean]": "boolean",
          "[object Number]": "number",
          "[object String]": "string",
          "[object Function]": "function",
          "[object Array]": "array",
          "[object Date]": "date",
          "[object RegExp]": "regexp",
          "[object Object]": "object"
        },
        jQuery = {
          isFunction: function (obj) {
            return jQuery.type(obj) === "function"
          },
          isArray: Array.isArray ||
          function (obj) {
            return jQuery.type(obj) === "array"
          },
          isWindow: function (obj) {
            return obj != null && obj == obj.window
          },
          isNumeric: function (obj) {
            return !isNaN(parseFloat(obj)) && isFinite(obj)
          },
          type: function (obj) {
            return obj == null ? String(obj) : class2type[toString.call(obj)] || "object"
          },
          isPlainObject: function (obj) {
            if (!obj || jQuery.type(obj) !== "object" || obj.nodeType) {
              return false
            }
            try {
              if (obj.constructor && !hasOwn.call(obj, "constructor") && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
                return false
              }
            } catch (e) {
              return false
            }
            var key;
            for (key in obj) {}
            return key === undefined || hasOwn.call(obj, key)
          }
        };
      if (typeof target === "boolean") {
        deep = target;
        target = arguments[1] || {};
        i = 2;
      }
      if (typeof target !== "object" && !jQuery.isFunction(target)) {
        target = {}
      }
      if (length === i) {
        target = this;
        --i;
      }
      for (i; i < length; i++) {
        if ((options = arguments[i]) != null) {
          for (name in options) {
            src = target[name];
            copy = options[name];
            if (target === copy) {
              continue
            }
            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 : {};
              }
              // WARNING: RECURSION
              target[name] = extend(deep, clone, copy);
            } else if (copy !== undefined) {
              target[name] = copy;
            }
          }
        }
      }
      return target;
    }
 

et un petit test pour montrer qu'il fait des copies profondes

 extend(true, 
    {
        "name": "value"
    }, 
    {
        "object": "value",
        "other": "thing",
        "inception": {
            "deeper": "deeper",
            "inception": {
                "deeper": "deeper",
                "inception": {
                    "deeper": "deeper"
                }
            }
        }
    }
)
 

Mais n'oubliez pas de fournir l'attribution: https://github.com/jquery/jquery/blob/master/src/core.js

11voto

Kato Points 12210

Une réponse rapide et sale aux copies en profondeur consiste simplement à tricher avec un peu de JSON. Ce n'est pas le plus performant, mais il fait extrêmement bien le travail.

 function clone(a) {
   return JSON.parse(JSON.stringify(a));
}
 

8voto

thataustin Points 314

Je sais que c’est une vieille question, mais j’aimerais simplement inclure la fusion de lodash dans le mélange comme une bonne solution. Je recommanderais lodash pour les fonctions utilitaires en général :)

1voto

marksyzm Points 1092

Cela fonctionne pour une extension d'objet profonde ... soyez averti qu'il remplace les tableaux plutôt que leurs valeurs, mais que vous pouvez évidemment le mettre à jour comme bon vous semble. Il doit conserver les capacités de dénombrement et toutes les autres tâches que vous souhaitez probablement que cela fasse.

 function extend(dest, from) {
    var props = Object.getOwnPropertyNames(from), destination;

    props.forEach(function (name) {
        if (typeof from[name] === 'object') {
            if (typeof dest[name] !== 'object') {
                dest[name] = {}
            }
            extend(dest[name],from[name]);
        } else {
            destination = Object.getOwnPropertyDescriptor(from, name);
            Object.defineProperty(dest, name, destination);
        }
    });
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X