Javascript 객체 클론할 깊이형 가장 효과적인 방법은 무엇입니까?

Javascript 객체여야 클론하려면 가장 효과적인 방법은 무엇입니까? # 39 i& obj = eval (뤼네발 (o)), ',' ve seen 사용되고 있지만, that& # 39 의 비표준 Firefox 에서 지원하는 유일한 .&lt br/&gt &lt br/>;;; # 39, ve done) 와 같은 것들을 i& 제슨스파스 (제슨.스트린그리피 (o)), '효율' obj = 그러나 질문. &lt br/&gt &lt br/>;;; # 39 i& 볼 수 있는 다양한 기능, 재귀 복사 역시 이제는 아니다. br /&gt <;

39 m, 놀란 i& 오빠예요-아니 정식 솔루션이므로 존재합니다.

질문에 대한 의견 (8)
해결책

넷윈을 깊이형 클론한

39 에서 실험적으로 작동됨 ";; s 불렀으매 it& 구조화된 cloning&quot 노드입니다 11 이상, 브라우저에 착륙할 예정입니다 기대해 본다. 자세한 내용은 [이 오토메이티드] (https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript/10916838 # 10916838) 참조.

빠른 데이터 손실 함께 클론한 JSON.parse/stringify -

사용하지 않는 경우, 함수, '정의되지 않은', '인피니티', '날짜의 정규 표현식 매핑하며 세트, 물방울, filelist, 이밎데이타, 분산 객체, 아주 단순해졌습니다 입력되었는지 어레이에는 어레이나 다른 복잡한 유형 내에서 하나의 객체가 깊은 클론할 실었다.

'제슨스파스 (제슨.스트린그리피 (객체))'

<! - begin 스니핏: js 숨기십시오: 거짓값 콘솔: 진정한 바벨. &gt 거짓값 -;

const a = {
  string: 'string',
  number: 123,
  bool: false,
  nul: null,
  date: new Date(),  // stringified
  undef: undefined,  // lost
  inf: Infinity,  // forced to 'null'
  re: /.*/,  // lost
}
console.log(a);
console.log(typeof a.date);  // Date object
const clone = JSON.parse(JSON.stringify(a));
console.log(clone);
console.log(typeof clone.date);  // result of .toISOString()

끝 - &lt 스니핏 >;!

참조 [Corban& # 39 의 오토메이티드] (https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript/5344074 # 5344074) 를 벤치마크.

신뢰할 수 있는 라이브러리를 사용하여 클론한

이후 클론한 객체에는 없는 사소한 (복잡한 유형, 원형파 참조입니다 기능 등), 대부분의 주요 클론할 라이브러리는 함수 객체. Don& # 39, t, re you& wheel이라고 것이다 - # 39 이미 사용하고 있는 경우, 함수 객체 클론한 라리브러리 있는지 확인합니다. 예를 들어,

ES6

참고로 리플리케이터에는 ES6 완전성을 위해 얕은 복제본에 메커니즘: ['오브ject.라시니 ()'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) 과 [전파하므로 작동자] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax).

해설 (24)

이 체크아웃합니다 벤치마트: http://jsben.ch/ # /bWfk9

내 앞에 있는 주요 관심사라고 I found 는 이전 속도 테스트

JSON.parse(JSON.stringify(obj))

할 수 있는 방법은 최저속 깊이형 클론할 객체에는 것이 보다 느린 제크리스에스테드 을 (를) '' 플래그가 설정되었습니다 깊이형 진정한 무려 10-20%).

이 때 상당히 빠른 'deep' 로 설정되었습니다 제크리스에스테드 플래깅 '거짓' (얕은 클론할). 좋은 옵션이 포함되어 있으므로, 일부 doesn& 정의되지 않은 추가적인 논리를 문자용 검증 및 속성 등을 통해 복제본에 있지만 이 또한 t # 39, 느린 약간은요 다운되어도 있습니다.

