딥 카피의 세 가지 구현 방법은 다음과 같습니다. 1. 모든 계층적 속성을 재귀적으로 복사합니다. 2. JSON 객체의 구문 분석 및 문자열화를 사용합니다. 3. JQ의 확장 방법을 차용합니다.
딥 카피의 세 가지 구현 방법은 다음과 같습니다.
1, 모든 레벨 속성을 복사하는 재귀 재귀
function deepClone(obj){ let objClone = Array.isArray(obj)?[]:{}; if(obj && typeof obj==="object"){ for(key in obj){ if(obj.hasOwnProperty(key)){ //判断ojb子元素是否为对象,如果是,递归复制 if(obj[key]&&typeof obj[key] ==="object"){ objClone[key] = deepClone(obj[key]); }else{ //如果不是,简单复制 objClone[key] = obj[key]; } } } } return objClone; } let a=[1,2,3,4], b=deepClone(a); a[0]=2; console.log(a,b);
이제 b는 a의 제어를 벗어납니다. 더 이상 a의 영향을 받지 않습니다.
딥 카피는 객체의 각 레벨의 속성을 복사하는 것임을 다시 한 번 강조합니다. JQ에는 객체를 복사할 수도 있는 확장 메소드가 있습니다. 살펴보겠습니다
let a=[1,2,3,4], b=a.slice(); a[0]=2; console.log(a,b);
그러면 슬라이스 메소드도 결국에는 a의 영향을 받지 않는다는 뜻인가요? 이 예에서는 모든 수준의 속성이 여전히 복사됩니다. a를
let a=[0,1,[2,3],4], b=a.slice(); a[0]=1; a[2][0]=1; console.log(a,b);
로 변경했지만 복사가 완료되지 않았습니다. 객체 b의 첫 번째 수준 속성은 실제로 영향을 받지 않지만 두 번째 수준 속성은 여전히 유지됩니다. 성공적으로 복사되지 않았으며 여전히 분리되어 있습니다. a의 제어가 없으면 슬라이스가 실제 전체 복사가 아님을 의미합니다.
다음은 Zhihu Q&A
에 있는 사진의 인용문입니다.
첫 번째 레이어의 속성은 실제로 딥 카피되어 독립적인 메모리를 가지고 있지만 더 깊은 속성은 여전히 동일한 주소를 공유하므로 위의 문제가 발생합니다. .
마찬가지로 concat 방법과 슬라이스도 이러한 상황이 있습니다. 여기서는 주의할 필요가 있습니다.
2. 재귀 외에도 JSON 객체의 구문 분석 및 문자열화를 빌릴 수도 있습니다
function deepClone(obj){ let _obj = JSON.stringify(obj), objClone = JSON.parse(_obj); return objClone } let a=[0,1,[2,3],4], b=deepClone(a); a[0]=1; a[2][0]=1; console.log(a,b);
이제 b는 a의 영향을 전혀 받지 않는다는 것을 알 수 있습니다.
그런데, 전체 복사 구현 외에도 JSON.stringify 및 JSON.parse를 localStorage와 결합하여 객체 배열 저장소를 구현할 수도 있습니다. 관심이 있으시면 블로거가 작성한 이 기사를 읽어보세요.
localStorage는 배열, 객체, localStorage, sessionStorage는 배열 객체를 저장합니다
3. 위의 두 가지 메소드 외에도 JQ의 확장 메소드를 빌릴 수 있습니다.
$.extend( [deep ], target, object1 [, objectN ] )
deep은 deep copy인지를 나타내며, true이면 deep copy이고, true이면 deep copy입니다. false, 얕은 복사본입니다
target Object 유형 대상 개체인 경우 다른 개체의 구성원 속성이 이 개체에 첨부됩니다.
object1 objectN선택 사항입니다. 객체 유형 첫 번째와 N번째 병합된 객체입니다.
let a=[0,1,[2,3],4], b=$.extend(true,[],a); a[0]=1; a[2][0]=1; console.log(a,b);
위 방법과 효과는 동일하지만 JQ 라이브러리에 의존해야 함을 알 수 있습니다.
말씀드렸지만 Deep Copy를 이해하는 것은 면접 질문에 대처하는 것뿐만 아니라 실제 개발에도 매우 유용합니다. 예를 들어, 한 묶음의 데이터가 백그라운드에서 반환되는데, 이 묶음의 데이터에 대해 작업을 수행해야 하지만, 다중 사용자 개발의 경우 이 데이터 묶음이 다른 기능을 가지고 있는지 알 방법이 없습니다. 직접 수정하면 숨겨진 문제가 발생할 수 있으므로 실제 상황에 맞게 복사하면 데이터를 보다 안전하게 운영할 수 있다는 뜻일 것입니다.
4.lodash의 _.cloneDeep()
다음은 제가 읽은 딥 카피 문제에 대한 해결 방법입니다.
JSON.parse
먼저 객체를 json 객체로 변환하세요. 그런 다음 이 json 객체를 구문 분석합니다.
let obj = {a:{b:22}};let copy = JSON.parse(JSON.stringify(obj));
이 방법의 장점은 코드 작성이 비교적 간단하다는 것입니다. 하지만 단점도 분명합니다. 먼저 임시적이고 큰 문자열을 만든 다음 이를 파서에 다시 넣습니다. 또 다른 단점은 이 방법이 순환 객체를 처리할 수 없다는 것입니다.
이 방법을 사용할 때 다음 루프 객체는 예외를 발생시킵니다.
let a = {};let b = {a};a.b = b;let copy = JSON.parse(JSON.stringify(a));
Map, Set, RegExp, Date, ArrayBuffer 및 기타 내장 유형은 직렬화 중에 손실됩니다.
let a = {};let b = new Set();b.add(11);a.test = b;let copy = JSON.parse(JSON.stringify(a));
a의 값은 다음과 같이 출력됩니다
copy的值打印如下
对比发现,Set已丢失。
Structured Clone 结构化克隆算法
MessageChannel
建立两个端,一个端发送消息,另一个端接收消息。
function structuralClone(obj) { return new Promise(resolve =>{ const {port1, port2} = new MessageChannel(); port2.onmessage = ev => resolve(ev.data); port1.postMessage(obj); }) } const obj = /* ... */; structuralClone(obj).then(res=>{ console.log(res); })
这种方法的优点就是能解决循环引用的问题,还支持大量的内置数据类型。缺点就是这个方法是异步的。
History API
利用history.replaceState。这个api在做单页面应用的路由时可以做无刷新的改变url。这个对象使用结构化克隆,而且是同步的。但是我们需要注意,在单页面中不要把原有的路由逻辑搞乱了。所以我们在克隆完一个对象的时候,要恢复路由的原状。
function structuralClone(obj) { const oldState = history.state; history.replaceState(obj, document.title); const copy = history.state; history.replaceState(oldState, document.title); return copy; }var obj = {};var b = {obj}; obj.b = bvar copy = structuralClone(obj); console.log(copy);
这个方法的优点是。能解决循环对象的问题,也支持许多内置类型的克隆。并且是同步的。但是缺点就是有的浏览器对调用频率有限制。比如Safari 30 秒内只允许调用 100 次
Notification API
这个api主要是用于桌面通知的。如果你使用Facebook的时候,你肯定会发现时常在浏览器的右下角有一个弹窗,对就是这家伙。我们也可以利用这个api实现js对象的深拷贝。
function structuralClone(obj) { return new Notification('', {data: obj, silent: true}).data; }var obj = {};var b = {obj}; obj.b = bvar copy = structuralClone(obj); console.log(copy)
同样是优点和缺点并存,优点就是可以解决循环对象问题,也支持许多内置类型的克隆,并且是同步的。缺点就是这个需要api的使用需要向用户请求权限,但是用在这里克隆数据的时候,不经用户授权也可以使用。在http协议的情况下会提示你再https的场景下使用。
lodash的_.cloneDeep()
支持循环对象,和大量的内置类型,对很多细节都处理的比较不错。推荐使用。
支持的类型有很多
我们这里再次关注一下lodash是如何解决循环应用这个问题的?
从相关的代码中。我们可以发现。lodash是用一个栈记录了。所有被拷贝的引用值。如果再次碰到同样的引用值的时候,不会再去拷贝一遍。而是利用之前已经拷贝好的值。
实现一个简易点的深拷贝,以解决循环引用的问题为目标
我们仅仅实现一个简易点的深拷贝。能优雅的处理循环引用的即可。在实现深拷贝之前,我们首先温习回顾一下js中的遍历对象的属性的方法和各种方法的优缺点。
js中遍历一个对象的属性的方法
- Object.keys() 仅仅返回自身的可枚举属性,不包括继承来的,更不包括Symbol属性
- Object.getOwnPropertyNames() 返回自身的可枚举和不可枚举属性。但是不包括Symbol属性
- Object.getOwnPropertySymbols() 返回自身的Symol属性
- for...in 可以遍历对象的自身的和继承的可枚举属性,不包含Symbol属性
- Reflect.ownkeys() 返回对象自身的所有属性,不管是否可枚举,也不管是否是Symbol。注意不包括继承的属性
实现深拷贝,解决循环引用问题
/** * 判断是否是基本数据类型 * @param value */function isPrimitive(value){ return (typeof value === 'string' || typeof value === 'number' || typeof value === 'symbol' || typeof value === 'boolean') }/** * 判断是否是一个js对象 * @param value */function isObject(value){ return Object.prototype.toString.call(value) === "[object Object]"}/** * 深拷贝一个值 * @param value */function cloneDeep(value){ // 记录被拷贝的值,避免循环引用的出现 let memo = {}; function baseClone(value){ let res; // 如果是基本数据类型,则直接返回 if(isPrimitive(value)){ return value; // 如果是引用数据类型,我们浅拷贝一个新值来代替原来的值 }else if(Array.isArray(value)){ res = [...value]; }else if(isObject(value)){ res = {...value}; } // 检测我们浅拷贝的这个对象的属性值有没有是引用数据类型。如果是,则递归拷贝 Reflect.ownKeys(res).forEach(key=>{ if(typeof res[key] === "object" && res[key]!== null){ //此处我们用memo来记录已经被拷贝过的引用地址。以此来解决循环引用的问题 if(memo[res[key]]){ res[key] = memo[res[key]]; }else{ memo[res[key]] = res[key]; res[key] = baseClone(res[key]) } } }) return res; } return baseClone(value) }
验证我们写的cloneDeep是否能解决循环应用的问题
var obj = {};var b = {obj}; obj.b = bvar copy = cloneDeep(obj); console.log(copy);
위 내용은 딥 카피의 세 가지 구현 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

국내 AI Dark Horse Deepseek은 글로벌 AI 산업에 충격을 주면서 강력하게 증가했습니다! 1 년 반 동안 단지 설립 된이 중국 인공 지능 회사는 무료 및 오픈 소스 모형 인 DeepSeek-V3 및 DeepSeek-R1에 대해 글로벌 사용자로부터 광범위한 칭찬을 받았습니다. DeepSeek-R1은 이제 OpenAIO1의 공식 버전과 비교할 수있는 성능으로 완전히 출시되었습니다! 웹 페이지, 앱 및 API 인터페이스에서 강력한 기능을 경험할 수 있습니다. 다운로드 방법 : iOS 및 Android 시스템을 지원하면 사용자가 App Store를 통해 다운로드 할 수 있습니다. Deepseek 웹 버전 공식 입구 : HT

DeepSeek : 서버와 혼잡 한 인기있는 AI를 처리하는 방법은 무엇입니까? 2025 년 핫 AI로서 DeepSeek은 무료이며 오픈 소스이며 OpenAIO1의 공식 버전과 비교할 수있는 성능을 가지고 있으며, 이는 인기를 보여줍니다. 그러나 높은 동시성은 서버 바쁜 문제를 가져옵니다. 이 기사는 이유를 분석하고 대처 전략을 제공합니다. DeepSeek 웹 버전 입구 : https://www.deepseek.com/deepseek 서버 바쁜 이유 : 높은 동시 액세스 : DeepSeek의 무료 및 강력한 기능은 동시에 많은 사용자를 유치하여 과도한 서버로드를 초래합니다. 사이버 공격 : DeepSeek은 미국 금융 산업에 영향을 미친다 고보고되었습니다.

2025 년 초, 국내 AI "Deepseek"은 놀라운 데뷔를했습니다! 이 무료 및 오픈 소스 AI 모델은 OpenAI의 O1의 공식 버전과 비교할 수있는 성능을 가지고 있으며 웹 측, 앱 및 API에서 완전히 출시되어 iOS, Android 및 웹 버전의 다중 터미널 사용을 지원합니다. DeepSeek 공식 웹 사이트 및 사용 지침의 심도있는 검색 : 공식 웹 사이트 주소 : https://www.deepseek.com/using 웹 버전 : 위의 링크를 클릭하여 DeepSeek 공식 웹 사이트를 입력하십시오. 홈페이지에서 "대화 시작"버튼을 클릭하십시오. 먼저 사용하려면 휴대폰 확인 코드와 함께 로그인해야합니다. 로그인 한 후 대화 인터페이스를 입력 할 수 있습니다. DeepSeek은 강력하고 코드를 작성하고 파일을 읽고 코드를 만들 수 있습니다.

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

WebStorm Mac 버전
유용한 JavaScript 개발 도구

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

SublimeText3 영어 버전
권장 사항: Win 버전, 코드 프롬프트 지원!

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

뜨거운 주제



