If I clone an array, I use cloneArr = arr.slice()
如果我克隆一个数组,我使用cloneArr = arr.slice()
I want know how to clone a object in nodejs.
我想知道如何在node . js中克隆一个对象。
11 个解决方案
#1
135
For utilities and classes where there is no need to squeeze every drop of performance, I often cheat and just use JSON to perform a deep copy:
对于那些不需要压缩每一滴性能的实用程序和类,我经常作弊,只使用JSON进行深度复制:
function clone(a) {
return JSON.parse(JSON.stringify(a));
}
This isn't the only answer or the most elegant answer; all of the other answers should be considered for production bottlenecks. However, this is a quick and dirty solution, quite effective, and useful in most situations where I would clone a simple hash of properties.
这不是唯一的答案,也不是最优雅的答案;所有其他的答案都应该考虑到生产瓶颈。但是,这是一个快速而又脏的解决方案,非常有效,在大多数情况下,我将克隆一个简单的属性散列。
#2
18
There are some Node modules out there if don't want to "roll your own". This one looks good: https://www.npmjs.com/package/clone
如果不想“滚你自己的”,还有一些节点模块。这个看起来不错:https://www.npmjs.com/package/clone
Looks like it handles all kinds of stuff, including circular references. From the github page:
看起来它处理各种各样的东西,包括循环引用。从github页面:
clone masters cloning objects, arrays, Date objects, and RegEx objects. Everything is cloned recursively, so that you can clone dates in arrays in objects, for example. [...] Circular references? Yep!
克隆控制克隆对象、数组、日期对象和RegEx对象。所有东西都被递归地克隆,因此您可以在对象的数组中克隆日期。[…循环引用吗?是的!
#3
17
Object.assign hasn't been mentioned in any of above answers.
对象。赋值在以上任何一个答案中都没有提到。
let cloned = Object.assign({}, source);
If you're on ES6 you can use the spread operator:
如果您使用ES6,您可以使用扩展操作符:
let cloned = { ... source };
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
#4
10
It's hard to do a generic but useful clone operation because what should be cloned recursively and what should be just copied depends on how the specific object is supposed to work.
做一个通用但有用的克隆操作是很困难的,因为应该递归地克隆什么,应该复制什么,取决于特定对象应该如何工作。
Something that may be useful is
可能有用的是
function clone(x)
{
if (x === null || x === undefined)
return x;
if (typeof x.clone === "function")
return x.clone();
if (x.constructor == Array)
{
var r = [];
for (var i=0,n=x.length; i<n; i++)
r.push(clone(x[i]));
return r;
}
return x;
}
In this code the logic is
在这段代码中,逻辑是
- in case of
null
orundefined
just return the same (the special case is needed because it's an error to try to see if aclone
method is present) - 如果是空的或未定义的,只需返回相同的(需要特殊情况,因为试图查看是否存在克隆方法是错误的)
- does the object have a
clone
method ? then use that - 对象是否有克隆方法?然后使用该
- is the object an array ? then do a recursive cloning operation
- 对象是数组吗?然后执行递归克隆操作
- otherwise just return the same value
- 否则只返回相同的值
This clone function should allow implementing custom clone methods easily... for example
这个克隆函数应该允许很容易地实现自定义克隆方法……例如
function Point(x, y)
{
this.x = x;
this.y = y;
...
}
Point.prototype.clone = function()
{
return new Point(this.x, this.y);
};
function Polygon(points, style)
{
this.points = points;
this.style = style;
...
}
Polygon.prototype.clone = function()
{
return new Polygon(clone(this.points),
this.style);
};
When in the object you know that a correct cloning operation for a specific array is just a shallow copy then you can call values.slice()
instead of clone(values)
.
在对象中,当您知道特定数组的正确克隆操作只是一个浅拷贝时,您可以调用values.slice()而不是clone(值)。
For example in the above code I am explicitly requiring that a cloning of a polygon object will clone the points, but will share the same style object. If I want to clone the style object too instead then I can just pass clone(this.style)
.
例如,在上面的代码中,我明确要求克隆一个多边形对象将克隆这些点,但将共享相同的样式对象。如果我也想克隆样式对象,那么我可以传递clone(this.style)。
#5
9
There is no native method for cloning objects. Underscore implements _.clone
which is a shallow clone.
没有用于克隆对象的本机方法。强调实现_。克隆,一个浅层的克隆。
_.clone = function(obj) {
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
It either slices it or extends it.
它要么切片,要么扩展。
Here's _.extend
这是_.extend
// extend the obj (first parameter)
_.extend = function(obj) {
// for each other parameter
each(slice.call(arguments, 1), function(source) {
// loop through all properties of the other objects
for (var prop in source) {
// if the property is not undefined then add it to the object.
if (source[prop] !== void 0) obj[prop] = source[prop];
}
});
// return the object (first parameter)
return obj;
};
Extend simply iterates through all the items and creates a new object with the items in it.
Extend简单地遍历所有项,并使用其中的项创建一个新对象。
You can roll out your own naive implementation if you want
如果需要,您可以推出自己的简单实现。
function clone(o) {
var ret = {};
Object.keys(o).forEach(function (val) {
ret[val] = o[val];
});
return ret;
}
There are good reasons to avoid deep cloning because closures cannot be cloned.
有充分的理由避免深度克隆,因为闭包不能被克隆。
I've personally asked a question about deep cloning objects before
and the conclusion I came to is that you just don't do it.
我个人曾经问过一个关于深度克隆对象的问题,我得出的结论是,你就是不这么做。
My recommendation is use underscore
and it's _.clone
method for shallow clones
我的建议是使用下划线,它是_。浅层无性系克隆方法
#6
9
For a shallow copy, I like to use the reduce pattern (usually in a module or such), like so:
对于浅拷贝,我喜欢使用reduce模式(通常在模块中),比如:
var newObject = Object.keys(original).reduce(function (obj, item) {
obj[item] = original[item];
return obj;
},{});
Here's a jsperf for a couple of the options: http://jsperf.com/shallow-copying
这里有一个jsperf选项:http://jsperf.com/shallow-copy
#7
6
Old question, but there's a more elegant answer than what's been suggested so far; use the built-in utils._extend:
老问题,但有一个比目前所提出的更优雅的答案;使用内置的utils._extend:
var extend = require("util")._extend;
var varToCopy = { test: 12345, nested: { val: 6789 } };
var copiedObject = extend({}, varToCopy);
console.log(copiedObject);
// outputs:
// { test: 12345, nested: { val: 6789 } }
Note the use of the first parameter with an empty object {} - this tells extend that the copied object(s) need to be copied to a new object. If you use an existing object as the first parameter, then the second (and all subsequent) parameters will be deep-merge-copied over the first parameter variable.
注意第一个参数的使用是空对象{}——这说明需要将复制的对象复制到新对象。如果您使用一个现有的对象作为第一个参数,那么第二个(以及所有后续的)参数将在第一个参数变量上进行深度合并复制。
Using the example variables above, you can also do this:
使用上面的示例变量,您还可以这样做:
var anotherMergeVar = { foo: "bar" };
extend(copiedObject, { anotherParam: 'value' }, anotherMergeVar);
console.log(copiedObject);
// outputs:
// { test: 12345, nested: { val: 6789 }, anotherParam: 'value', foo: 'bar' }
Very handy utility, especially where I'm used to extend in AngularJS and jQuery.
非常方便的实用工具,特别是在使用AngularJS和jQuery进行扩展时。
Hope this helps someone else; object reference overwrites are a misery, and this solves it every time!
希望这能帮助别人;对象引用覆盖是一种痛苦,而且每次都解决它!
#8
5
You can use lodash as well. It has a clone and cloneDeep methods.
你也可以使用lodash。它有一个克隆和克隆的方法。
var _= require('lodash');
var objects = [{ 'a': 1 }, { 'b': 2 }];
var shallow = _.clone(objects);
console.log(shallow[0] === objects[0]);
// => true
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
#9
2
Depending on what you want to do with your cloned object you can utilize the prototypal inheritence mechanism of javascript and achieve a somewhat cloned object through:
根据您想要对克隆对象做什么,您可以利用javascript的原型继承机制,通过以下方式实现某种程度的克隆对象:
var clonedObject = Object.create(originalObject);
Just remember that this isn't a full clone - for better or worse.
请记住,这不是一个完整的克隆——不管好或坏。
A good thing about that is that you actually haven't duplicated the object so the memory footprint will be low.
这样做的好处是,实际上您没有复制对象,因此内存占用将会很低。
Some tricky things to remember though about this method is that iteration of properties defined in the prototype chain sometimes works a bit different and the fact that any changes to the original object will affect the cloned object as well unless that property has been set on itself also.
关于这个方法,需要记住的一些棘手的事情是,在原型链中定义的属性的迭代有时会有一点不同,而对原始对象的任何更改也会影响到被克隆的对象,除非属性本身也被设置。
#10
1
I implemented a full deep copy. I believe its the best pick for a generic clone method, but it does not handle cyclical references.
我实现了一个完整的深度拷贝。我认为它是通用克隆方法的最佳选择,但是它不处理循环引用。
Usage example:
parent = {'prop_chain':3}
obj = Object.create(parent)
obj.a=0; obj.b=1; obj.c=2;
obj2 = copy(obj)
console.log(obj, obj.prop_chain)
// '{'a':0, 'b':1, 'c':2} 3
console.log(obj2, obj2.prop_chain)
// '{'a':0, 'b':1, 'c':2} 3
parent.prop_chain=4
obj2.a = 15
console.log(obj, obj.prop_chain)
// '{'a':0, 'b':1, 'c':2} 4
console.log(obj2, obj2.prop_chain)
// '{'a':15, 'b':1, 'c':2} 4
The code itself:
This code copies objects with their prototypes, it also copy functions (might be useful for someone).
这段代码用原型复制对象,它也复制函数(可能对某些人有用)。
function copy(obj) {
// (F.prototype will hold the object prototype chain)
function F() {}
var newObj;
if(typeof obj.clone === 'function')
return obj.clone()
// To copy something that is not an object, just return it:
if(typeof obj !== 'object' && typeof obj !== 'function' || obj == null)
return obj;
if(typeof obj === 'object') {
// Copy the prototype:
newObj = {}
var proto = Object.getPrototypeOf(obj)
Object.setPrototypeOf(newObj, proto)
} else {
// If the object is a function the function evaluate it:
var aux
newObj = eval('aux='+obj.toString())
// And copy the prototype:
newObj.prototype = obj.prototype
}
// Copy the object normal properties with a deep copy:
for(var i in obj) {
if(obj.hasOwnProperty(i)) {
if(typeof obj[i] !== 'object')
newObj[i] = obj[i]
else
newObj[i] = copy(obj[i])
}
}
return newObj;
}
With this copy I can't find any difference between the original and the copied one except if the original used closures on its construction, so i think its a good implementation.
有了这个副本,我找不出原件和复制品之间有什么区别,除非原件在结构上使用了闭包,所以我认为这是一个很好的实现。
I hope it helps
我希望这有助于
#11
1
for array, one can use
对于数组,可以使用
var arr = [1,2,3];
var arr_2 = arr ;
print ( arr_2 );
arr=arr.slice(0);
arr = arr.slice(0);
print ( arr );
arr[1]=9999;
print ( arr_2 );
#1
135
For utilities and classes where there is no need to squeeze every drop of performance, I often cheat and just use JSON to perform a deep copy:
对于那些不需要压缩每一滴性能的实用程序和类,我经常作弊,只使用JSON进行深度复制:
function clone(a) {
return JSON.parse(JSON.stringify(a));
}
This isn't the only answer or the most elegant answer; all of the other answers should be considered for production bottlenecks. However, this is a quick and dirty solution, quite effective, and useful in most situations where I would clone a simple hash of properties.
这不是唯一的答案,也不是最优雅的答案;所有其他的答案都应该考虑到生产瓶颈。但是,这是一个快速而又脏的解决方案,非常有效,在大多数情况下,我将克隆一个简单的属性散列。
#2
18
There are some Node modules out there if don't want to "roll your own". This one looks good: https://www.npmjs.com/package/clone
如果不想“滚你自己的”,还有一些节点模块。这个看起来不错:https://www.npmjs.com/package/clone
Looks like it handles all kinds of stuff, including circular references. From the github page:
看起来它处理各种各样的东西,包括循环引用。从github页面:
clone masters cloning objects, arrays, Date objects, and RegEx objects. Everything is cloned recursively, so that you can clone dates in arrays in objects, for example. [...] Circular references? Yep!
克隆控制克隆对象、数组、日期对象和RegEx对象。所有东西都被递归地克隆,因此您可以在对象的数组中克隆日期。[…循环引用吗?是的!
#3
17
Object.assign hasn't been mentioned in any of above answers.
对象。赋值在以上任何一个答案中都没有提到。
let cloned = Object.assign({}, source);
If you're on ES6 you can use the spread operator:
如果您使用ES6,您可以使用扩展操作符:
let cloned = { ... source };
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
#4
10
It's hard to do a generic but useful clone operation because what should be cloned recursively and what should be just copied depends on how the specific object is supposed to work.
做一个通用但有用的克隆操作是很困难的,因为应该递归地克隆什么,应该复制什么,取决于特定对象应该如何工作。
Something that may be useful is
可能有用的是
function clone(x)
{
if (x === null || x === undefined)
return x;
if (typeof x.clone === "function")
return x.clone();
if (x.constructor == Array)
{
var r = [];
for (var i=0,n=x.length; i<n; i++)
r.push(clone(x[i]));
return r;
}
return x;
}
In this code the logic is
在这段代码中,逻辑是
- in case of
null
orundefined
just return the same (the special case is needed because it's an error to try to see if aclone
method is present) - 如果是空的或未定义的,只需返回相同的(需要特殊情况,因为试图查看是否存在克隆方法是错误的)
- does the object have a
clone
method ? then use that - 对象是否有克隆方法?然后使用该
- is the object an array ? then do a recursive cloning operation
- 对象是数组吗?然后执行递归克隆操作
- otherwise just return the same value
- 否则只返回相同的值
This clone function should allow implementing custom clone methods easily... for example
这个克隆函数应该允许很容易地实现自定义克隆方法……例如
function Point(x, y)
{
this.x = x;
this.y = y;
...
}
Point.prototype.clone = function()
{
return new Point(this.x, this.y);
};
function Polygon(points, style)
{
this.points = points;
this.style = style;
...
}
Polygon.prototype.clone = function()
{
return new Polygon(clone(this.points),
this.style);
};
When in the object you know that a correct cloning operation for a specific array is just a shallow copy then you can call values.slice()
instead of clone(values)
.
在对象中,当您知道特定数组的正确克隆操作只是一个浅拷贝时,您可以调用values.slice()而不是clone(值)。
For example in the above code I am explicitly requiring that a cloning of a polygon object will clone the points, but will share the same style object. If I want to clone the style object too instead then I can just pass clone(this.style)
.
例如,在上面的代码中,我明确要求克隆一个多边形对象将克隆这些点,但将共享相同的样式对象。如果我也想克隆样式对象,那么我可以传递clone(this.style)。
#5
9
There is no native method for cloning objects. Underscore implements _.clone
which is a shallow clone.
没有用于克隆对象的本机方法。强调实现_。克隆,一个浅层的克隆。
_.clone = function(obj) {
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
It either slices it or extends it.
它要么切片,要么扩展。
Here's _.extend
这是_.extend
// extend the obj (first parameter)
_.extend = function(obj) {
// for each other parameter
each(slice.call(arguments, 1), function(source) {
// loop through all properties of the other objects
for (var prop in source) {
// if the property is not undefined then add it to the object.
if (source[prop] !== void 0) obj[prop] = source[prop];
}
});
// return the object (first parameter)
return obj;
};
Extend simply iterates through all the items and creates a new object with the items in it.
Extend简单地遍历所有项,并使用其中的项创建一个新对象。
You can roll out your own naive implementation if you want
如果需要,您可以推出自己的简单实现。
function clone(o) {
var ret = {};
Object.keys(o).forEach(function (val) {
ret[val] = o[val];
});
return ret;
}
There are good reasons to avoid deep cloning because closures cannot be cloned.
有充分的理由避免深度克隆,因为闭包不能被克隆。
I've personally asked a question about deep cloning objects before
and the conclusion I came to is that you just don't do it.
我个人曾经问过一个关于深度克隆对象的问题,我得出的结论是,你就是不这么做。
My recommendation is use underscore
and it's _.clone
method for shallow clones
我的建议是使用下划线,它是_。浅层无性系克隆方法
#6
9
For a shallow copy, I like to use the reduce pattern (usually in a module or such), like so:
对于浅拷贝,我喜欢使用reduce模式(通常在模块中),比如:
var newObject = Object.keys(original).reduce(function (obj, item) {
obj[item] = original[item];
return obj;
},{});
Here's a jsperf for a couple of the options: http://jsperf.com/shallow-copying
这里有一个jsperf选项:http://jsperf.com/shallow-copy
#7
6
Old question, but there's a more elegant answer than what's been suggested so far; use the built-in utils._extend:
老问题,但有一个比目前所提出的更优雅的答案;使用内置的utils._extend:
var extend = require("util")._extend;
var varToCopy = { test: 12345, nested: { val: 6789 } };
var copiedObject = extend({}, varToCopy);
console.log(copiedObject);
// outputs:
// { test: 12345, nested: { val: 6789 } }
Note the use of the first parameter with an empty object {} - this tells extend that the copied object(s) need to be copied to a new object. If you use an existing object as the first parameter, then the second (and all subsequent) parameters will be deep-merge-copied over the first parameter variable.
注意第一个参数的使用是空对象{}——这说明需要将复制的对象复制到新对象。如果您使用一个现有的对象作为第一个参数,那么第二个(以及所有后续的)参数将在第一个参数变量上进行深度合并复制。
Using the example variables above, you can also do this:
使用上面的示例变量,您还可以这样做:
var anotherMergeVar = { foo: "bar" };
extend(copiedObject, { anotherParam: 'value' }, anotherMergeVar);
console.log(copiedObject);
// outputs:
// { test: 12345, nested: { val: 6789 }, anotherParam: 'value', foo: 'bar' }
Very handy utility, especially where I'm used to extend in AngularJS and jQuery.
非常方便的实用工具,特别是在使用AngularJS和jQuery进行扩展时。
Hope this helps someone else; object reference overwrites are a misery, and this solves it every time!
希望这能帮助别人;对象引用覆盖是一种痛苦,而且每次都解决它!
#8
5
You can use lodash as well. It has a clone and cloneDeep methods.
你也可以使用lodash。它有一个克隆和克隆的方法。
var _= require('lodash');
var objects = [{ 'a': 1 }, { 'b': 2 }];
var shallow = _.clone(objects);
console.log(shallow[0] === objects[0]);
// => true
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
#9
2
Depending on what you want to do with your cloned object you can utilize the prototypal inheritence mechanism of javascript and achieve a somewhat cloned object through:
根据您想要对克隆对象做什么,您可以利用javascript的原型继承机制,通过以下方式实现某种程度的克隆对象:
var clonedObject = Object.create(originalObject);
Just remember that this isn't a full clone - for better or worse.
请记住,这不是一个完整的克隆——不管好或坏。
A good thing about that is that you actually haven't duplicated the object so the memory footprint will be low.
这样做的好处是,实际上您没有复制对象,因此内存占用将会很低。
Some tricky things to remember though about this method is that iteration of properties defined in the prototype chain sometimes works a bit different and the fact that any changes to the original object will affect the cloned object as well unless that property has been set on itself also.
关于这个方法,需要记住的一些棘手的事情是,在原型链中定义的属性的迭代有时会有一点不同,而对原始对象的任何更改也会影响到被克隆的对象,除非属性本身也被设置。
#10
1
I implemented a full deep copy. I believe its the best pick for a generic clone method, but it does not handle cyclical references.
我实现了一个完整的深度拷贝。我认为它是通用克隆方法的最佳选择,但是它不处理循环引用。
Usage example:
parent = {'prop_chain':3}
obj = Object.create(parent)
obj.a=0; obj.b=1; obj.c=2;
obj2 = copy(obj)
console.log(obj, obj.prop_chain)
// '{'a':0, 'b':1, 'c':2} 3
console.log(obj2, obj2.prop_chain)
// '{'a':0, 'b':1, 'c':2} 3
parent.prop_chain=4
obj2.a = 15
console.log(obj, obj.prop_chain)
// '{'a':0, 'b':1, 'c':2} 4
console.log(obj2, obj2.prop_chain)
// '{'a':15, 'b':1, 'c':2} 4
The code itself:
This code copies objects with their prototypes, it also copy functions (might be useful for someone).
这段代码用原型复制对象,它也复制函数(可能对某些人有用)。
function copy(obj) {
// (F.prototype will hold the object prototype chain)
function F() {}
var newObj;
if(typeof obj.clone === 'function')
return obj.clone()
// To copy something that is not an object, just return it:
if(typeof obj !== 'object' && typeof obj !== 'function' || obj == null)
return obj;
if(typeof obj === 'object') {
// Copy the prototype:
newObj = {}
var proto = Object.getPrototypeOf(obj)
Object.setPrototypeOf(newObj, proto)
} else {
// If the object is a function the function evaluate it:
var aux
newObj = eval('aux='+obj.toString())
// And copy the prototype:
newObj.prototype = obj.prototype
}
// Copy the object normal properties with a deep copy:
for(var i in obj) {
if(obj.hasOwnProperty(i)) {
if(typeof obj[i] !== 'object')
newObj[i] = obj[i]
else
newObj[i] = copy(obj[i])
}
}
return newObj;
}
With this copy I can't find any difference between the original and the copied one except if the original used closures on its construction, so i think its a good implementation.
有了这个副本,我找不出原件和复制品之间有什么区别,除非原件在结构上使用了闭包,所以我认为这是一个很好的实现。
I hope it helps
我希望这有助于
#11
1
for array, one can use
对于数组,可以使用
var arr = [1,2,3];
var arr_2 = arr ;
print ( arr_2 );
arr=arr.slice(0);
arr = arr.slice(0);
print ( arr );
arr[1]=9999;
print ( arr_2 );