Primitive Type / Reference Type

Rock Kyun·2023년 10월 31일
2
post-custom-banner

오늘 했던 것

  • React 기초 학습
  • Reference Type 데이터 학습

Data Type

  • 자바스크립트의 데이터 타입은 원시타입과 참조 타입 자료형이 있다.
    Primitive Type / Reference Type

  • 두 타입의 차이점은 실제 데이터를 저장하느냐 (Primitive)
    데이터가 담긴 메모리의 주소 값을 저장하느냐이다. (Reference)

Primitive Type(원시 타입)

  • Primitive Type 자료형은 변수 선언, 초기화, 할당 시
    데이터가 저장 된 메모리 영역에 직접 접근한다.
  • 변수에 새 데이터가 재할당 될 경우
    새로운 메모리 영역에 재할당 된 데이터를 저장한다.

종류

  • Number
  • String
  • Boolean
  • null
  • undefined

Primitive Type의 복사

  • Primitive Type은 복사 시 데이터 값이 복사된다
<.js>
let a = 10; // Primitive Type 데이터 할당
let b = a; // Primitive Type 복사

a = 15; // Primitive Type 재할당

console.log(a, b, a === b);
// 출력 결과: 15, 10, false
// b는 복사해뒀던 a의 값을 그대로 유지하고 있다.
// a와 b는 서로 다르다.

Reference Type (참조 타입)

  • 변수가 가지고 있는 메모리 주소를 이용해서 변수의 값에 접근한다.
  • 변수에 데이터 할당 시
    값이 직접 저장되는 것이 아닌 데이터가 저장 된 메모리의 주소가 저장된다.

종류

  • Array
  • Object
  • Function

Reference Type의 복사

  • Reference Type을 복사할 경우
    값이 저장 된 메모리의 주소 값이 복사된다.
  • 복사한 Reference Type을 변경하면 원본 데이터도 같이 변경된다.
  • 복사한 데이터는 원본 데이터의 주소 값을 복사한 것이기 때문에
    복사한 Reference Type 데이터를 변경하면
    원본 Reference Type 데이터가 저장 된 메모리 주소를 참조하여
    접근하고 해당 주소에 있는 데이터의 값을 변경하는 것인데
    결과적으로 원본 데이터에 접근하고 원본 데이터를 변경하는 것과 같은 것이다.
let data = { // Reference Type 데이터의 변수
  name: 'lee',
  age: 20,
}

let newData = data; // 원본 Reference Type 데이터(주소 값)를 복사한 변수

newData.name = 'kim' // 복사한 Reference Type 데이터의 값 변경

console.log(data, newData)
// 출력 결과: { name: 'kim', age: 20 }, { name: 'kim', age:20 }
// 복사본과 원본이 모두 변경 되어버림

console.log(data === newData) // true

Reference Type을 복제하려면

  • Reference Type을 복제하려면
    원본과 다른 메모리 주소를 가진 변수를 만들어야 하는데
    그 방법으로는 얕은 복사깊은 복사가 있다.

얕은 복사

  • Reference Type 데이터 안에 중첩 된 Reference Type의 데이터가 없을 때 (2차원 객체가 아닐 때)

1. spread Operator(전개구문 연산자) 사용

<.js>
  
let data = {
  name: 'lee',
  age: 20,
}

let newData = {...data};
// spread Operator(전개구문 연산자)로 값을 모두 풀어서 {}안에 담는다.

newData.name = 'kim';

console.log(data, newData);
// 출력 결과: {name: 'lee', age: 20}, {name: 'kim', age: 20}

console.log(data === newData);
// 출력 결과: false

2. Object.assign() 사용

MDN 공식문서: Object.assign

<.js>

let data = {
  name: 'lee',
  age: 20,
}

let newData = Object.assign({}, data); 
// Object.assign(반환 할 객체, 반환 할 객체에 담고 싶은 속성)

newData.name = 'kim';

console.log(data, newData);
// 출력 결과: {name: 'lee', age: 20}, {name: 'kim', age: 20}

console.log(data === newData);
// 출력 결과: false

깊은 복사

  • Reference Type 데이터 안에 중첩 된 Reference Type 데이터가 있을 때
    (2차원 객체)

1. 재귀함수를 사용

<.js>
  
function deepCopy(object) {
  // 만약 인자로 들어온 데이터가 null 이거나
  // 자료형의 type이 object가 아니라면
  // 인자로 들어온 object를 그대로 return
  if (object === null || typeof object !== "object") {
    return object;
  }

  // 만약 들어온 데이터의 type이 Reference Type(object || Array || Function)이면
  // 빈 객체를 만든 후
  // 인자로 들어온 object의 속성만큼 돌며
 //  함수 스스로를 호출하여 복사 된 값을 반환한다.
  let copy = {};
  for (let key in object) {
    copy[key] = deepCopy(object[key]);
  }
  return copy;
}

let data = {  // 2차원 객체 (중첩 객체)
  name: 'lee',
  age: 20,
  hobby: {hobby1: 'meditation'}
}

let newData = deepCopy(data) // 재귀함수로 깊은 복사 진행

newData.name = 'kim'; // name 속성 변경
newData.hobby.hobby1 = 'piano'; // hobby 배열의 0번 인덱스 변경

console.log(data === newData); // 출력 결과: false
console.log(data, newData); 
// 출력 결과:
// {name: "lee" age: 20, hobby: { hobby1: 'meditation'}} 
// {name: 'kim', age: 20, hobby: { hobby1 : 'piano'}}
post-custom-banner

0개의 댓글