변수
는 변할 수 있는 데이터를 말하고, 식별자
는 어떤 변수를 식별하는데 사용되는 이름, 즉 변수명을 일컫는다.
불변성
구분은 변경 가능성의 대상이 '데이터 영역' 메모리 , 즉 변수에 할당된 데이터 영역이 변할 수 있는가에 따라 결정
변수상수
구분은 변경가능성의 대상이 '변수 영역' 메모리 , 즉 변수 자체가 변할 수 있는가에 따라 결정
let name
name = 'Harry'
위와 같이 name이라는 변수를 선언하고, name 변수에 'Harry' 라는 문자열을 할당하는 과정은 아래와 같다.
let name = 'Harry'
name = name + 'Potter'
위와 같이 name이라는 변수의 데이터를 변경한다면 어떻게 될까? 단순하게 생각한다면 당연히 name에 할당된 데이터 영역의 값 자체를 변경한다고 생각할 수 있다. 하지만, 데이터 영역의 값은 변경할 수 없다.
즉, 위의 연산에서는 우리가 위에서 'Harry'라는 문자열을 저장한 데이터 영역 (@5004)의 데이터 자체를 변경하는게 아니라,
변수 타입의 데이터 할당 과정을 통해서, 변수타입의 데이터 영역은 불변하다는 것을 알 수 있다. 즉, 데이터 영역 자체의 데이터를 변경할 수 없기 때문에 ('Harry'를 'Harry Potter'로 변경할 수 없음) 새로운 데이터 영역을 할당('Harry' 영역과 'Harry Potter' 영역은 별개) 하고, 변수 영역에서 참조하는 데이터 영역의 주소를 바꿔야한다는 것이다.
한마디로 정리하자면 불변성과 가변성은 변수 영역이 참조하는 데이터 영역이 바뀌느냐 안바뀌느냐의 차이이다.
let obj = {
name: 'Dobby',
belong: 'malfoy house',
}
위와 같이 obj 라는 객체를 선언하고 프로퍼티로 name과 belong을 각각 정의해주었다. 객체의 데이터 할당과정은 아래와 같다.
let obj = {
name: 'Dobby',
belong: 'malfoy house',
}
obj.belong = 'howarts'
위의 예시를 통해서 우리는 자바스크립트 참조형 객체는, obj라는 이름을 가진 변수 영역이 가리키는 데이터 영역의 주소 (@5001) 의 변경 없이도 데이터를 변경 가능하다는 사실을 알 수 있다. 즉 , 변수영역이 가리키는 데이터 영역이 변경되지 않으므로 가변적이다고 할 수 있다.
이렇게 변수형과 참조형의 데이터 할당과정이 다르니, 당연히 변수 복사과정도 다를 수 밖에 없다.
먼저 변수형이 어떻게 복사되는지를 아래 예시를 통해 보자.
let name1 = 'Harry'
let name2 = name1
console.log(name1, name2)
// 결과
// Harry, Harry
let name2 = 'Hermione'
console.log(name1, name2)
// 결과
// Harry, Hermione
변수형 name1을 변수형 name2에 복사하고, name2의 데이터를 변경해도 name1의 값이 변경되지 않는다. 두 변수 모두 처음에는 'Harry'라는 데이터를 담은 같은 데이터 영역 주소를 참조했지만, name2에 'Hermione'을 대입한 순간 name2라는 이름을 가진 변수 영역이 가리키는 데이터 영역의 주소만 변경되기 때문
이다.
하지만 참조형을 복사할 때는 조금 다르다. 아래 예시를 통해 보자.
let obj1 = {
name: 'Dobby',
belong: 'hogwarts',
}
let obj2 = obj1
console.log(obj1, ojb2)
// 결과
// { name: 'Dobby', belong:'howarts'},
// { name: 'Dobby', belong:'howarts'}
obj2.name = 'Kreacher'
console.log(obj1, ojb2)
// 결과
// { name:'Kreacher', belong:'howarts'}
// { name:'Kreacher', belong:'howarts'}
obj2에 obj1 을 대입한 후, obj2의 프로퍼티 값을 변경하면 obj1의 프로퍼티값도 함께 변경된다. 아래 그림을 통해 알아보자
따라서 obj2의 프로퍼티 값을 변경하면 obj1의 프로퍼티 값도 변경된다. 따라서 아래와 같이 obj2에 아예 새로운 객체를 저장하면 obj1의 는 변경되지 않는다. 당연히 obj2 라는 이름을 가진 변수 영역 (@1001) 이 참조하는 데이터 영역 자체를 변경하는 것이기 때문이다.
let obj2 = obj1
let obj2 = {
name: 'Kreacher',
belong: 'black house',
}
// obj1의 데이터는 변경되지 않는다.
얕은 복사 (shallow copy)
깊은 복사 (deep copy)
이렇게 자바스크립트가 변수에 데이터를 어떻게 할당하는지와 불변성과 가변성 개념 , 그리고 얕은 복사와 깊은 복사를 알아보았다. 특히 리액트 개발을 할 때 불변성 가변성 개념을 숙지하는 것이 중요하다.
상태 관리를 할 때 불변성을 지키지 않고, 객체를 변경하면 리액트는 해당 객체가 변경된지 감지하지 못하기 때문이다. 위에서도 보았듯 객체 프로퍼티를 변경할 시 객체 obj 가 저장된 변수 영역이 가리키는 데이터 영역의 주소는 변경되지 않는다.
이번 포스팅에서 깊은복사와 얕은복사를 깊게 설명하지 않았으므로 이 포스팅 을 참고할 것을 추천한다