TIL 1 - 기본형 타입과 참조형 타입이 서로 다르게 동작하는 이유 :: study

UlongChaS2·2021년 8월 10일
0
post-thumbnail

위코드에선 수료하고 한달 동안 취업을 위한 세션이 있다. 스터디를 꾸려 원하는 책을 공부하며, 면접 출제 내용과 모의 면접을 서로 봐주는 시스템입니다.
고로 우리가 선택한 책은 코어 자바스트립트 - 정재남
JavaScript를 근본적인 것 부터 알고싶으면 이 책으로 공부하라는 말을 무수히 들은 추천이 많은 책입니다😃 그럼 시~작 🙌

데이터 타입의 종류

기본형

(원시형 : primitive type)

숫자, 문자열, 불리언, null, undefined, 심볼 (ES6에서 추가)

참조형

(reference type)

객체, 배열, 함수, 날짜, 정규표현식 등

기본형은 할당이나 연산시 복제, 참조형은 참조하는데 더 깊게 들여다보면
기본형은 값이 담긴 주솟값을 바로 복제, 참조형은 값이 담긴 주솟값들로 이루어진 묶음을 가르키는 주솟값을 복제한다.


🤔 데이터를 왜 유니크한 메모리 주솟값을 이용해서 저장해야할까?

메모리는 매우 많은 비트들로 구성되어 있으며, 고유한 식별자인 메모리 주솟값 통해 위치를 알 수 있다.
(여담으로 컴퓨터의 언어는 0, 1로 구성되어 있고 비트 단위로 위치를 찾는다면 매우 비효일적이게 된다.
그래서 사람들은 비트를 적당하게 묶어 검색 시간을 줄이는 방법을 생각해낸다. 그 단위다 이제 바이트이다.)


데이터 할당의 흐름

let a;		// 1️⃣ 변수 a 선언
a = 'abc';	// 2️⃣ 변수 a에 데이터 할당
let a = 'abc';	// 3️⃣ 1, 2를 한 문장을 표현
  1. 메모리에 비어있는 공간 확보, 그 공간의 식별자를 a라고 선언
  2. a라고 선언한 공간에 'abc'데이터를 넣은 주솟값을 할당

JavaScript에서 숫자형 데이터는 64비트로 정해진 공간을 확보하지만 문자열 같은 경우는 영어와 한글만 봐도 차지하는 비트 수가 달라 정해지지 않았기 때문에 용량과 전체 글자 수 모두 가변적이다.

미리 데어터 공간을 확보를 하고 있는 상황이라면 데이터가 변환되었을 때 그 크기에 맞춰 늘리는 작업이 계속 되어야한다.
또한 수정하는 데이터가 마지막에 있는 것이라면 단순히 늘리기만 하면 되지만 중간에 있는 데이터가 바뀌게 된다면 뒤에 저장된 데이터들을 전부 뒤로 옮기고 이동시킨 주소들을 식별자에 모든 것을 다시 연결시켜야하는 작업을 해야한다.

임으로써 값이 수정했을 때 무조건 새 별도의 공간을 만들어 저장하는 방법으로 하여 데이터 변환을 자유롭게 할 수 있게하고 메모리를 더욱 효율적으로 관리하기 위해서 값을 직접적으로 넣지않고 데이터를 따로 저장해서 그 주솟값을 연결해준다.

변수와 상수는 불변성 여부인가?

정말이 개념은 어려운데 변수와 상수는 불변성 여부로 나누어 지는게 아니다.
그럼 어떤 기점으로 나누어 지게 되는 걸까?

변수 / 상수의 구분

일단 이 두개를 구분하는 것은 변경 가능성에 초점을 둔다.

한 번 데이터 할당이 이뤄진 변수 공간에 다른 데이터를 재할당할 수 있는지 여부로 나누어 지게 된다.

오해할 수 있는게 상수는 보통 JS에선 const로 쓰는데 상수 자체가 불변값이 아니라 데이터의 기본형이 불변성을 가지는 것 이다.

불변성의 아닌 것의 차이는 뭘까?

가변값 불변값이란 것은 눈 앞에 보이지 않고 추상적으로 생각해야해서 몹시 까다로운데 정리를 해보자면

  • 기본형 : 기본형의 주솟값에 담긴 데이터는 바뀌지 않고 값이 바뀌게 되면 값이 담긴 데이터의 주솟값으로 바꾸는 것
  • 참조형 : 참조형의 주솟값은 데이터 묶음을 가르키는 또 다른 주솟값이라 데이터 묶음들이 각각 다른 주솟값으로 변환한다고 한들 식별자가 있는 공간의 주솟값은 그 전과 똑같은 참조의 주솟값을 가지고 있기에 바뀔 수 있는 가변 값이라 할 수 있다.

