>  기사  >  웹 프론트엔드  >  js 배열 및 객체의 깊은 복사본과 얕은 복사본에 대한 자세한 설명

js 배열 및 객체의 깊은 복사본과 얕은 복사본에 대한 자세한 설명

小云云
小云云원래의
2018-02-01 09:03:401365검색

이 글은 주로 js의 배열과 객체의 깊고 얕은 복사본을 자세히 소개합니다. 관심 있는 친구들이 참고할 수 있기를 바랍니다.

전제: 값을 할당할 때 원시 데이터 유형과 객체 유형의 차이점 ​​

자바스크립트 데이터 유형은 원시 데이터 유형과 객체 유형으로 구분됩니다. 둘은 메모리에 서로 다른 방식으로 저장되므로 할당에 차이가 있습니다. 밤을 각각 가져가자


var x = 1;
 var y = x; //y获得了和x同样的值
 y = 2;
 console.log(x); // 1

 var m = [1,2]; //m存放的是指向[1,2]这个数组对象的引用地址
 var n = m; //n也获得 [1,2]数组对象的引用地址
 n[0] = 3;
 console.log(m); //[3,2]

위의 밤에서 알 수 있듯이 원래 데이터 유형을 할당하면 실제 데이터 값이 할당되고 나면 둘은 동일한 값이므로 영향을 미치지 않습니다. 객체 유형은 원본 데이터의 참조 주소를 제공하므로 Shangli의 배열과 같이 본질적으로 동일한 데이터 객체이기 때문에 이전 데이터와 새 데이터가 서로 영향을 미칩니다. 복사?

이름에서 알 수 있듯이 얕은 복사는 속성 값이 객체 유형인 경우 객체 데이터에 대한 참조만 복사되므로 이전 데이터와 새 데이터가 완전히 분리되지 않고 각각에 영향을 미칩니다. 다른. 다른 예를 들어보세요...

//测试数据
var array1 = ['a',1,true,{name:'lei',age:18}];
 
//concat() slice() 实现浅拷贝
var array2 = array1.concat()
 
//修改拷贝后的数据
array2[0] = 'b';      //array1[0]是原始数据类型 所以是直接赋值的
array2[3].name = 'zhang';  //array1[3]是对象数据类型 所以拷贝的是对象的引用,其实还是和原数组使用同一对象
 
console.log(array1);  // ['a',1,true,{name:'zhang',age:18}]

이 예에서 array2는 array1의 얕은 복사본 개체입니다. 배열 요소는 원래 데이터 유형이고 서로 영향을 미치지 않지만(array1[0]) array1[3] ]는 객체 유형이지만 여전히 서로 영향을 미칩니다.

얕은 복사본을 구현하는 방법


Shangli의 Array.concat() 또는 array.slice()는 배열의 얕은 복사본을 구현하는 특별한 방법입니다.

직접 구현하는 방법은 무엇인가요? 객체/배열의 각 속성을 순회한 다음 이를 새 객체에 할당하는 것만으로도 충분하지 않을까요? 구현은 다음과 같습니다


 //实现浅拷贝
 function shallowCopy( target ){
  if(typeof target !== 'object') return ;
  //判断目标类型,来创建返回值
  var newObj = target instanceof Array ? [] : {};
 
  for(var item in target){
   //只复制元素自身的属性,不复制原型链上的
   if(target.hasOwnProperty(item)){
    newObj[item] = target[item]
   }
  }
 
  return newObj
 }</strong>
 
 //测试
 
 var test = [1,&#39;a&#39;,{name:&#39;lei&#39;,age:18}];
 
 var copy = shallowCopy(test);
 console.log(copy[2].name);  //lei
 
 copy[2].name = &#39;zhang&#39;;
 console.log(test[2].name);  //zhang  原数据也被修改


deep copy와 그 구현


Shallow Copy에서 설명을 보면 기본적으로 딥 카피는 '완전한' 복사본이라고 이해할 수 있습니다. 복사 후에는 이전 데이터와 새 데이터가 완전히 분리되어 더 이상 객체 유형의 속성 값을 공유하지 않으며 서로 영향을 미치지 않습니다.

구현 방법:

까다로운 방법 JSON.parse(JSON.stringify(Obj))


var test = [1,&#39;a&#39;,{name:&#39;lei&#39;,age:18}]; 
var copy1 = JSON.parse(JSON.stringify(test)); //特殊方式 
console.log(copy1); 
copy1[2].name = &#39;zhang&#39;
console.log(test);  //[1,&#39;a&#39;,{name:&#39;lei&#39;,age:18}] 未受到影响

참고: 이 방법은 속성 값이 함수인 개체를 완전 복사할 수 없습니다.

2. Deep Copy 구현

얕은 복사를 구현했는데, 생각해 보면 객체 유형 속성 값을 할당할 때 결과가 완전히 분리되지 않는 것으로 보입니다. 따라서 객체 유형 속성을 복사하는 방식을 수정해야 합니다. 값을 다시 호출하여 깊은 복사를 실현합니다.

//实现深拷贝
function deepCopy( target ){
 if(typeof target !== &#39;object&#39;) return ;
 //判断目标类型,来创建返回值
 var newObj = target instanceof Array ? [] : {};
 
 for(var item in target){
  //只复制元素自身的属性,不复制原型链上的
  if(target.hasOwnProperty(item)){
   newObj[item] = <strong>typeof target[item] == &#39;object&#39; ? deepCopy(target[item]) : target[item] //判断属性值类型
</strong>  }
 }
 
 return newObj
}
 
//测试
var test = [1,&#39;a&#39;,{name:&#39;lei&#39;,age:18}];
 
var copy2 = deepCopy(test);
copy2[2].name = &#39;zhang&#39;
 
console.log(test); ////[1,&#39;a&#39;,{name:&#39;lei&#39;,age:18}] 未受到影响


Summary

얕은 복사의 이유를 이해하세요. 객체 유형 데이터를 복사할 때 참조 주소는 복사되지만 동일한 데이터 객체가 계속 사용됩니다. 따라서 딥 카피를 구현하는 방법은 직접 할당을 피하기 위해 객체 유형 속성 값을 재귀적으로 딥 복사하는 것입니다.

관련 권장사항:

JQuery의 $.extend 얕은 복사 및 전체 복사 예제 분석

js 전체 복사 및 얕은 복사란 무엇이며 구현 방법

jquery에서 전체 복사 및 얕은 복사 구현

위 내용은 js 배열 및 객체의 깊은 복사본과 얕은 복사본에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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