객체에는 클론할 피할 수 있는 구조를 알고 있는 경우 또는 시도 중인 깊이형 네스트된 어레이에는 단순한 '를 쓸 수 있습니다 (var) 에서 내가 obj)' 루프 클론할 확인하는 동안 너회의 객체에는 해스운프로페티 것보다 훨씬 빨리 훨씬 많을 것 포함한다.

마지막으로 알려진 객체 구조에 클론하려면 시도중입니다 경우 훨씬 더 많이 얻을 수 있으며, 핫 루프 이어지고 있는 것만으로 성능이 클론 절차 및 수동으로로 객체에는 것이다.

Javascript engine) 가 'for.in' 루프 및 검사 해스운프로페티 추적 빨아들일 dell. 최적화합니다 느린 너회가 다운되어도 잘 알려져 있다. 수작업식 클론할 속도용 때 절대적으로 있어야 합니다.

var clonedObject = {
  knownProp: obj.knownProp,
  ..
}

두려워 ' (제슨.스트린그리피 (obj)' 에 '방법을 사용하여 제슨스파스 날짜' - '객체에는 제슨.스트린그리피 (새 날짜 ())' 의 ISO 에서 날짜 형식, 즉 '제슨스파스 문자열으로 되돌려줍니다 표현 ()', 't doesn& # 39 로 다시 변환하시겠습니까 날짜' 객체에는. [지켜보리니 이 문제에 대한 자세한 내용은] [2].

