어레이를 복제하면 cloneArr = arr.slice()
nodejs에서 객체를 복제하는 방법을 알고 싶습니다.
답변:
성능을 떨어 뜨릴 필요가없는 유틸리티 및 클래스의 경우, 필자는 종종 속임수를 쓰며 JSON을 사용하여 깊은 복사를 수행합니다.
function clone(a) {
return JSON.parse(JSON.stringify(a));
}
이것은 유일한 대답이나 가장 우아한 대답이 아닙니다. 프로덕션 병목 현상에 대해서는 다른 모든 답변을 고려해야합니다. 그러나 이것은 빠르고 더러운 솔루션이며 매우 효과적이며 간단한 속성 해시를 복제하는 대부분의 상황에서 유용합니다.
newObj = obj.clone(args...);
Object.assign은 위의 답변에서 언급되지 않았습니다.
let cloned = Object.assign({}, source);
ES6를 사용하는 경우 스프레드 연산자를 사용할 수 있습니다.
let cloned = { ... source };
참조 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
let a = {x:1}; let b = Object.assign({}, a); a.x = 2; a.y = 1; console.log(a, b);
"자신의 롤링"을 원하지 않는 경우 일부 노드 모듈이 있습니다. 이것은 좋아 보인다 : https://www.npmjs.com/package/clone
순환 참조를 포함하여 모든 종류의 항목을 처리하는 것처럼 보입니다. 로부터 github의의 페이지 :
복제 마스터는 개체, 배열, 날짜 개체 및 RegEx 개체를 복제합니다. 모든 것이 재귀 적으로 복제되므로, 예를 들어 객체의 배열에서 날짜를 복제 할 수 있습니다. [...] 순환 참조? 네!
일반적이지만 유용한 복제 작업을 수행하는 것은 어렵습니다. 무엇을 재귀 적으로 복제해야하고 무엇을 복사해야하는지에 따라 특정 개체의 작동 방식이 달라지기 때문입니다.
유용 할 수있는 것은
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;
}
이 코드에서 논리는
null또는 undefined그냥 반환 ( clone메서드가 있는지 확인하려고 시도하는 오류이므로 특별한 경우가 필요합니다 )clone메서드가 있습니까? 그런 다음 사용이 복제 기능을 사용하면 사용자 지정 복제 방법을 쉽게 구현할 수 있습니다. 예를 들어
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);
};
객체에서 특정 배열에 대한 올바른 복제 작업이 얕은 복사본이라는 것을 알고있는 경우 values.slice()대신을 호출 할 수 있습니다 clone(values).
예를 들어 위의 코드에서 다각형 객체의 복제는 점을 복제하지만 동일한 스타일 객체를 공유하도록 명시 적으로 요구합니다. 대신 스타일 객체도 복제하려면 clone(this.style).
.clone메소드 자체 를 구현해야 함을 언급하는 +1 . 복제 개체를 처리하는 가장 좋은 방법입니다.
if (x.clone)해야if (typeof x.clone === 'function')
개체를 복제하는 기본 방법은 없습니다. 밑줄 _.clone은 얕은 클론을 구현 합니다.
_.clone = function(obj) {
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
슬라이스하거나 확장합니다.
여기에 _.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는 모든 항목을 반복하고 항목이 포함 된 새 개체를 만듭니다.
원하는 경우 나만의 순진한 구현을 롤아웃 할 수 있습니다.
function clone(o) {
var ret = {};
Object.keys(o).forEach(function (val) {
ret[val] = o[val];
});
return ret;
}
클로저를 복제 할 수 없기 때문에 딥 복제를 피해야하는 좋은 이유가 있습니다.
저는 개인적으로 질문 deep cloning objects before을했고 결론은 당신이 그렇게하지 않는다는 것입니다.
내 권장 사항은 사용 underscore이며 _.clone얕은 클론에 대한 방법입니다.
얕은 사본의 경우 (보통 모듈 등에서) reduce 패턴을 사용하는 것을 좋아합니다.
var newObject = Object.keys(original).reduce(function (obj, item) {
obj[item] = original[item];
return obj;
},{});
다음은 몇 가지 옵션에 대한 jsperf입니다. http://jsperf.com/shallow-copying
오래된 질문이지만 지금까지 제안 된 것보다 더 우아한 대답이 있습니다. 내장 된 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 } }
빈 객체 {}와 함께 첫 번째 매개 변수를 사용하는 것에 유의하십시오. 이것은 복사 된 객체를 새 객체로 복사해야한다는 것을 extend에게 알려줍니다. 기존 객체를 첫 번째 매개 변수로 사용하는 경우 두 번째 (및 모든 후속) 매개 변수가 첫 번째 매개 변수 변수에 대해 딥 병합 복사됩니다.
위의 예제 변수를 사용하여 다음을 수행 할 수도 있습니다.
var anotherMergeVar = { foo: "bar" };
extend(copiedObject, { anotherParam: 'value' }, anotherMergeVar);
console.log(copiedObject);
// outputs:
// { test: 12345, nested: { val: 6789 }, anotherParam: 'value', foo: 'bar' }
특히 AngularJS 및 jQuery에서 확장하는 데 사용되는 매우 편리한 유틸리티입니다.
이것이 다른 사람에게 도움이되기를 바랍니다. 객체 참조 덮어 쓰기는 비참하며 매번 해결됩니다!
lodash 도 사용할 수 있습니다 . 그것은이 복제 및 cloneDeep의 방법을.
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]);
복제 된 객체로 수행하려는 작업에 따라 자바 스크립트의 프로토 타입 상속 메커니즘을 활용하고 다음을 통해 다소 복제 된 객체를 얻을 수 있습니다.
var clonedObject = Object.create(originalObject);
이것이 좋든 나쁘 든 완전한 클론이 아니라는 점을 기억하십시오.
그것에 대한 좋은 점은 실제로 개체를 복제하지 않았으므로 메모리 공간이 적다는 것입니다.
이 방법에 대해 기억해야 할 몇 가지 까다로운 점은 프로토 타입 체인에 정의 된 속성의 반복이 때때로 약간 다르게 작동한다는 것입니다. 또한 해당 속성이 자체적으로 설정되지 않는 한 원본 객체의 변경 사항이 복제 된 객체에도 영향을 미친다는 사실입니다. .
var a = {foo: "bar"}, b = Object.create(a); a.foo = "broken"; console.log(b.foo); // "broken";
b.foo = "working"; console.log(a.foo); // still "broken";물론 원래 개체의 변경 사항이 "복제본"에 반영되고 "복제본"의 변경 사항이 원래 개체에 반영되지 않는다는 점을 알고 있어야합니다.하지만 위험하다고 부르지는 않겠습니다. – 모든 것은 클론으로 무엇을 하려는지에 달려 있습니다.
전체 딥 카피를 구현했습니다. 일반적인 복제 방법에 대한 최선의 선택이라고 생각하지만 순환 참조를 처리하지 않습니다.
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
이 코드는 프로토 타입과 함께 객체를 복사하고 함수도 복사합니다 (누군가에게 유용 할 수 있음).
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;
}
이 사본을 사용하면 원본이 구성에 클로저를 사용하는 경우를 제외하고는 원본과 복사 한 것 사이의 차이점을 찾을 수 없으므로 좋은 구현이라고 생각합니다.
도움이 되길 바랍니다
JavaScript의 객체와 배열은 참조로 호출을 사용합니다. 복사 된 값을 업데이트하면 원래 객체에 반영 될 수 있습니다. 이를 방지하려면 lodash 라이브러리 cloneDeep 메서드 실행 명령을 사용하여 참조가 전달되지 않도록 개체를 딥 클론 할 수 있습니다.
npm 설치 lodash
const ld = require('lodash')
const objectToCopy = {name: "john", age: 24}
const clonedObject = ld.cloneDeep(objectToCopy)