변수, 데이터, 불변성

이윤환·2022년 4월 4일
1

자바스크립트가 데이터를 처리하는 과정을 알아보자

먼저 js에서 데이터 타입은
크게는 기본형과 참조형을 나뉘고

기본형에는 숫자(number), 문자열(string), 불리언(boolean), null, undefined 등이 있고,
참조형에는 객체(object), 배열(array), 함수(function) 등이 있다.

기본형과 참조형을 무슨 기준으로 나눌까

기본형은 불변값이고 참조형은 가변값이라는 차이가 있다.

그게 무슨 말인지 알기 전에 먼저 변수와 식별자에 대해서 간략히 소개하자면
변수는 변경 가능한 데이터가 담길 수 있는 공간이고, 식별자는 그 변수의 이름을 말한다.

let name

name 이라는 식별자의 변수를 선언함

변수를 선언하면 컴퓨터는 메모리의 빈 공간에 식별자를 저장하고, 그 공간에 undefined를 할당해준다.

식별자 저장 장소 [name 값: undefined][ ][ ][ ][ ][ ]...
데이터 저장 장소 [ a ][ b ][ c ][ d ][ e ]...

이후 그 변수에 기본형 데이터를 할당하려고 하면 별도의 공간에 데이터를 저장하고
그 공간의 주소를 변수의 값 영역에 할당한다.

name = "이윤환" name 이라는 식별자의 변수를 선언함
식별자 저장 장소 [name - 값: @a][ ][ ][ ][ ][ ]...
데이터 저장 장소 [ a : "이윤환" ][ b ][ c ][ d ][ e ]...

만일 내가 a = "김윤환" 이런식으로 새로운 데이터를 할당 할 경우 데이터 저장 장소의 a의 값이 바뀌는게 아니라
새로운 데이터 저장 장소에 빈 공간에 데이터를 저장하고 식별자 name이 참조하는 주소 값을 변경시킨다.
식별자 저장 장소 [name - 값: @b][ ][ ][ ][ ][ ]...
데이터 저장 장소 [ a : "이윤환" ][ b : "김윤환" ][ c ][ d ][ e ]...
                      ↑ 변경되지 않음
즉 한 번 만든 값을 바꿀 수 없다 하여 불변값이라고 한다.

만일 참조형 데이터를 할당하려고 하면 컴퓨터는 참조형 데이터 내부 프로퍼티들을 위한 변수 영역을 별도로 확보해서 확보된 주소를 변수에 연결하고,
let obj = {a: 1, b: 'Leeyhunhwan', c: true} 참조형 데이터를 변수 선언 및 할당
다시 앞서 확보한 변수 영역에 각 프로퍼티의 식별자를 저장하고,
각 데이터를 별도의 공간에 저장해서 그 주소를 식별자들과 매칭시킨다.

식별자 저장 장소 [obj - 값: @a][ ][ ][ ][ ][ ]...
데이터 저장 장소 [ a : @g~@i ][ b : 1 ][ c : "이윤환" ][ d : true ][ e ]...
객체 @a (obj) 의 변수 영역 [ g 이름: a 값: @b ][ h 이름: b 값: @c ][ i 이름: c 값: @d ][ j ][ k ]...

기본형 데이터와의 차이는 객체의 변수(프로퍼티)의 영역이 따로 하나 더 존재한다는 점이다.
즉 객체가 별도로 할애한 영역은 변수 영역일 뿐 데이터 영역은 기존의 메모리 공간을 그대로 활용하고 있다.
앞서 봤듯이 데이터 영역에 저장된 값은 모두 불변값이다.
그러나 변수(영역)에는 다른 값을 얼마든지 대입 할 수 있다.

obj.c = false

식별자 저장 장소 [obj - 값: @a][ ][ ][ ][ ][ ]...
데이터 저장 장소 [ a : @g~@i ][ b : 1 ][ c : "이윤환" ][ d : true ][ e : false ]...
객체 @a (obj) 의 변수 영역 [ g - 값: @b ][ h - 값: @c ][ i - 값: @e ][ j ][ k ]...
                                                                       ↑ 변경됨

즉 변수 영역에는 얼마든지 다른 값을 대입 할 수 있으므로 불변하지 않다. 즉 가변값이다 라고 하는것이다.

정리하면 기본형과 참조형의 차이는 참조형은 주솟값을 복사하는 과정을 한 단계 더 거치는 점이다.

이러한 차이는 값을 복사하는데 있어 큰 차이가 벌어진다.
가령 기본값을 가진 변수 자체를 새로운 변수에 복사를 한 후 복사 된 변수의 값을 변경하여도 복사의 주체인 변수에는 영향을 끼치지 않는 반면
참조형 값을 가진 변수를 새로운 변수에 복사를 한 후 복사된 변수의 프로퍼티의 값을 변경하면 복사의 주체인 변수 또한 값이 바뀐다.

	let a = 1;
	let b = a;
    b = 2;
    console.log(a) // 1 영향을 끼치지 않음
	let obj = {a: 1, b: 20};
	let obj2 = obj
    obj2.a = 3
    console.log(obj.a) // 3 값이 바뀜

그래서 우리는 참조형 변수를 복사할때 얕은 복사 혹은 깊은 복사라는 방법을 사용해야 한다.
얕은 복사는 바로 아래 단계의 값만 복사하는 방법이고, 깊은 복사는 내부의 모든 값을 하나하나 전부 복사하는 방법이다.

내가 아는 예제를 적고 끝내겠다. 나머지는 너가 찾아라

얕은복사

  let shallowCopy = function(obj) {
      let result = {};
      for(let prop in target){
          result[prop] = obj[prop];
      }
      return result;
  }

  or

  let obj = {a: 1, b: 20};
  let obj2 = {...obj}

깊은 복사

	let deepCopy = function(obj) {
    	let result = {};
        if(typeof obj === 'object' && target !== null){ // typeof는 null에 대해서도 'object' 를 반환하는 버그가 있다.
        	for(let prop in target){
            	result[prop] = deepCopy(obj[prop]);
            }
        } else {
            result = obj;
       	}
        return result;
    }
profile
나는 이윤환

0개의 댓글