얕은 복사본
얕은 복사본은 개체의 비트 단위 복사본입니다. 원본 개체의 값과 정확히 동일한 복사본을 갖는 새 개체를 만듭니다. 객체의 필드가 다른 객체에 대한 참조인 경우 참조 주소만 복사됩니다. 즉, 메모리 주소가 복사됩니다.
일반 언어에서 얕은 복사는 개체 주소의 복사본이며 새 스택을 열지 않습니다. 즉, 복사의 결과로 두 개체가 동일한 주소를 가리키게 됩니다. 한 개체의 속성을 수정하면 됩니다. 다른 개체의 속성도 변경됩니다.
Deep copy
Deep copy는 모든 필드를 복사하고 해당 필드가 가리키는 동적으로 할당된 메모리를 복사합니다. 전체 복사는 개체와 개체가 참조하는 개체가 복사될 때 발생합니다.
일반 언어에서 딥 카피는 새로운 스택을 엽니다. 두 객체는 두 개의 서로 다른 주소에 해당합니다. 한 객체의 속성을 수정해도 다른 객체의 속성은 변경되지 않습니다.
보기 예 보기
얕은 복사: X
의 참조를 Y
에 복사합니다. 따라서 X
와 Y
의 주소는 동일합니다. 이는 동일한 메모리 위치를 가리킨다는 의미입니다. X
的引用复制到Y
中。因此,X
和Y
的地址是相同的,也就是说它们指向相同的内存位置。
深拷贝:复制X
的所有成员,为Y
分配不同的内存位置,然后将复制的成员分配给Y
,实现深拷贝。这样,如果X
消失了,Y
在内存中仍然有效。
考虑下面的代码:
var employeeDetailsOriginal = { name: '前端小智', age: 18, Profession: '前端开发' };
假设你想创建一个这个对象的副本,这样即使原始值被改变了,仍然可以通过副本得到原始对象的值。
我会这样做:
var employeeDetailsDuplicate = employeeDetailsOriginal; // 浅拷贝
如果咱们改变一个值:
employeeDetailsDuplicate.name = '王大治';
这样操作,咱们的原始对象 employeeDetailsOriginal
的属性 name
也会跟着改变,因为这里是一个浅拷贝。这样咱们就获取不到原始对象的值了。所以这种拷贝做法是不对的。
但是,通过使用原始employeeDetailsOriginal
变量的属性创建一个全新的变量,就可以创建一个深拷贝副本。
var employeeDetailsDuplicate = { name: employeeDetailsOriginal.name, age: employeeDetailsOriginal.age, Profession: employeeDetailsOriginal.Profession }; // 深拷贝
现在,如果更改employeeDetailsDuplicate.name
,它只会影响employeeDetailsDuplicate
,而不会影响employeeDetailsOriginal
。
谈谈 Object.assign()
Object.assign()
是咱们经常用到的方法,其实这个方法就是浅拷贝。但是它又有一点特殊的地方,就是可以处理第一层的深拷贝。
var employeeDetailsOriginal = { name: '前端小智', family: { name: '前端大家庭' } }; var employeeDetailsDuplicate = Object.assign({}, employeeDetailsOriginal ); employeeDetailsDuplicate.name = '王大治' employeeDetailsDuplicate.family.name = '后端大家庭' console.log(employeeDetailsOriginal ); // { name: "前端小智", family: {name: "后端大家庭"} } console.log(employeeDetailsDuplicate); // { name: "王大冶智", family: {name: "后端大家庭"} }
看上面的例子,属性name
的值并没有跟着变,但是属性中family
的name
X
의 모든 멤버를 복사하고 Y
에 다른 메모리 위치를 할당한 다음 복사된 멤버를 Y
에 할당하여 Deep 구현 복사. 이렇게 하면 X
가 사라지더라도 Y
는 메모리에서 여전히 유효합니다. 다음 코드를 고려해보세요. 对于简单的JSON对象,最简单的方法是
var objectIsNew = JSON.parse(JSON.stringify(objectIsOld));
//如果使用jQuery,可以使用:
// 浅拷贝
var objectIsNew = jQuery.extend({}, objectIsOld);
// 深拷贝
var objectIsNew = jQuery.extend(true, {}, objectIsOld);
원래 값이 변경되더라도 복사본을 통해 원래 개체의 값을 계속 얻을 수 있도록 이 개체의 복사본을 만들고 싶다고 가정해 보겠습니다.
function keepCloning(objectpassed) { if (objectpassed=== null || typeof objectpassed!== 'object') { return objectpassed; } // 临时存储原始的obj的构造 var temporary_storage = objectpassed.constructor(); for (var key in objectpassed) { temporary_storage[key] = keepCloning(objectpassed[key]); } return temporary_storage; } var employeeDetailsOriginal = { name: '前端小智', age: 18, Profession: '前端开发' }; var employeeDetailsDuplicate = (keepCloning(employeeDetailsOriginal)); employeeDetailsOriginal.name = "前端大治"; console.log(employeeDetailsOriginal); console.log(employeeDetailsDuplicate);값을 변경하면:
rrreee
이런 식으로 원래 개체employeeDetailsOriginal
의 name
속성도 변경됩니다. 왜냐하면 여기 얕은 사본이 있습니다. 이런 식으로는 원래 객체의 가치를 얻을 수 없습니다. 따라서 이 복사 관행은 잘못된 것입니다. 그러나 원본 employeeDetailsOriginal
변수의 속성을 사용하여 완전히 새로운 변수를 생성하면 전체 복사본을 생성할 수 있습니다. rrreee이제 employeeDetailsDuplicate.name
을 변경하면 employeeDetailsDuplicate
에만 영향을 미치고 employeeDetailsOriginal
에는 영향을 미치지 않습니다.
Object.sign()에 대해 이야기
Object.sign()
은 우리가 자주 사용하는 메서드입니다. 사실 이 메서드는 얕습니다. 복사 . 하지만 여기에는 특별한 것이 있습니다. 즉, 첫 번째 레이어의 전체 복사본을 처리할 수 있다는 것입니다.
name
속성의 값은 변경되지 않았지만 family
속성의 name
값은 변경되었습니다. 변경되었습니다. 🎜🎜🎜🎜전체 복사 구현 방법🎜🎜🎜🎜유일한 방법은 이 개체를 복제하는 것입니다. 🎜rrreee🎜객체 딥 카피에 대한 순수 JS 방법 (최고의 방법은 아님)🎜rrreee🎜🎜🎜요약🎜🎜🎜🎜딥 카피를 이해하는 것은 인터뷰 질문에 대처하는 것뿐만 아니라 실제 개발에도 매우 유용합니다. 예를 들어, 한 묶음의 데이터가 백그라운드에서 반환되는데, 이 묶음의 데이터에 대해 작업을 수행해야 하지만, 다중 사용자 개발의 경우 이 데이터 묶음이 다른 기능을 가지고 있는지 알 방법이 없습니다. 직접 수정하면 숨겨진 문제가 발생할 수 있으므로 실제 상황에 맞게 복사하면 데이터를 보다 안전하게 운영할 수 있다는 뜻일 것입니다. 🎜🎜이 기사는 다음에서 복제되었습니다: https://segmentfault.com/a/1190000020438346🎜🎜권장 관련 튜토리얼: 🎜JavaScript 비디오 튜토리얼🎜🎜위 내용은 JS의 Deep Copy와 Shallow Copy에 대해 알아봅시다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!