[javascript] Nodejs : 객체를 복제하는 방법

어레이를 복제하면 cloneArr = arr.slice()

nodejs에서 객체를 복제하는 방법을 알고 싶습니다.



답변

성능을 떨어 뜨릴 필요가없는 유틸리티 및 클래스의 경우, 필자는 종종 속임수를 쓰며 JSON을 사용하여 깊은 복사를 수행합니다.

function clone(a) {
   return JSON.parse(JSON.stringify(a));
}

이것은 유일한 대답이나 가장 우아한 대답이 아닙니다. 프로덕션 병목 현상에 대해서는 다른 모든 답변을 고려해야합니다. 그러나 이것은 빠르고 더러운 솔루션이며 매우 효과적이며 간단한 속성 해시를 복제하는 대부분의 상황에서 유용합니다.


답변

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


답변

“자신의 롤링”을 원하지 않는 경우 일부 노드 모듈이 있습니다. 이것은 좋아 보인다 : 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은 얕은 클론을 구현 합니다.

_.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에서 확장하는 데 사용되는 매우 편리한 유틸리티입니다.

이것이 다른 사람에게 도움이되기를 바랍니다. 객체 참조 덮어 쓰기는 비참하며 매번 해결됩니다!