我正在努力研究nodeJS中对象的深层副本。我自己的延伸是废话。下划线的延伸是持平的。在stackexchange上有相当简单的扩展变体,但是没有一个甚至接近jQuery.extend(true,{},obj,obj,obj).. (大多数实际上都很糟糕,并且搞砸了asnyc代码的好处。)
因此,我的问题是:NodeJS有一个很好的深层副本吗?有人移植过jQuery吗?
答案 0 :(得分:27)
它已被移植。 node-extend
请注意,该项目没有测试且没有太多受欢迎程度,因此请自担风险。
如前所述,您可能不需要深层拷贝。尝试更改您的数据结构,这样您只需要浅拷贝。
我写了一个较小的模块,建议你使用xtend。它没有包含jQuery行李的实现,也没有像node-extend那样的bug。
答案 1 :(得分:14)
你想要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;
}
和一个小测试,以显示它做深拷贝
extend(true,
{
"name": "value"
},
{
"object": "value",
"other": "thing",
"inception": {
"deeper": "deeper",
"inception": {
"deeper": "deeper",
"inception": {
"deeper": "deeper"
}
}
}
}
)
但请记住提供归因:https://github.com/jquery/jquery/blob/master/src/core.js
答案 2 :(得分:11)
对深拷贝的快速而肮脏的回答只是用一点点JSON作弊。它并不是最高效的,但它确实能很好地完成这项任务。
function clone(a) {
return JSON.parse(JSON.stringify(a));
}
答案 3 :(得分:11)
请使用内置的util模块:
var extend = require('util')._extend;
var merged = extend(obj1, obj2);
答案 4 :(得分:8)
我知道这是一个老问题,但我只想把lodash's merge作为一个好的解决方案。我建议lodash一般用于实用程序功能:)
答案 5 :(得分:1)
这适用于深度对象扩展...请注意它替换数组而不是它们的值,但显然可以按照您喜欢的方式更新。它应该保持枚举功能和你可能想要它做的所有其他事情
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);
}
});
}
答案 6 :(得分:1)
在Node.js中,您可以使用Extendify创建一个支持嵌套对象扩展(深度扩展)的_.extend函数,并且它也是不可变的(因此深度克隆)。< / p>
_.extend = extendify({
inPlace: false,
isDeep: true
});
答案 7 :(得分:1)
node.extend做得很深,熟悉jQuery语法
答案 8 :(得分:1)
只需安装扩展。 文档: node extend package 安装:
npm install extend
然后享受它:
extend ( [deep], target, object1, [objectN] )
深是可选的。默认为false。如果切换为true,它将以递归方式合并您的对象。
答案 9 :(得分:0)
Sharped版本称为whet.extend。
我用CoffeeScript重新编写node-extend并添加了travis-ci测试套件,因为我需要在节点中进行深度处理,所以现在就在这里。
是的,我认为在某些情况下它绝对正确地使用深度合并,例如我在配置工作时使用它,当我们需要将默认和用户分支合并在一起时。
答案 10 :(得分:0)
您也可以使用我的扩展插件版本 https://github.com/maxmara/dextend