또한, 적어도 65 에 크롬 유념하십시오 넷윈을 클론한 갈 길 아니다. [이 에스페르프] 따르면 (https://jsperf.com/efficient-deep-cloning-teqniques), 수행 기능을 새로 만들어 넷윈을 클론한 800x 는 거의 모든 방법을 사용하여 보다 느린 제슨.스트린그리피 원하는거요 놀라운 속도로 가로질러 보드입니다.

이 기본 방법을 사용하는 경우 시도하시겠습니까 Javascript ES6 클론하는 또는 얕은 복제본입니다.

Object.assign({}, obj);

[2]: # 11491993 https://stackoverflow.com/questions/11491938/issues-with-date-when-using-json-stringify-and-json-parse/11491993

해설 (29)

변수만 않고 있다고 가정할 때, 모든 기능을 사용할 수 있는 객체에는 됩니다.

var newObject = JSON.parse(JSON.stringify(oldObject));
해설 (13)

구조화된 클론한

Html 표준 dm_ownerdm_owner [ 내부 구조화된 클론한 / 직렬화하지 알고리즘입니다 ] [1] 깊이형 클론을 만들 수 있는 객체. 그러나 아직 일부 제한된 내장현 유형 외에 it 는 JSON 지원 하에 몇 가지 유형, 세트, 물방울, 날짜, 정규 표현식 매핑하며 filelist 이밎데이타, 분산, 아마 입력되었는지 어레이에는 어레이에는 향후 추가. 또한, 경기 내에서 지원할 수 있도록 허용하는 클론된 데이터를 보존하는 참조입니다 대한 오류를 일으킬 수 있는 구조 및 반복 JSON.

지원하기 위해 node. js: 실험 & # 128578.

'현재' 는 v8 모듈에서의 node. js (vmware. 노드입니다 11) [같이 구조화된 직렬화하지 API 를 직접] (https://nodejs.org/api/all.html # v8_serialization_api) 으로, 이 기능은 있지만 여전히 &quot experimental&quot 변경될 수 있으며, 또는 제거, 향후 버전. # 39 를 사용하는 경우, re you& 호환적 버전, 객체가 클로닝 (cloning) 같은 단순한: "'js 랭 필요한 (# 39, & # 39, v8&), v8 = 상수 const 스트루스터트클로네 = obj = &gt. { v8.deserialize 반품하십시오 (v8.serialize (목표)); }; "'

직접판매용 봉사할 수 있는 브라우저: 어쩌면 결국? & # 128528.

브라우저 제공하십시오 구조화된 클론한 알고리즘입니다 직접판매용 인터페이스입니다 있지 않습니다 ' ()' 기능을 설명한 적이 있지만 노드전역 스트루스터트클로네 [whatwg / html 에서 # 793 깃허브] (https://github.com/whatwg/html/issues/793). 현재 대부분의 약간만이라도 등 간단한 용도로 사용하기 제안했다. "'js 랭 const 클론할 = 스트루스터트클로네 (원본). "'

39 이것은 배송되었을 않는 한, browsers&. 구축이 체계적인 클론할 디렉토리에만 간접적으로 드러냈다.

비동기적입니다 해결하십시오. 사용할 수 있습니다. & # 128533.

이 api 를 통해 데이터를 게시할 수 있는 체계적인 클론할 낮은 오버헤드 만들 수 있는 방법이 기존 1 포트에 메사게차네우스. 다른 포트에 연결된 'a' 이벤트 '라는 메시지가 있는 발생시켜 구조화된 클론할 .data'. 이러한 이벤트를 수신하는 죄송합니다. 반드시 비동기적입니다, 동기식 상대적으로 실용적인 대안 있다. "'js 랭 클래스 스트루스터트클로너 { 구성자를 () { this.pendingClones = 신규 맵 (); this.nextKey = 0;

const 채널 = new 메사게채널 (); this.inPort = channel.port1. this.outPort = channel.port2.

this.outPort.onmessage = ({데이터: 키 값을 {}}) = &gt. { const 해결하십시오 = this.pendingClones.get (키). 해결하십시오 (가치). this.pendingClones.delete (키). }; this.outPort.start (); } 클로네세인스 (가치) { 새로운 약속하나요 복귀하십시오 (해결하십시오 = &gt. { const 키 = this.nextKey++. this.pendingClones.set (key, 해결하십시오); this.inPort_.postMessage (}, {키 값을). }). } } const 스트루스터트클로네세인스 빈다우드스트루스터트클로네세인스 = = 스트루스터트클론스터proto티페리클로네세인c빈드 (새 스트루스터트클로너); "'

들어 있습니다.

"'js 랭 const 주 = 비동기 () = &gt. { const 오리지널 = {날짜: 새로운 날짜 (), 번호: 마테오랭동 ()}; 오리지널드셀프 = 원본, const 클론할 = 기다리는 스트루스터트클로네세인스 (원본).

39, 다른 객체에는 // They& re:

콘솔드라스트 (원래 클론할! =); 콘솔드라스트 (오리지널드다테 클로네.다테! =);

39 경기 They& //, re:

콘솔드라스트 (오리지널드셀프 = 원래). 콘솔드라스트 (클로네.셀프 클론할 =); 포함된 // avamer 값: 콘솔드라스트 (클로네스 움베르 오리지널드 움베르 =); 콘솔드라스트 (번호 (오리지널드다테) = 번호 (클로네.다테));

콘솔드로그 (complete.&quot 어설션을 ";). }; 주 (); "'

동기식 해결 방법: 끔찍해! & # 129314.

There are no good 만들 수 있는 옵션을 구조화된 클론입니다 동시에. 다음은 몇 가지 비실용적입니다 hacks 한다. '흐리스토리오푸쉬국가 ()' 와 '흐리스토리오레프리스국가 ()' 의 인수, 지정할 수 있는 체계적인 클론할 모두 그들의 첫 번째 값을 흐리스토리오스테이트 만들기 ''. 이 모든 객체를 생성할 수 있는 체계적인 클론할 이렇게 사용할 수 있습니다. "'js 랭 const 스트루스터트클로네 = obj = &gt. { const 올스테이트 = 흐리스토리오스테이트. 흐리스토리오레프리스국가 (obj, null). const 클레오니도비 = 흐리스토리오스테이트. 흐리스토리오레프리스국가 (올스테이트, null); 클레오니도비 반품하십시오. }; "'

들어 있습니다.

<! - begin 스니핏: js 숨기십시오: 참 - &gt.

'use strict';

const main = () => {
  const original = { date: new Date(), number: Math.random() };
  original.self = original;

  const clone = structuredClone(original);

  // They're different objects:
  console.assert(original !== clone);
  console.assert(original.date !== clone.date);

  // They're cyclical:
  console.assert(original.self === original);
  console.assert(clone.self === clone);

  // They contain equivalent values:
  console.assert(original.number === clone.number);
  console.assert(Number(original.date) === Number(clone.date));

  console.log("Assertions complete.");
};

const structuredClone = obj => {
  const oldState = history.state;
  history.replaceState(obj, null);
  const clonedObj = history.state;
  history.replaceState(oldState, null);
  return clonedObj;
};

main();

끝 - &lt 스니핏 >;! 비록 매우 느린 동기식 수 있습니다. 이 브라우저 기록 조작 관련된 모든 오버헤드에 초래. 크롬 반복적으로 되기 위해 일시적으로 응답하지 않는 이 메서드를 호출할 일으킬 수 있다. 이 ['알림' 구성자를] (https://developer.mozilla.org/en-US/docs/Web/API/Notification/Notification) 는 구조화된 클론할 연관된 데이터를. 또한 시도_횟수 있지만브라우저에 표시하십시오 사용자에게 통지용 있지만 이는 없을 경우 자동으로 요청되었습니다 통지용 않을 수 없습니다. # 39 의 경우 다른 용도로 사용 권한, ll, ve 통지용 닫으십시오 we& 즉시 we& # 39 만들어졌다.

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.onshow = n.close.bind(n);
  return n.data;
};

들어 있습니다.

<! - begin 스니핏: js 숨기십시오: 참 - &gt.

'use strict';

const main = () => {
  const original = { date: new Date(), number: Math.random() };
  original.self = original;

  const clone = structuredClone(original);

  // They're different objects:
  console.assert(original !== clone);
  console.assert(original.date !== clone.date);

  // They're cyclical:
  console.assert(original.self === original);
  console.assert(clone.self === clone);

  // They contain equivalent values:
  console.assert(original.number === clone.number);
  console.assert(Number(original.date) === Number(clone.date));

  console.log("Assertions complete.");
};

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.close();
  return n.data;
};

main();

끝 - &lt 스니핏 >;! [1]: https://html.spec.whatwg.org/multipage/structured-data.html # 정형 데이터를 안전하게 반군지역

해설 (4)

39 한 경우, 모든 내장 시도하시겠습니까 wasn& t 수 있습니다.

function clone(obj) {
    if (obj === null || typeof (obj) !== 'object' || 'isActiveClone' in obj)
        return obj;

    if (obj instanceof Date)
        var temp = new obj.constructor(); //or new Date(obj);
    else
        var temp = obj.constructor();

    for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            obj['isActiveClone'] = null;
            temp[key] = clone(obj[key]);
            delete obj['isActiveClone'];
        }
    }
    return temp;
}
해설 (11)

