JavaScript의 심층 복제본 상세 분석
4918 단어 JavaScript딥 카피얕은 카피
1. 얕은 복사
얕은 복사본은 인용만 복사하고 복사 값은 없습니다.JS에서 가장 간단한 간단한 간단한 복사본은 "="부호 조작부호를 이용하여 실현하는 것이다.
var obj1 = {
a:1,
b:[2,3,4],
c:{name:'tanj'},
fun:function(){
console.log('fun')
}
}
var obj2 = obj1
obj2.a = 666 /* obj2 ,obj1 */
console.log(obj1) /* {a: 666, b: Array(3), c: {…}, fun: ƒ} */
상기 코드에서 우리는obj2의 값을 수정했고obj1의 값도 이에 따라 바뀌었다. 사용 = "얕은 복사만 실현했다."2. 딥 카피
딥 복제본은 대상에 대한 완전 복제본으로 딥 복제본이 실행된 후의 두 값은 서로 영향을 주지 않는다.
1. JSON을 이용한다.stringify와 JSON.parse 방법
JSON.stringify는 JavaScript 값을 JSON 문자열로 변환합니다.
JSON.parse는 JSON 문자열을 JavaScript 값으로 변환합니다.
var obj1 = {
a:1,
b:[2,3,4],
c:{name:'tanj'},
}
var obj2 = JSON.parse(JSON.stringify(obj1))
obj2.a = 12
console.log(obj1) /* {a: 1, b: Array(3), c: {…}} */
obj2의 값을 수정하는 것은 obj1의 속성 값에 영향을 주지 않습니다. 분명히 우리는 JSON을 이용합니다.parse와 JSON.stringify는 깊은 복사를 실현했다.하지만 정말 이렇게 간단하게 실현할 수 있을까?우리 아래의 예를 봅시다!
var obj1 = {
a:1,
b:[2,3,4],
c:{name:'tanj'},
fun:function(){
console.log('fun')
}
}
var obj2 = JSON.parse(JSON.stringify(obj1))
obj2.a = 12
console.log(obj1) /* {a: 1, b: Array(3), c: {…}, fun: ƒ} */
console.log(obj2) /* {a: 12, b: Array(3), c: {…}} */
변환된 obj2에 fun이라는 속성이 없습니다. 이것은 JSON을 이용하기 때문입니다.stringify 변환 과정에서 undefined,function,symbol을 무시했습니다.분명히 우리의 대상에 이러한 유형의 속성이 나타날 때 이 방법을 이용하여 깊은 복사를 할 수 없다.2. 귀속
function deepClone(source){
if(!isObject(source)) return source
var newObj = source instanceof Array? []:{}
for(let key in source){
if(source.hasOwnProperty(key)){
newObj[key] = isObject(source[key])?deepClone(source[key]):source[key]
}
}
return newObj
}
function isObject(x) {
return typeof x === 'object' && x != null
}
위의 방법을 테스트해 보십시오.
var obj1 = {
a:1,
b:[2,3,4],
c:{name:'tanj'},
fun:function(){
console.log('fun')
}
}
var obj2 = deepClone(obj1)
obj2.a = 12
console.log(obj1) /* {a: 1, b: Array(3), c: {…}, fun: ƒ} */
예를 통해 알 수 있듯이 우리는obj2의 a 속성 값을 수정했지만 obj1의 a 속성 값에 영향을 주지 않았다.귀속을 통해 우리는 깊은 복사를 실현할 수 있다!주의: 상술한 방법은 순환 인용 문제를 해결하지 못했다.
var obj1 = {}
obj1.a = obj1
var obj2 = deepClone(obj1) /* , */
console.log(obj2)
순환 인용 문제를 해결하고 Symbol 형식의 복사를 실현하는 방법에 관해서는 잠시 후에 보완하겠습니다.3. 기타 복제 방법
1. 그룹의 concat () 및 slice () 방법
우리는 그룹 중 두 가지 방법인concat과slice가 복제 그룹을 완성하고 새 그룹으로 되돌아갈 수 있다는 것을 알고 있다.concat을 예로 들다.
var arr = [1,2,3]
var arr2 = arr.concat()
arr2[2]=4
console.log(arr) /* [1, 2, 3] */
console.log(arr2) /* [1, 2, 4] */
arr2의 값을 바꾸면 arr의 값에 영향을 주지 않는다. 이것은 수조의 깊은 복사를 실현한 것인가. 먼저 결론을 서둘러 내리지 않고 아래의 예를 보고 분석한다.
var arr = [1,2,3,[4,5,6],{a:7}]
var arr2 = arr.concat()
arr2[3] = 444
arr2[4].a=8
console.log(arr) /* [1,2,3,[4,5,6],{a:8}] */
console.log(arr2) /* [1,2,3,444,{a:8}] */
우리는 arr2[3]를 직접 수정했지만 arr의 변화를 일으키지는 않았지만, 우리는 arr2[4]를 수정했다.a시,arr의 상응하는 원소가 함께 바뀌었다.사실 우리는arr2수조의 원소를 직접 변화(예를 들어arr2[0]=***,arr2[1]=***,arr2[3]=***)할 때 원수조arr에 영향을 주지 않지만 우리가 수조의 [3,4,5] 또는 {a:7}를 수정할 때 원수조arr의 변화를 초래할 수 있다.결론:concat () 방법은 수조 1층을 깊이 복사했다.
수조의 슬라이스 () 방법을 다시 시도해 볼 수 있으며, 수조의 1층만 깊이 복사했다.
2. Object.assign () 및...확장 연산자
var obj1 = {
a:1,
b:[2,3,4],
c:{name:'tanj'}
}
var obj2 = {...obj1}
obj2.a = 666
obj2.c.name = 'xinxin'
console.log(obj1) /* {a:1,b:[2,3,4],c:{name:'xinxin'}} */
보시면 이용...전개 연산자는 대상의 첫 번째 층의 깊은 복사를 실현한다.뒤에 있는 것은 복사된 인용 값일 뿐이다.Object를 사용해 보세요.assign () 메서드:
var obj1 = {
a:1,
b:[2,3,4],
c:{name:'tanj'}
}
var obj2 = {}
Object.assign(obj2,obj1)
obj2.a = 666
obj2.b[0] = 0
console.log(obj1) /* {a:1,b:[0,3,4],c:{name:'tanj'} */
마찬가지로 대상의 첫 번째 층만 깊이 복사했다. 만약에 원본 대상의 속성 값(예를 들어obj1)이 대상을 가리키는 인용이라면obj2도 그 인용 값만 복사한다.그래서obj2에서 b가 가리키는 그 그룹을 바꾸면obj1의 값도 바뀐다.계층 1에 대해서만 심층 복제할 수 있습니다.
function shallowClone(source) {
const newObj = source.constructor === Array ? [] : {}
for (let keys in source) {
if (source.hasOwnProperty(keys)) {
newObj[keys] = source[keys]
}
}
return newObj
}
다음은 JavaScript의 얕은 복사본에 대한 상세한 내용을 분석하고 JavaScript의 얕은 복사본에 대한 더 많은 자료를 보시기 바랍니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
기초 정리 - 1문자 (String) 숫자 (Number) 불린 (Boolean) null undefined 심볼 (Symbol) 큰정수 (BigInt) 따옴표로 묶어 있어야 함 Not-A-Number - 숫자 데이터 / 숫자로 표...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.