TIL. 데이터타입에 대한 이해

FE_JACOB 👨🏻‍💻·2021년 9월 12일
0

Today I learned

목록 보기
24/30

DATA TYPE에 대한 이해

코어자바스크립트를 읽고..

데이터 타입의 종류

데이터 타입에는 기본적으로 2가지가있다.
기본형(원시형) : Boolean, Number, String, null, undefined, symbol
참조형 : 객체, 배열, 함수, 날짜, 정규표현식등

데이터를 복제를 할때 가장 큰 차이점은 기본형은 값이 담긴 주솟값을 복제하는 반면 참조형은 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제한다.

정확하지만 이해하기 어렵게 적어놨다. 그래서 천천히 데이터의 선언과 할당이 어떻게 이루어지는지 파악할 필요가 있다.

📌변수 선언 및 데이터 할당

평소 데이터를 선언할때 바로 값을 할당하곤한다.

let a = 10

하지만 실제 데이터가 선언되고 할당되는 순서는 아래와 같다.

let a;
a = 10

이렇게 봤을때 우선 a 라는 변수를 선언함과 동시에 메모리 어느한곳에(쉽게 메모리주소라고 칭함) 저장을 한다.
예를들어 메모리주소 1번 - a 이런식으로.

그리고 값을 할당을 하게되면 값을 저장하는 한 주소(쉽게 데이터주소라고 칭함) 데이터주소 1번 - 값 : 10 를 저장한다.

이를 합치면
메모리주소 1번 - 이름: a, 값: 데이터주소 1 이렇게 저장이 된다.

즉, 내가 값을 변경하면 실제 값이 변경되는게 아닌 값에 저장되어있는 데이터주소 값이 변경되는것이다.

let a = 10
a = 20

이런상황이라면
메모리주소 1번 - 이름: a, 값: 데이터주소 1 가 있고
데이터주소 1 - 값: 10 이었다가 20을 a 에 할당함과 동시에 20이라는 값이 데이터주소에 있는지 확인하고 없으면
데이터 주소 2 - 값: 20을 만들고
메모리주소 1번 - 이름: a, 값: 데이터주소 2 로 저장을 다시한다.

📌불변값이란?

불변값은 이름에서도 알수있다시피 값을 변경할 수 없다. 기본형 데이터는 모두 불변값이다. 그렇다고해서 불변값 = 상수 ❌다.

값이 변하지 않는다 라는 뜻을 깊게 이해할 필요가 있다. 이전에 변수에 값을 재할당 했을때를 돌이켜보면 메모리의 값이 바뀌는게 아닌 값을 저장해둔 주소를 바꾼다.

let a = 10
a = 20

이렇게 바꿨을때 10이 저장된 주소에 20으로 바꾸는게 아닌 20을 새로운 메모리 주소에 저장을 하고 그 a 의 값 10이 저장되어있는 주소를 20이 저장되어있는 주소로 바꿔준다. 결국 원래있던 10은 없어지지 않는다. 10을 다시 20으로 바꾸는것도 아니다. 이를 불변값이라고 한다.

상수는 재선언, 재할당이 불가능하다. 그래서 불변값이라고 착각 할 수있는것이다.

const a = 10;
a = 20 (불가능)

📌가변값이란?

참조형데이터는 가변값이다. 참조형데이터 할당에 대해서 설명을하면 내부 프로퍼티를 저장하고 그 값의 주소를 또 저장한다.

let obj = {
	name: "Jacob"
}

이 상황에서
메모리주소1 - 이름: obj, 값: 데이터주소1 이라는 메모리 주소가 하나 생기고 그 안에 값들을 저장한다.
그리고 변수를 저장할 메모리 주소를 만든다. (메모리 이름은 변수주소 라고 칭한다)
변수주소 1 - 이름: name, 값: 'Jacob' 를 만들고
데이터주소1 - 값: 변수주소1 이렇게 변수주소를 데이터주소에 값으로 첨부한다.

이런상황에서 만약 내가 이름을 바꾼다면?

let obj = {
	name: "Jacob"
}

obj.name = "Jun"

이렇게 바꿔도
메모리주소1 - 이름: obj, 값: 데이터주소1 는 바뀌지 않는다. 데이터주소1 안에 Jacob 값을 가지고 있는 주소가 바뀌는 것이다. 즉, 불변값처럼 새로운 값, 객체가 생성되는게 아닌, 내부 프로퍼티의 값만 바뀐것이다. 그래서 가변값이라고 한다.

📌 중간정리

데이터에는 기본형과 참조형이 있다.
기본형 = 불변값 => 값을 재할당할때 새로운 값을 만들어서 재할당한다.
참조형 = 가변값 => 값을 재할당할때 객체를 새로 만들지 않고 내부 프로퍼티만 값이 변한다.

📌복사하는 방법

기본형:

let a = 10
let b = a

a = 20 
console.log(a === b) // false

참조형:

let obj1 = {
  name : "Jacob"
}
let obj2 = obj1

obj2.name = "Jun"

console.log(obj1 === obj2) // true
console.log(obj1.name === obj2.name) // true

이 두가지가 다른 이유는 기본형은 불변값이기 때문에 참조형은 가변값이기 때문이다.

기본형은 복사 후 재할당을 했을때 새로운 값으로 만들어지기 때문에 두개는 전혀 다른값이 되는것이다.
하지만 참조형은 애초에 주소값을 서로 공유를 했기때문에 하나의 obj2 의 값들이 담겨있는 내부 주소값만 바뀌는것일뿐 객체는 그대로이다.

참조형을 불변값으로 사용하기 위해서는 immutable.js 등 라이브러리를 사용하면 가능하다.

참조형을 불변하게 사용하고 싶으면 아예 새로운 객체를 return해주면 된다.

let user = {
  name : "Jacob"
}

const changeName = (user) => {
	return {
    name: user.name
    }
}

let user2 = changeName(user)

console.log(user === user2) //false

📌 얕은복사와 깊은복사

객체안에 중첩해서 값을 할당했을 경우 복사할때 두가지 방법이 존재한다.
위와 같은 방법은 얕은 복사다.
만약 객체의 내부 프로퍼티가 중첩되어 사용된다면 ?

우선 불변성을 적용하는 방법

let user = {
	name : "Jacob",
  	url : {
      youtube : "https...."
    }
}
const changeName = (user, newName) => {
	return {
    name : newName,
    url: user.url
  }
  
}

let user2 = changeName(user, "Malon")
user2.name = "haha"
user2.url.youtube = ""
console.log(user.name === user2.name) //false
console.log(user.url.youtube === user2.url.youtube) //true

얕은 복사로는 중첩된거는 복사를 못한다.

깊은복사

	let copyObj = (target) =>{
	let result ={}
	if(typeof target === 'object' && target !== ''){
	    for (let prop in target){
	      result[prop] = copyObj(target[prop])
	    }
	  }else{
	    result = target
	  }
	   return result
	 }

이렇게 하거나 JSON을 이용해서 하는 방법도 있다.

profile
단순히 개발자로서 제게 있었던 일을 적는 공간입니다 ✍🏻

0개의 댓글