효율적인 방법으로 한 줄의 코드가 아닌 깊이형 클론할) 승인/보류 객체에는 클론할

Ui_policytable_java_spe_policy '오브ject.라시니' 방법은 (ES6) 는 2015년 ecma 스크립트 부분을 정확히 어떤 표준판과 합니다.

var clone = Object.assign({}, obj);

이 값을 복사합니다를 오브ject.라시니 &gt, () 메서드를 사용하여 모든 특성 (properties) 을 하나 이상의 객체를 대상으로 객체에는 İç 열거 소스.

[자세히.] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)

Polyfill 지원할 수 있는 오래된 브라우저:

if (!Object.assign) {
  Object.defineProperty(Object, 'assign', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(target) {
      'use strict';
      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert first argument to object');
      }

      var to = Object(target);
      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i];
        if (nextSource === undefined || nextSource === null) {
          continue;
        }
        nextSource = Object(nextSource);

        var keysArray = Object.keys(nextSource);
        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    }
  });
}
해설 (9)

코드:

// extends 'from' object with members from 'to'. If 'to' is null, a deep clone of 'from' is returned
function extend(from, to)
{
    if (from == null || typeof from != "object") return from;
    if (from.constructor != Object && from.constructor != Array) return from;
    if (from.constructor == Date || from.constructor == RegExp || from.constructor == Function ||
        from.constructor == String || from.constructor == Number || from.constructor == Boolean)
        return new from.constructor(from);

    to = to || new from.constructor();

    for (var name in from)
    {
        to[name] = typeof to[name] == "undefined" ? extend(from[name], null) : to[name];
    }

    return to;
}

