deep extend (like jQuery's) for nodeJS

后端 未结 11 876
情歌与酒
情歌与酒 2020-12-13 17:27

I am struggling with deep copies of objects in nodeJS. my own extend is crap. underscore\'s extend is flat. there are rather simple extend variants here on stackexchange, bu

11条回答
  •  星月不相逢
    2020-12-13 18:20

    You want jQuery's, so just use it:

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

    and a small test to show that it does deep copies

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

    But remember to provide attribution: https://github.com/jquery/jquery/blob/master/src/core.js

提交回复
热议问题