기본형 데이터 할당 흐름

let a = 'abc';	// 1️⃣ 
a = a + 'def';	// 2️⃣

let b = 5;	// 3️⃣ 
let c = 5;	// 4️⃣
b = 7;		// 5️⃣

1️⃣ 'abc'라는 데이터 주솟값을 식별자 a가 있는 공간에 주솟값으로 부여
2️⃣ 위의 'abc'의 데이터에 더하는게 아닌 새롭게 만들어 주솟값 부여

3️⃣ 5의 데이터 주솟값을 식별자 b에게 부여
4️⃣ 5라는 데이터가 있으니 그 주솟값을 c에게 부여
5️⃣ 7이란 데이터를 만들어 그 주솟값을 식별자 b에게 부여

참조형 데이터 할당 흐름

let obj1 = {		// 1️⃣ 
  a: 1,
  b: 'bbb'
}	
obj1.a = 2;		// 2️⃣

let nestingObj = {	// 3️⃣ 
  x: 3,
  arr: [ 3, 2 ],
};
nestingObj.arr = 'str';	// 4️⃣
  • 1️⃣, 2️⃣

  • 3️⃣ , 4️⃣

기본형과 참조형 변수의 복사 비교

변수를 복사하는 과정은 기본형과 참조형 데이터 모두 같은 주소를 가지고 있는 것은 동일 하지만 데이터 할당 과정에서 다르기에 변수 복사 이후의 동작에 큰 차이가 있다.

복수 이후 재할당 차이점

객체의 프로퍼티 변경시

let a = 10;
let b = a;
let obj1 = { c: 10, d: 'ddd' };
let obj2 = obj1;

b = 15;
obj2.c = 20;

프로퍼티 변경시 앞에 적었다 싶이 기본형은 데이터의 주솟값 참고형은 데이터 묶음의 주솟값을 가져와 기본형은 데이터가 바뀌니 주솟값이 바뀌게 되고, 참고형은 속 안 주솟값만 바뀌고 겉으로 보면 데이터 주솟값이 바뀌지 않기 때문에 다음과 같은 된다.

console.log(a === b);		// false
console.log(obj1 === obj2);	// ture

객체 자체를 변경했을 때

b = 15;
obj2 = { c: 20, d: 'ddd' };

console.log(a === b);		// false
console.log(obj1 === obj2);	// false

기본형은 말할 것도 없고 참조형 또한 데이터 자체를 변경하면 다른 값으로 된다.
다른 값으로 변형이 되는데 가변값이라고 할 수 있는 것은 그 내부의 프로퍼티를 변경했을 때만 성립하게 된다.

불변 객체로 왜 만들어야할까?

불변객체는(immutable object)는 3대 프레임워크나 라이브러리뿐만 아니라 함수형 프로그래밍, 디자인 패턴 등에서도 매우 중요한 기초가 되는 개념이다.

참조형이라도 기본형과 마찬가지로 데이터를 직접 변경하면 기존 데이터는 변하지 않는다. 이 말은 즉 내부 프로퍼티를 변경하면 기존 데이터도 변한다는 뜻이다.

값을 전달받아 내부가 변한다고 하더라도 원본 객체는 변하지 않아야하는 경우가 많은데 이 때 불변 객체가 필요하다.

let user = {
  name: 'hi',
  gender: 'female',
}

let changeName1 = function (user, newName) {
  let newUser = user;
  newUser.name = newName;
  return newUser;
}

let changeName2 = function (user, newName) {
  return {
    name: newName,
    gender: user.gender,
  }
}

let user2 = changeName1(user, 'bye');
let user3 = changeName2(user, 'hello again');

console.log(user.name, user2.name, user3.name);	// bye, bye, hello again
console.log(user === user2, user2 === user3);	// true, false

여기에서 다른 점은

  • changeName1 : 내부 프로퍼티를 그냥 바꿔서 결론은 기존 데이터의 내용도 바뀌었고
  • changeName2: 내부 프로퍼티를 들고와 새로운 {}안에 넣어줌으로써 새로운 객체가 생겼고 다른 주솟값을 보게 되어 다른 요소가 되었다.

위 코드의 아쉬운 점은 changeName2 안에 name과 gender가 하드 코딩 되었있다는 점이고 그 부분을 개선하기 위해선 모든 프로퍼티를 복사하는 함수를 만드는 편이 좋다.


책에선 얕은 복사와 깊은 복사 내용이 나오는데 다른 블로그 내용과 머릿속으로 정리를 해야해 상당히 길어질 것 같아 다음 편에 또 써야할 것 같다.


0개의 댓글

관련 채용 정보