솔미는 성장중
[JS] 불변성 본문
원시 데이터의 "데이터 불변성"
원시 데이터 : String, Number, Boolean, null, undefined
원시 데이터에서는 단순하게 모양이 다르면 false가 나온다고 생각해도 틀리진 않는다.
하지만 정확히는 '메모리 주소'가 같고 다름에 따라 true/false가 바뀐다.
let a = 1
let b = 4
console.log(a,b,a===b) //1 4 false -> 메모리 주소가 달라서 false
b=a
console.log(a,b,a===b) //1 1 true -> b가 a가 가리키는 메모리주소를 가리키게 됨
a=7
console.log(a,b,a===b) //7 1 false -> 메모리 주소가 달라서 false
새로운 원시 데이터를 사용했을 때 그 원시 주소가 기존 메모리 상에 들어있을 때 원시 데이터를
새로운 메모리에 만들지 않고, 기존 메모리 주소를 바라보도록 만든다.
즉, 원시 데이터들은 불변한다!
참조형 데이터의 "가변성"
참조형 데이터(object, array, function)
참조형 데이터는 새로운 값을 만들 때 마다 새로운 메모리 주소에 할당된다.
let a = {k:1}
let b = {k:1}
console.log(a,b,a===b) // {k:1} {k:1} false -> a는 1번메모리, b는 2번메모리
a.k = 7 //1번 메모리 내용 수정
b=a //b가 1번 메모리 주소를 바라보게 됨.
console.log(a,b,a===b) //{k:7} {k:7} true
a.k=2 //1번 메모리 내용 수정
console.log(a,b,a===b) //{k:2} {k:2} true -> b도 함께 바뀐 모습!!!!!!!!!!!!
let c = b //c도 1번 메모리를 바라보게 됨.
console.log(a,b,c, a===c) //{k:2} {k:2} {k:2} true
a.k=10
console.log(a,b,c,a===c) //{k:9} {k:9} {k:9} true
참조형 데이터에서 'a=b와 같은할당' = '같은 메모리 주소를 보게 만든다.'라는 의미이다.'
a,b를 별개의 데이터로 관리하고 싶다면 '복사'를 이용해야한다.
복사
문제 상황 예시) user와 copyUser를 별개의 데이터로 컨트롤하고 싶은데 user를 바꾸는 copyUser도 바뀌는 모습.
const user = {
name:'solmi',
age:99,
emails: [ovo10203@gmail.com]
}
const copyUser = user //여기가 문제!!!!!!!!!!!!!!!!
console.log(copyUser===user) //false
user.age = 20
console.log(user) //~~, age:20, ~~
console.log(copyUser) // ~~, age:20, ~~
해결방법
얕은 복사
표면만 복사
1.
Object.assign({},user)
2.
Object.assign{...user}
전개연산자를 사용하기 전에 빈 객체가 만들어짐 { }
전개연산자는 중괄호를 날리고, 속성 값을 빈 객체 속에 넣음.
cf) 배열데이터에선
const B = A.concat([])
const B = [...A]
다만, 얕은 복사는 user 객체 데이터 하나만 복사가 됐기에..!
user.emails에서 emails는 참조형 배열 데이터는 복사가 안되어서 아래와 같은 현상이 일어난다. emails 객체 데이터에 관해선 같은 메모리 주소를 바라보고 있기 때문에!
user.emails.push('1234@gmail.com')
console.log(user.emails === copyUser.emails) //true
이를 해결하기 위해선
.
.
.
깊은 복사 !
내부에 있는 모든 참조관계까지 새로운 메모리로 복사
(즉, 참조형 데이터 안에 참조형 데이터가 있는 경우는 깊은 복사 추천)
- Lodash사용
npm i Lodash
- main.js 상단에 import해주기
import _ from 'lodash'
- const copyUser 선언 수정해주기
const copyUser = _.cloneDeep(user) //깊은 복사
cf) 배열데이터에선
import cloneDeep from 'lodash/cloneDeep'
const b = cloneDeep(a)
cf) 객체데이터 예시. 메모리에서 흐름 보기
'JavaScript' 카테고리의 다른 글
[JS] 이벤트 (event) (0) | 2023.08.03 |
---|---|
[JS] DOM : 크기 & 좌표 구하기 (0) | 2023.08.02 |
[JS] DOM (0) | 2023.07.31 |
[JS] fetch() (0) | 2023.07.31 |
[JS] 동기/비동기 (콜백 패턴, promise, Async & Await, Resolve, Reject, 에러 핸들링, 반복문에서의 비동기) (0) | 2023.07.31 |