테스트:

var obj =
{
    date: new Date(),
    func: function(q) { return 1 + q; },
    num: 123,
    text: "asdasd",
    array: [1, "asd"],
    regex: new RegExp(/aaa/i),
    subobj:
    {
        num: 234,
        text: "asdsaD"
    }
}

var clone = extend(obj);
해설 (8)

이게 I& # 39, m 사용:

function cloneObject(obj) {
    var clone = {};
    for(var i in obj) {
        if(typeof(obj[i])=="object" && obj[i] != null)
            clone[i] = cloneObject(obj[i]);
        else
            clone[i] = obj[i];
    }
    return clone;
}
해설 (5)
  • 깊이형 복제본에 performance:* 의해 세계 에서 가장 최악의
  • = &quot 재지정 "; (구체화하십시오 어레이에는 번호임 어레이에는 - 어레이만)
  • 슬라이스에 (구체화하십시오 어레이에는 번호임 어레이에는 - 어레이만)
  • 연결 (구체화하십시오 어레이에는 번호임 어레이에는 - 어레이만)
  • 사용자 정의 함수. 복제본에 for 루프는) 또는 반복
  • jQuery& 오레스테드 s $ # 39.
  • 제슨스파스 (구체화하십시오 어레이에는 번호임 어레이에는 객체에는 어레이에는 - 어레이만)
  • 언더스코엘가이스 & # 39 의 _.clone (구체화하십시오 어레이에는 번호임 어레이에는 - 어레이만)

    39 의 _.cloneDeep Lo-Dash& -

  • 문자열이나 숫자 배열입니다 깊이형 복제본에 (한 단계 - 아니 참조 포인터) *

어레이에서는 번호와 같은 기능을 포함하고 있을 때, 이콩카트 문장열 이슬리스 () (), 대입 연산자 (), 오스플리스 &quot &quot Underscore.js& # 39 의, 함수, 클론, 및, = 발쿰치로 깊은 복제본이므로 array& # 39 의 원소.

여기서 가장 빠른 성능을 재지정 있다.

var arr1 = ['a', 'b', 'c'];
var arr2 = arr1;
arr1 = ['a', 'b', 'c'];

및 이슬리스 () 에 비해 성능이 우수한 이콩카트 (), http://jsperf.com/duplicate-array-slice-vs-concat/3

var arr1 = ['a', 'b', 'c'];  // Becomes arr1 = ['a', 'b', 'c']
var arr2a = arr1.slice(0);   // Becomes arr2a = ['a', 'b', 'c'] - deep copy
var arr2b = arr1.concat();   // Becomes arr2b = ['a', 'b', 'c'] - deep copy
  • 깊이형 복제본에 객체에는 배열입니다 (두 개 이상의 수준을 - 참조 포인터) *
var arr1 = [{object:'a'}, {object:'b'}];

쓰기 사용자 정의 함수 () 는 보다 빠른 성능을 $ 오레스테드 () 또는 제슨스파스):

function copy(o) {
   var out, v, key;
   out = Array.isArray(o) ? [] : {};
   for (key in o) {
       v = o[key];
       out[key] = (typeof v === "object" && v !== null) ? copy(v) : v;
   }
   return out;
}

copy(arr1);

타사 유틸리티를 사용하여 기능:

$.extend(true, [], arr1); // Jquery Extend
JSON.parse(arr1);
_.cloneDeep(arr1); // Lo-dash

