티스토리 뷰

 

아래글에서 이어지는 내용입니다.

 

 

[JS] 자바스크립트가 데이터를 할당하는 방법 (feat. 불변성, 가변성)

도서 코어 자바스크립트를 내용 일부를 정리한 글입니다. 자바스크립트의 데이터 할당 과정과 변수의 불변성과 가변성에 대하여 자바스크립트의 타입 자바스크립트의 데이터 타입은 크게 원시

munak.tistory.com

 


 

서론

이전 글에서 원시값과 객체의 데이터 할당에 대해 작성했었습니다.

데이터 할당 과정이 다르니, 복사의 과정에도 차이가 발생하게 됩니다.

 

 

원시값(Primitive values)의 복사

아래 간단한 예시를 들어 보겠습니다.

let name1 = 'Rimo'
let name2 = name1
console.log(name1, name2) // Rimo, Rimo

 

name1은 'Rimo'라는 문자열을 저장하고 있습니다. 그리고 name2를 선언한 뒤 name1을 할당합니다.

따라서 첫 번째 출력결과는 'Rimo', 'Rimo'가 됩니다.

 

내부적으론 name1 변수와 name2 변수가 동일하게 'Rimo'라는 데이터를 담은 데이터 영역의 주소를 참조하고 있을 겁니다.

name2 = 'abc'
console.log(name1, name2) // Rimo, abc

 

여기서 name2에 문자열 'abc'를 할당하면 어떻게 될까요?

 

문자열 'abc'가 새로운 데이터 영역에 저장이 되고, name2의 변수 영역은 이를 참조하도록 변경되겠죠.

즉, name2의 값을 변경해도,  name1의 값은 변경되지 않습니다. 

 

 

 

당연한 거 아닌가요?라고 생각하실 수도 있을 것 같습니다. 🤔

이어서 객체의 복사를 살펴보겠습니다.

 

 

 

객체(Object)의 복사

let obj1 = {
  name: 'Rimo',
  age: 24,
}
let obj2 = obj1
console.log(obj1, ojb2) // { name: 'Rimo', age: 24 }, { name: 'Rimo', age: 24 }

obj2.name = 'abc'
console.log(obj1, ojb2) // { name: 'abc', age: 24 }, { name: 'abc', age: 24 }

 

name과 age 프로퍼티를 가진 객체 obj1를 선언했습니다. 그리고 obj2에 obj1을 할당했습니다.

첫 번째 출력 결과는 동일하게 `{ name: 'Rimo', age: 24 }`가 나타납니다.

 

그리고 obj2.name에 문자열  'abc'을 할당한 뒤 다시 출력해보았습니다. 

두 번째 출력 결과에서는 `{ name: 'abc', age: 24 }`가  나타났습니다.

 

변경한 것은 obj2.name인데 obj1.name까지 바뀌었죠.

즉, 복사된 객체의 프로퍼티의 값을 변경했더니 원본 객체 또한 변경된 모습입니다.

왜 이런 일이 발생했을까요?

 

 

임의의 메모리가 존재한다고 가정하고 다시 살펴보겠습니다.

let obj1 = {
  name: 'Rimo',
  age: 24,
}
let obj2 = obj1

 

 

위 코드가 실행되었을 때, 즉 복사가 일어나면 obj1과 obj2는 같은 프로퍼티가 들어있는 데이터 영역을 참조하도록 복사가 됩니다.

 

 

 

 

obj2.name는 다음과 같이 데이터 영역의 참조를 따라 접근하게 되죠.

 

 

 

 

따라서 obj2.name = 'abc'를 실행하면 name 변수영역이 참조하고 있는 데이터 영역이 바뀌게 됩니다.

 

 

 

때문에 같은 프로퍼티의 변수영역(@1004~)을 참조하고 있는 obj1도 영향을 받게 되는 겁니다.

 

 

이런 복사의 형태를 얕은 복사라고 합니다.

 

 

 

얕은 복사와 깊은 복사

얕은 복사(Shallow Copy) 

위 예시와 같이, 객체를 복사할 때 원래의 값과 복사된 값이 객체 내부 프로퍼티까지 같은 주소를 참조하고 있는 것을 말합니다.
원래 값과 복사된 값의 데이터 변경이 서로에게 영향을 미치게 됩니다. ⭐

 

깊은 복사(Deep Copy)

위의 예시와 달리 객체의 원래 값과 복사된 값이 객체 내부 프로퍼티까지 다른 주소를 참조하고 있는 것을 말합니다.
주소자체가 달라지므로 각각의 변경이 서로에게 영향을 미치지 않습니다.

 

 

객체의 깊은 복사

'객체는 가변성을 가질 수 있음으로 얕은 복사가 일어날 수 있다.'라는 사실을 모른다면,

의도치 않게 원본 데이터를 손상시켜 버릴 수도 있겠죠? 이를 감지하는 방법도 없을 거고요.

 

그럼 객체를 깊은 복사 하려면 어떻게 해야 할까요? 간단합니다. 새로운 객체를 만들어 할당하는 거죠.

let obj1 = {
  name: 'Rimo',
  age: 24,
}

let obj2  = {
  name: 'abc',
  age: 24,
}

 

이렇게 하면 ob1과 ob2가 각각 다른 프로퍼티의 주소를 가지게 됩니다.

 

 

기존의 객체의 값을 그대로 사용하고 싶다면 아래와 같이 작성하거나, JSON 변환을 이용해 볼 수 있습니다. (관련 문서)

var obj2 = { 
	name: obj1.name, 
    age: obj1.age, 
}

 

 

 

감사합니다.


 

 

공부한 내용을 복습/기록하기 위해 작성한 글이므로 내용에 오류가 있을 수 있습니다.

 
댓글
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday