ㅇㅇㅈ Blog

프론트엔드 수행중

0%

JS-데이터 불변성

데이터 불변성(Immutability)

  • 원시 데이터 : String, Number, Boolean, undefined, null
    • 원시데이터들은 메모리에 만들어지면 불변한다.
    • 간단히 생긴게 같으면 같은 데이터, 다르면 다른 데이터이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
let a = 1
let b = 4
console.log(a, b, a === b)
// 1 4 false
b = a
console.log(a, b, a === b)
// 1 1 true
a = 7
console.log(a, b, a === b)
// 7 1 false
let c = 1
console.log(b, c, b === c)
// 1 1 true
  • 참조형 데이터 : Object, Array, Function
    • 불변성이 없다. 즉, 가변한다
    • 모양이 같다고 같은 데이터는 아니다
    • 한 쪽을 수정하면 의도치 않게 다른쪽도 수정이 될 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let a = { k: 1 }
let b = { k: 1 }
console.log(a, b, a === b)
// {k:1} {k:1} false
a.k = 7
b = a
console.log(a, b, a === b)
// {k:7} {k:7} true
a.k = 2
console.log(a, b, a === b)
// {k:2} {k:2} true
let c = b
console.log(a, b, c, a === c)
// {k:2} {k:2} {k:2} true
a.k = 9
console.log(a, b, c, a === c)
// {k:9} {k:9} {k:9} true
  • 참조형 데이터를 새롭게 할당해서 완전히 구분지어 사용하고 싶으면
    복사라는 개념을 사용해 메모리상에서 분리해줘야 한다.
    • 복사에는 얕은복사와 깊은복사가 있다
1
2
3
4
5
6
7
8
9
10
11
12
const user = {
name: 'abc',
age: 85,
emails: ['abc@gmail.com'],
}
const copyUser = user
console.log(copyUser === user)
// true
user.age = 22
console.log(user.age) // 22
console.log(copyUser.age) // 22
// 데이터가 둘 다 변했다
  1. 얕은 복사
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 복사방법.1
// Object.assign()을 이용하는 방법
const user = {
name: 'abc',
age: 85,
emails: ['abc@gmail.com'],
}
const copyUser = Object.assign({}, user)
console.log(copyUser === user)
// false
user.age = 22
console.log(user.age) // 22
console.log(copyUser.age) // 85

// 방법.2
// ...전개연산자를 이용하는 방법
const copyUser = { ...user }
console.log(copyUser === user)
// false

얕은 복사의 문제점

  • 얕은 복사의 문제점은 겉표면만 복사하기 때문에 데이터 안의 또다른
    참조형 데이터는 복사가 되지 않는다.
1
2
3
4
5
6
7
user.emails.push('neo@naver.com')
console.log(user.emails === copyUser.emails)
// ture
console.log(user.emails)
// ['sacultang@gmail.com', 'neo@naver.com']
console.log(copyUser.emails)
// ['sacultang@gmail.com', 'neo@naver.com']
  1. 깊은복사
  • 자바스크립트로 구현하기 까다롭다
1
2
3
4
5
6
7
8
9
10
11
12
13
function copyObj(obj) {
const result = {}
for (let key in obj) {
if (typeof obj[key] === 'object') {
result[key] = copyObj(obj[key])
} else {
result[key] = obj[key]
}
}
return result
}
const copiedobj = copyObj(user)
console.log(copiedobj)

user의 이메일은 배열이었는데 cpoiedobj에는 객체데이터로 바껴있다..
lodash를 사용하도록 하자..

1
2
3
4
5
6
7
8
9
import _ from 'lodash'

const clone = _.cloneDeep(user)
console.log(clone === user)
// false

clone.emails.push('abc@naver.com')
console.log(user.emails === clone.emails)
// false

잘 복사 된다