여기서 jQuery& 오레스테드, s $ # 39 는 성능 향상:

해설 (6)
var clone = function() {
    var newObj = (this instanceof Array) ? [] : {};
    for (var i in this) {
        if (this[i] && typeof this[i] == "object") {
            newObj[i] = this[i].clone();
        }
        else
        {
            newObj[i] = this[i];
        }
    }
    return newObj;
}; 

Object.defineProperty( Object.prototype, "clone", {value: clone, enumerable: false});
해설 (1)

인질상황이 [라이브러리 (일명 "클론")] (https://github.com/pvorb/node-clone) 가 이 꽤 잘. 또한 임의의 재귀 클론한 제가 알기로는 객체에는 가장 완벽한 복사 / 또 다른 이는 아직 답을 汲摹窍妨绰 사용순환 참조입니다 적용되지 않습니다.

[찾아 켜짐이 고궁박물원] 수 있습니다 (https://npmjs.org/package/clone) 도. 물론 노엘가이스트 브라우저를 사용할 수 있습니다

예를 들어보겠습니다 on how to use it.

또한 설치

npm install clone

it 와 [청산] 또는 패키지 (https://github.com/ender-js/Ender).

ender build clone [...]

소스 코드를 직접 다운로드할 수도 있습니다.

다음 소스 코드의 사용할 수 있습니다.

var clone = require('clone');

var a = { foo: { bar: 'baz' } };  // inital value of a
var b = clone(a);                 // clone a -> b
a.foo.bar = 'foo';                // change a

console.log(a);                   // { foo: { bar: 'foo' } }
console.log(b);                   // { foo: { bar: 'baz' } }

(부인: 난 작성자입니다 라이브러리란.)

해설 (4)

이것은 오래된 그러니까말이야 생각해봤죠 도움을 줄 수 있지만, 이 후 다음 사람을 따라 한단다.

As long as you don& 할당할지 아무것도 없는 메모리에 저장되어 있습니다 t # 39, 객체가 참조. 동시에 공유할 수 있도록 만드는 보기할 객체에는 you& # 39 와 같은 다른 객체, ll 작성해야 할 팩터리의 있습니다.

var a = function(){
    return {
        father:'zacharias'
    };
},
b = a(),
c = a();
c.father = 'johndoe';
alert(b.father);
해설 (5)

'항상' 는 객체가 클로닝 (cloning) 에 대한 모든 일이 js, 그 당시 내가 전에 다른 방식으로 javascript 객체 복사 es6 목록 아래 있습니다 싶은 것을 아래 객체에는 투명지에 깊이형 복제본입니다 다음과 같이 밝혔다:

var obj = {a:1, b:2, c:3, d:4};

이 객체를 변경하지 않고 몇 가지 방법을 복제본에 출처:

  1. 할 수 있는 간단한 함수를 사용하여 ES5+ 복제본에 당신꺼에요:
function deepCopyObj(obj) {
    if (null == obj || "object" != typeof obj) return obj;
    if (obj instanceof Date) {
        var copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
    }
    if (obj instanceof Array) {
        var copy = [];
        for (var i = 0, len = obj.length; i < len; i++) {
            copy[i] = cloneSO(obj[i]);
        }
        return copy;
    }
    if (obj instanceof Object) {
        var copy = {};
        for (var attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = cloneSO(obj[attr]);
        }
        return copy;
    }
    throw new Error("Unable to copy obj this object.");
}
  1. 및 제슨.스트린그리피스 ES5+ 제슨스파스 사용하여
var  deepCopyObj = JSON.parse(JSON.stringify(obj));
  1. 앙굴라이스:
var  deepCopyObj = angular.copy(obj);
  1. 포함한다.
var deepCopyObj = jQuery.extend(true, {}, obj);
  1. 언더스코레이스 &amp. 로다시:
var deepCopyObj = _.cloneDeep(obj); //latest version UndescoreJs makes shallow copy

이러한 희망을 움말.

해설 (9)

39 이 사용하는 경우, re you& 라이브러리마다 언더스코엘가이스 는 [클론할] [2] 메서드입니다.

var newObject = _.clone(oldObject);

[2]: http://documentcloud.github.com/underscore/ # 클론할

해설 (3)
  • 깊이형 JavaScript 객체 복사 (생쥐라. (the best and 가장 간단한) *

1. 제슨스파스 사용하여 (제슨.스트린그리피 (객체));

var obj = { 
  a: 1,
  b: { 
    c: 2
  }
}
var newObj = JSON.parse(JSON.stringify(obj));
obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 2 } } 
  • *2.using 생성되는가 방법
function cloneObject(obj) {
    var clone = {};
    for(var i in obj) {
        if(obj[i] != null &&  typeof(obj[i])=="object")
            clone[i] = cloneObject(obj[i]);
        else
            clone[i] = obj[i];
    }
    return clone;
}

var obj = { 
  a: 1,
  b: { 
    c: 2
  }
}
var newObj = cloneObject(obj);
obj.b.c = 20;

console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 2 } } 

