const user={
name:"Heropy",
age:85,
emails:['thesecon@gmail.com']
}
const copyUser = user
console.log(copyUser === user)// true
user.age = 22
console.log('user',user)//
user
{name:"Heropy",
age:22,
emails:['thesecon@gmail.com']}
console.log('copyUser',copyUser)//
copyUser
{name:"Heropy",
age:22,
emails:['thesecon@gmail.com']}
위와 같이
const copyUser = user를 해줬기 때문에 같은 메모리 주소를 바라보고
있다. 그렇기 때문에 console.log(copyUser === user)// true 값이
반환되었다.
그렇기 때문에 user.age=22로 바꿀 시 copyUser와 user둘다 age값이
바뀌는 것을 확인 할 수 있다.
const user={
name:"Heropy",
age:85,
emails:['thesecon@gmail.com']
}
const copyUser = Object.assign({},user)
console.log(copyUser === user)// false
user.age = 22
console.log('user',user)//
user
{name:"Heropy",
age:22,
emails:['thesecon@gmail.com']}
console.log('copyUser',copyUser)//
copyUser
{name:"Heropy",
age:85,
emails:['thesecon@gmail.com']}
위와같이 Object.assign을 이용하여 복사하면 새로운 메모리를
사용하여 복사하게 되는데 그렇기 때문에 console.log(copyUser === user)// false 값이 반환되게 된다.
또 user.age=22로 바꾼것도 다른 메모리를 사용하기 때문에 85로
나온다.
이러한 방법이 싫다면 아래의 방법으로 사용할 수도 있습니다.
const user={
name:"Heropy",
age:85,
emails:['thesecon@gmail.com']
}
const copyUser = {...user}
console.log(copyUser === user)// false
user.age = 22
console.log('user',user)//
user
{name:"Heropy",
age:22,
emails:['thesecon@gmail.com']}
console.log('copyUser',copyUser)//
copyUser
{name:"Heropy",
age:85,
emails:['thesecon@gmail.com']}
바로 전개 연산자(spread operator)를 사용하는 방법입니다.
결과는 Object.assign을 사용한것과 같습니다.
const user={
name:"Heropy",
age:85,
emails:['thesecon@gmail.com']
}
const copyUser = {...user}
console.log(copyUser === user)// false
user.age = 22
console.log('user',user)//
user
{name:"Heropy",
age:22,
emails:['thesecon@gmail.com']}
console.log('copyUser',copyUser)//
copyUser
{name:"Heropy",
age:85,
emails:['thesecon@gmail.com']}
user.emails.push('neo@zillinks.com')
console.log(user.emails === copyUser.emails)// true
위와 같이 user에 user.emails.push('neo@zillinks.com')를 push
해주면 console.log(user.emails === copyUser.emails)// true
이 반환 됩니다.
분명 전개연산자로 메모리 주소를 따로 할당하여 복사했는데 어째서
user.emails와 비교했을 때 true같이 반환되는 것일까요.
그 이유는 emails는 배열, 즉 참조형 데이터 이기 때문입니다.
그렇기 때문에 둘의 age는 85와22로 다르지만 emails는 공유를 하게 되는
것입니다.
그러면 이렇게 값을 공유하기 싫을때는 어떤 방법을 사용하면 될까요??
그럴때 깊은 복사를 사용하시면 됩니다.
깊은 복사는 js로 구현하기 어렵기 때문에 lodash라는 라이브러리의
도움을 받겠습니다.
import _ from 'lodash'
const user={
name:"Heropy",
age:85,
emails:['thesecon@gmail.com']
}
const copyUser = _.cloneDeep(user)
console.log(copyUser === user)// false
user.age = 22
console.log('user',user)//
user
{name:"Heropy",
age:22,
emails:['thesecon@gmail.com']}
console.log('copyUser',copyUser)//
copyUser
{name:"Heropy",
age:85,
emails:['thesecon@gmail.com']}
user.emails.push('neo@zillinks.com')
console.log(user.emails === copyUser.emails)// false
위와같이 _.cloneDeep(user) 입력시 깊은 복사가 됩니다.
결과는 얕은 복사를 했을 때처럼 emails를 공유하지 않고 user에만
들어가 있는 것을 확인 할 수 있습니다.
또한 console.log(user.emails === copyUser.emails)// false
console.log로 확인시 얕은 복사로 했을때 true가 나왔던 것이
false로 나오는 것도 확인 할 수 있었습니다.
깊은 복사를 할 수 있는 이유는 lodash홈페이지를 들어가서 clone검색시
자세히 알아 볼 수 있는데 주소는 lodash홈페이지 링크를 남겨두겠다.
홈페이지에 접속시 deepclone을 할 수 있는 이유가 재귀적으로 복사 하기
떄문이라고 나와 있는데 재귀란 하나의 데이터 안에서 어떠한 내용이 반복적으로 실행되는 것을 말한다.
이를 통해 깊은 복사가 가능하다. 안에 있는 로직을 이해할 필요는 없지만
알고 있으면 좋다고 생각해 정리를 해봤습니다.
정리하면 만약 참조형 데이터를 사용하고 값을 공유했으면 좋겠다라고 생각하면 얕은 복사를 사용하면 되고 나는 아예 독립적으로 사용하고 싶다.
라고 생각하면 깊은 복사를 사용하면 된다고 생각합니다.