[JS] 원시 자료형과 참조 자료형

초코침·2023년 3월 2일
0

JavaScript

목록 보기
9/26

원시 자료형과 참조 자료형

JavaScript의 7가지 데이터 타입(숫자, 문자열, 불리언, null, undefined, 심벌, 객체 타입)은 원시 타입(primitive type)과 객체 타입(object/reference type)으로 구분할 수 있다. 이때 원시 타입과 객체 타입은 크게 세 가지 측면에서 다르다.

  • 원시 타입의 값, 즉 원시 값은 변경 불가능한 값이다. 이에 비해 객체 타입의 값, 즉 객체는 변경 가능한 값이다.
  • 원시 값을 변수에 할당하면 변수에는 실제 값이 저장된다. 이에 비해 객체를 변수에 할당하면 변수에는 참조 값이 저장된다.
  • 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달된다(값에 의한 전달). 이에 비해 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다(참조에 의한 전달).
원시 타입객체 타입
변경 불가능한 값변경 가능한 값
실제 값이 저장됨참조 값이 저장됨
값에 의한 전달(원시 값 복사)참조에 의한 전달(참조 값 복사)

Call By Value

변수(b)에 원시 값을 갖는 변수(a)를 할당하면 할당받는 변수(b)에는 할당되는 변수(a)의 원시 값이 복사되어 전달되는데 이를 값에 의한 전달이라 한다. a와 b의 값은 동일하지만 서로 다른 메모리 공간에 저장된 별개의 변수이다. 따라서 각 변수에 재할당이 발생해도 서로 간 영향을 주고 받지 않는다.

let a = 100;
let b = a;

Call By Reference

객체를 가리키는 변수(a)를 다른 변수(b)에 할당하면 원본의 참조 값이 복사되어 전달되는데 이를 참조에 의한 전달이라 한다. a와 b는 서로 다른 메모리 공간에 동일한 주소 값을 가지고 있어 결과적으로 동일한 값을 참조하게 된다. 따라서 서로 영향을 주고받게 된다.

let a = [ 1, 3, 5, 7 ]
let b = a;

얕은 복사와 깊은 복사

얕은 복사(Shallow Copy)

객체를 프로퍼티 값으로 갖는 객체의 경우, 한 단계까지만 복사하는 것을 얕은 복사라고 한다.

a가 갖는 주소 값에 해당하는 값을 b에 얕은 복사하게 되면 a와 b는 서로 다른 메모리 공간에 동일한 값을 갖게 되어 서로 영향을 미치지 않아 보일 수 있으나, 값이 되는 객체 안에 중첩되어 있는 또 다른 객체까지는 복사가 되지 않아 중첩된 객체는 동일한 참조 값을 갖는다. 따라서 a와 b는 여전히 서로 영향을 주고받는 관계다.

깊은 복사(Deep Copy)

객체에 중첩되어 있는 객체까지 모두 복사하는 것을 말한다.

복사하기

배열 복사하기

  1. slice() 사용하기 → 얕은 복사
  2. spread syntax 사용하기 → 얕은 복사

  3. JSON.parse(JSON.stringify(ARRAY)) 사용하기 → 깊은 복사

    단, 중첩된 자료형 중 함수가 존재하는 경우 함수가 null로 바뀌기 때문에 완전한 복사 방법이라고 볼 수는 없다.

  4. 외부 라이브러리 사용(lodash, ramda)

객체 복사하기

  1. Object.assign() 사용하기 → 얕은 복사
  2. spread syntax 사용하기 → 얕은 복사
  3. JSON.parse(JSON.stringify(OBJECT)) 사용하기 → 깊은 복사
  4. 외부 라이브러리 사용(lodash, ramda)

Call By Sharing?

결국 값에 의한 전달참조에 의한 전달은 전달하는 것이 원시 값이냐 주소 값이냐의 차이지, 결국 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 전달한다는 면에서 동일하다. 따라서 엄밀히 말하면 자바스크립트에서는 값에 의한 전달만이 존재한다고 말할 수 있다. 이런 이유로 두 가지를 구분하지 않고 공유에 의한 전달이라고 표현하기도 한다.

profile
블로그 이사중 🚚 (https://sungjihyun.vercel.app)

0개의 댓글