3. # 39 을 사용하여 Lo-Dash& _.cloneDeep 링크 [로다시] [1]

var obj = { 
  a: 1,
  b: { 
    c: 2
  }
}

var newObj = _.cloneDeep(obj);
obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 2 } } 

4. 오브ject.라시니 () 메서드를 사용하여

var obj = { 
  a: 1,
  b: 2
}

var newObj = _.clone(obj);
obj.b = 20;
console.log(obj); // { a: 1, b: 20 }
console.log(newObj); // { a: 1, b: 2 }  
  • 그러나 잘못된 때 *
var obj = { 
  a: 1,
  b: { 
    c: 2
  }
}

var newObj = Object.assign({}, obj);
obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 20 } } --> WRONG
// Note: Properties on the prototype chain and non-enumerable properties cannot be copied.
  • *5.using 언더스코엘가이스 _.clone 링크 [언더스코엘가이스] [2]
var obj = { 
  a: 1,
  b: 2
}

var newObj = _.clone(obj);
obj.b = 20;
console.log(obj); // { a: 1, b: 20 }
console.log(newObj); // { a: 1, b: 2 }  
  • 그러나 잘못된 때 *
var obj = { 
  a: 1,
  b: { 
    c: 2
  }
}

var newObj = _.cloneDeep(obj);
obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 20 } } --> WRONG
// (Create a shallow-copied clone of the provided plain object. Any nested objects or arrays will be copied by reference, not duplicated.)

참조 medium.com

[1]: https://lodash.com/docs/4.17.10 # 클로네딥 [2]: https://underscorejs.org/ # 클론할

해설 (3)

39, s, s # 39 위에 오토메이티드 ConroyP& here& 버전을 사용할 수 있는 경우에도 구성자를 필요한 매개변수입니다 있다.

