>  기사  >  웹 프론트엔드  >  js에서 얕은 복사와 깊은 복사를 구현하는 방법은 무엇입니까? (요약)

js에서 얕은 복사와 깊은 복사를 구현하는 방법은 무엇입니까? (요약)

不言
不言원래의
2018-09-18 14:58:227765검색

이 기사에서는 js에서 얕은 복사와 깊은 복사를 구현하는 방법에 대해 설명합니다. (요약) 도움이 필요한 친구들이 참고할 수 있을 만큼 참고할만한 가치가 있습니다.

js에는 문자열, 숫자, 부울, null, undefind의 다섯 가지 기본 데이터 유형이 있습니다. 이 다섯 가지 유형의 할당은 가치 이전입니다. 객체 할당은 객체 주소에 대한 참조를 할당하는 것입니다. 이때, 객체의 속성이나 값을 수정하면 해당 객체에 대한 모든 참조의 값이 변경됩니다. 객체에 대한 참조를 복사하는 대신 새 객체를 실제로 복사하려면 객체의 전체 복사본을 사용해야 합니다.

얕은 복사 구현

1. '=' 할당.

말할 것도 없이 가장 기본적인 할당 방법은 객체에 대한 참조를 할당하는 것입니다.

2.Object.asset()

Object.Assign은 ES6의 새로운 함수입니다. Object.sign() 메서드는 소스 객체의 열거 가능한 속성 중 원하는 수를 대상 객체에 복사한 다음 대상 객체를 반환할 수 있습니다. 그러나 Object.sign()은 객체 자체가 아닌 객체의 속성에 대한 참조를 복사하는 단순 복사를 수행합니다.

Object.assign(target, ...sources)

매개변수:
target: 대상 개체.
소스: 소스 개체의 수.
반환값: 대상 객체가 반환됩니다.

var obj = { a: {a: "hello", b: 21} };
var initalObj = Object.assign({}, obj);

initalObj.a.a = "changed";
console.log(obj.a.a); // "changed"

주의해야 할 점:
Object.sign()은 다음과 같이 전체 복사 계층을 처리할 수 있습니다.

var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = Object.assign({}, obj1);
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 20, c: 30 } <-- 沒被改到
console.log(obj2);
// { a: 10, b: 100, c: 30 }

Deep copy

1. 문자열 변환을 위한 수동 복사

var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 20, c: 30 } <-- 沒被改到
console.log(obj2);
// { a: 10, b: 100, c: 30 }

2 JSON을 사용합니다. . stringify는 객체를 문자열로 변환한 다음 JSON.parse를 사용하여 문자열을 새 객체로 변환합니다.

var obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.body.a = 20;
console.log(obj1);
// { body: { a: 10 } } <-- 沒被改到
console.log(obj2);
// { body: { a: 20 } }
console.log(obj1 === obj2);
// false
console.log(obj1.body === obj2.body);
// false

이것이 진정한 Deep Copy입니다. 이 방법은 간단하고 사용하기 쉽습니다.

그러나 이 방법에는 많은 단점도 있습니다. 예를 들어 객체의 생성자를 삭제한다는 점입니다. 즉, 깊은 복사 후에는 객체의 원래 생성자가 무엇이든 상관없이 깊은 복사 후에는 객체가 됩니다.

이 메서드가 올바르게 처리할 수 있는 유일한 객체는 Number, String, Boolean, Array 및 flat 객체, 즉 json으로 직접 표현할 수 있는 데이터 구조입니다. RegExp 개체는 이런 방식으로 전체 복사될 수 없습니다.

즉, JSON 형식으로 변환할 수 있는 개체만 이 방식으로 사용할 수 있습니다.

var obj1 = { fun: function(){ console.log(123) } };
var obj2 = JSON.parse(JSON.stringify(obj1));
console.log(typeof obj1.fun);
// 'function'
console.log(typeof obj2.fun);
// 'undefined' <-- 没复制

3. 재귀 복사

function deepClone(initalObj, finalObj) {    
  var obj = finalObj || {};    
  for (var i in initalObj) {        
    var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
    if(prop === obj) {            
      continue;
    }        
    if (typeof prop === 'object') {
      obj[i] = (prop.constructor === Array) ? [] : {};            
      arguments.callee(prop, obj[i]);
    } else {
      obj[i] = prop;
    }
  }    
  return obj;
}
var str = {};
var obj = { a: {a: "hello", b: 21} };
deepClone(obj, str);
console.log(str.a);

4. Object.create() 메서드를 사용하세요

var newObj = Object.create(oldObj)를 직접 사용하여 전체 복사 효과를 얻으세요.

function deepClone(initalObj, finalObj) {    
  var obj = finalObj || {};    
  for (var i in initalObj) {        
    var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
    if(prop === obj) {            
      continue;
    }        
    if (typeof prop === 'object') {
      obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
    } else {
      obj[i] = prop;
    }
  }    
  return obj;
}

5.jquery

jquery는 Deep Copy에 사용할 수 있는 $.extend를 제공합니다.

var $ = require('jquery');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f);
// false

6. 타사 함수

lodash와 같은 딥 복사 기능을 갖춘 다른 타사 함수 라이브러리도 있습니다.

위 내용은 js에서 얕은 복사와 깊은 복사를 구현하는 방법은 무엇입니까? (요약)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.