nodeJS的深度扩展(如jQuery)

its*_*ony 42 jquery deep-copy extend node.js

我正在努力使用nodeJS中的对象的深层副本.我自己的延伸是废话.下划线的延伸是持平的.在stackexchange上有相当简单的扩展变体,但是没有一个甚至接近jQuery.extend(true,{},obj,obj,obj)..(大多数实际上都很糟糕并且搞砸了asnyc代码的好处.)

因此,我的问题是:NodeJS有一个很好的深层副本吗?有人移植过jQuery吗?

Ray*_*nos 27

它已被移植.节点延伸

请注意,该项目没有测试,也没有太大的受欢迎程度,因此使用风险由您自行承担.

如上所述,您可能不需要深层复制.尝试更改您的数据结构,这样您只需要浅拷贝.

几个月后

我写了一个较小的模块,建议你使用xtend.它没有包含jQuery行李的实现,也没有像node-extend那样的bug.

  • 在尝试了一些我为[node.extend](https://github.com/dreamerslab/node.extend)选择的模块后,因为它正确地使用原型克隆了对象.xtend和node-extend(带有' - ')都不能这样做. (5认同)
  • 对不起,你怎么能说这只是因为*你*从未使用过深刻的副本,他们是坏的,应该在所有情况下都避免使用? (4认同)
  • @itsatony xtend只按设计进行浅扩展 (3认同)
  • @Raynos你应该告诉你是你推广的图书馆的作者. (3认同)
  • 即使你是100%公正的,你也必须按照[此处](http://meta.stackoverflow.com/help/behavior)"披露您的联盟" (2认同)

jco*_*and 15

你想要jQuery,所以只需使用它:

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;
    }
Run Code Online (Sandbox Code Playgroud)

和一个小测试,以表明它做了深层复制

extend(true, 
    {
        "name": "value"
    }, 
    {
        "object": "value",
        "other": "thing",
        "inception": {
            "deeper": "deeper",
            "inception": {
                "deeper": "deeper",
                "inception": {
                    "deeper": "deeper"
                }
            }
        }
    }
)
Run Code Online (Sandbox Code Playgroud)

但请记住提供归因:https://github.com/jquery/jquery/blob/master/src/core.js


Kat*_*ato 11

深度拷贝的快速而肮脏的答案只是用一点点JSON作弊.它不是最高效的,但它确实做得非常好.

function clone(a) {
   return JSON.parse(JSON.stringify(a));
}
Run Code Online (Sandbox Code Playgroud)

  • 如果它只是一个面向数据的对象,那就太好了,但是如果你的对象来自一个特定的构造函数,并且它自己的方法和继承都会丢失,那么你就不想这样做了. (3认同)
  • @marksyzm这绝对是真的; 它只对复制简单的值对象有用; 它对于日期,函数以及在某些情况下构造的对象都是失败的. (2认同)
  • 不,除了功能之外,它并不适用于所有功能.在您之前直接引用评论:"它仅对复制简单的值对象有用; 它对于日期,函数以及在某些情况下构造的对象都是失败的 (2认同)

小智 11

请使用内置的util模块:

var extend = require('util')._extend;

var merged = extend(obj1, obj2);
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个记录的方法,并以下划线为前缀,这通常意味着它不是为了公共消费. (12认同)
  • `util._extend`也不深. (3认同)

tha*_*tin 8

我知道这是一个老问题,但我只想将lodash的合并作为一个很好的解决方案.我推荐一般的实用功能lodash :)