//If Object.create isn't already defined, we just do the simple shim,
//without the second argument, since that's all we need here
var object_create = Object.create;
if (typeof object_create !== 'function') {
    object_create = function(o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

function deepCopy(obj) {
    if(obj == null || typeof(obj) !== 'object'){
        return obj;
    }
    //make sure the returned object has the same prototype as the original
    var ret = object_create(obj.constructor.prototype);
    for(var key in obj){
        ret[key] = deepCopy(obj[key]);
    }
    return ret;
}

이 기능은 내 심프레토 라이브러리를 사용할 수도 있습니다.

  • Edit:*

39 의 here& 보다 강력한 버전 (저스틴 매클랜드리스 덕분에 이 는 이제 아니라 순환 참조).

/**
 * Deep copy an object (make copies of all its object properties, sub-properties, etc.)
 * An improved version of http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
 * that doesn't break if the constructor has required parameters
 * 
 * It also borrows some code from http://stackoverflow.com/a/11621004/560114
 */ 
function deepCopy(src, /* INTERNAL */ _visited, _copiesVisited) {
    if(src === null || typeof(src) !== 'object'){
        return src;
    }

    //Honor native/custom clone methods
    if(typeof src.clone == 'function'){
        return src.clone(true);
    }

    //Special cases:
    //Date
    if(src instanceof Date){
        return new Date(src.getTime());
    }
    //RegExp
    if(src instanceof RegExp){
        return new RegExp(src);
    }
    //DOM Element
    if(src.nodeType && typeof src.cloneNode == 'function'){
        return src.cloneNode(true);
    }

    // Initialize the visited objects arrays if needed.
    // This is used to detect cyclic references.
    if (_visited === undefined){
        _visited = [];
        _copiesVisited = [];
    }

    // Check if this object has already been visited
    var i, len = _visited.length;
    for (i = 0; i < len; i++) {
        // If so, get the copy we already made
        if (src === _visited[i]) {
            return _copiesVisited[i];
        }
    }

    //Array
    if (Object.prototype.toString.call(src) == '[object Array]') {
        //[].slice() by itself would soft clone
        var ret = src.slice();

        //add it to the visited array
        _visited.push(src);
        _copiesVisited.push(ret);

        var i = ret.length;
        while (i--) {
            ret[i] = deepCopy(ret[i], _visited, _copiesVisited);
        }
        return ret;
    }

    //If we've reached here, we have a regular object

    //make sure the returned object has the same prototype as the original
    var proto = (Object.getPrototypeOf ? Object.getPrototypeOf(src): src.__proto__);
    if (!proto) {
        proto = src.constructor.prototype; //this line would probably only be reached by very old browsers 
    }
    var dest = object_create(proto);

    //add this object to the visited array
    _visited.push(src);
    _copiesVisited.push(dest);

    for (var key in src) {
        //Note: this does NOT preserve ES5 property attributes like 'writable', 'enumerable', etc.
        //For an example of how this could be modified to do so, see the singleMixin() function
        dest[key] = deepCopy(src[key], _visited, _copiesVisited);
    }
    return dest;
}

//If Object.create isn't already defined, we just do the simple shim,
//without the second argument, since that's all we need here
var object_create = Object.create;
if (typeof object_create !== 'function') {
    object_create = function(o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}
해설 (0)

다음 두 개의 동일한 객체에는 인스턴스를 만듭니다. I found it 및 사용하고 현재는. # 39 의 it& 간단하고 쉽게 사용할 수 있습니다.

var objToCreate = JSON.parse(JSON.stringify(cloneThis));
해설 (6)

좋은 로다시 있다 [_.cloneDeep (가치)] (http://lodash.com/docs # 클로네딥) 방법:

var objects = [{ 'a': 1 }, { 'b': 2 }];

var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
해설 (4)

제안됩니다 크록 포드 (쉐퍼드도 포지셔닝하십시오) 이 기능을 사용하여:

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

var newObject = object(oldObject);

39 의 작동 it& 간결한 예상대로 진실이며당신이 don& # 39, 라리브러리 필요한 건 아니다.

  • EDIT:*

이 때문에 이 또한 '는 "에 대한 폴리필 오브ject.크레이트 사용할 수 있습니다.

var newObject = Object.create(oldObject);
  • NOTE:* 사용할 경우 일부 이터레이션에 해스운프로페티 '를 사용하고 있는' 이 중 일부 문제가 발생할 수도 있습니다. 만들기 ',' '누가 새로 만들기 때문에 빈 객체에는 상속됩니다 올도비치'. 하지만 여전히 유용한 실용적인 클론하는 객체에는.

',' 의 경우 이상플레 올도비치리아 = 5

newObject.a; // is 5

하지만.

oldObject.hasOwnProperty(a); // is true
newObject.hasOwnProperty(a); // is false
해설 (6)
function clone(obj)
 { var clone = {};
   clone.prototype = obj.prototype;
   for (property in obj) clone[property] = obj[property];
   return clone;
 }
해설 (5)