nodeJS 的深度扩展(如 jQuery 的)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9399365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
deep extend (like jQuery's) for nodeJS
提问by itsatony
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, but none are even close to jQuery.extend(true, {}, obj, obj, obj) .. (most are actually terrible and screw up the benefits of asnyc code.)
我正在努力处理 nodeJS 中对象的深层副本。我自己的扩展是废话。下划线的扩展是平坦的。stackexchange 上有相当简单的扩展变体,但没有一个甚至接近 jQuery.extend(true, {}, obj, obj, obj) ..(大多数实际上很糟糕并且搞砸了 asnyc 代码的好处。)
hence, my question: is there a good deep copy for NodeJS? Has anybody ported jQuery's ?
因此,我的问题是:NodeJS 有没有很好的深拷贝?有没有人移植 jQuery 的?
采纳答案by jcolebrand
You want jQuery's, so just use it:
你想要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;
}
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
但记得提供署名:https: //github.com/jquery/jquery/blob/master/src/core.js
回答by Raynos
It's already been ported. node-extend
它已经被移植了。节点扩展
Note the project doesn't have tests and doesn't have much popularity, so use at your own risk.
请注意,该项目没有测试,也没有多少流行度,因此使用风险自负。
As mentioned you probably don't need deep copies. Try to change your data structures so you only need shallow copies.
如前所述,您可能不需要深拷贝。尝试更改您的数据结构,以便您只需要浅拷贝。
Few months later
几个月后
I wrote a smaller module instead, recommend you use xtend. It's not got an implementation containing jQuery baggage nor does it have bugs like node-extend does.
我写了一个较小的模块,建议您使用xtend。它没有包含 jQuery 包袱的实现,也没有像 node-extend 那样的错误。
回答by Kato
A quick and dirty answer to deep copies is just to cheat with a little JSON. It's not the most performant, but it does do the job extremely well.
对深拷贝的一个快速而肮脏的答案就是用一点 JSON 作弊。它的性能不是最好的,但它确实非常好地完成了这项工作。
function clone(a) {
return JSON.parse(JSON.stringify(a));
}
回答by ScriptMaster
Please use the built-in util module:
请使用内置的 util 模块:
var extend = require('util')._extend;
var merged = extend(obj1, obj2);
回答by thataustin
I know this is an old question, but I'd just like to throw lodash's mergeinto the mix as a good solution. I'd recommend lodash for utility functions in general :)
我知道这是一个老问题,但我只想将lodash 的合并作为一个很好的解决方案。我一般会推荐 lodash 作为实用函数:)
回答by user1928072
In Node.js, You can use Extendifyto create an _.extend function that supports nested objects extension (deep extend) and is also immutable to it's params (hence deep clone).
在 Node.js 中,您可以使用Extendify创建一个 _.extend 函数,该函数支持嵌套对象扩展(深度扩展)并且对于它的参数也是不可变的(因此是深度克隆)。
_.extend = extendify({
inPlace: false,
isDeep: true
});
回答by marksyzm
This works for deep object extension... be warned that it replaces arrays rather than their values but that can obviously be updated how you like. It should maintain enumeration capabilities and all the other stuff you probably want it to do
这适用于深层对象扩展……请注意,它会替换数组而不是它们的值,但显然可以根据您的喜好进行更新。它应该保持枚举功能和您可能希望它做的所有其他事情
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);
}
});
}
回答by Stanislav
node.extenddoes it deep and has familiar jQuery syntax
node.extend做的很深入并且有熟悉的 jQuery 语法
回答by Amin Jalali
just install extend. docs: node extend packageinstall:
只需安装扩展。文档: 节点扩展包安装:
npm install extend
then enjoy it:
然后享受它:
extend ( [deep], target, object1, [objectN] )
deep is optional. default is false. if switch to true it will recursively merge your objects.
深度是可选的。默认为假。如果切换为 true,它将递归合并您的对象。
回答by Vlad Miller
You also can use my version of extend plugin https://github.com/maxmara/dextend
您也可以使用我的扩展插件版本 https://github.com/maxmara/dextend