Javascript

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

JeanneLee57 2023. 3. 2. 13:05

 

 

1. 원시 자료형 vs 참조 자료형

2. 원시 자료형

2-1. 변경 불가능한 값

2-2. 변수에 실제 값을 저장

2-3. 값에 의한 참조

3. 참조 자료형

3-1. 변경 가능한 값

3-2. 변수에 참조 값을 저장

3-3. 참조에 의한 전달

 

1. 원시 자료형 vs 참조 자료형

  원시 자료형 참조 자료형
타입 숫자, 문자열, 불리언, BigInt, null, undefined, 심벌 객체(배열 포함)
변경 변경 불가능(immutable) 변경 가능(mutable)
변수 할당 방식 변수에 실제 값을 저장 변수에 참조 값을 저장
복사 방식 원시 값 자체를 복사(값에 의한 전달) 참조 값을 복사(참조에 의한 전달)

 

2. 원시 자료형

2-1. 변경 불가능한 값

원시 자료형은 변경 불가능한 값이다.

변수에 값을 한번 할당하면 그 값은 바꿀 수 없다.

변수에 새로운 값을 재할당할 때, 자바스크립트 엔진은 새로운 메모리 공간를 확보해 그 값을 저장한다.

처음 할당한 값은 더 이상 변수에 의해 참조되지 않을 뿐, 그 값이 변한 것은 아니다.

 

2-2. 변수에 실제 값을 저장

이처럼 변수에는 원시 자료형의 실제 값이 저장된다.

이것은 참조 자료형에서 변수에 실제 값이 아닌 참조 값이 저장되는 것과 구별된다.


2-3. 값에 의한 전달

원시 자료형이 할당된 변수를 다른 변수에 할당할 경우,

자바스크립트 엔진은 새로운 메모리 공간을 확보하고, 원래 변수에 있던 값 그 자체를 복사해서 새로운 공간에 저장한다.

따라서 두 변수는 서로 다른 메모리 공간에 저장돼 있고, 한 변수의 값을 변경해도 다른 변수 값에 영향을 주지 않는다.

 

3. 참조 자료형

3-1. 변경 가능한 값

참조 자료형은 변경 가능한 값이다.

변수에 객체를 할당한 이후에도 자유롭게 프로퍼티를 추가, 삭제할 수 있다.

 

3-2. 변수에 참조 값을 저장

변수에 참조 자료형을 할당하면 그 변수에는 객체가 들어 있는 메모리 주소(참조 값)이 저장된다.

객체를 할당한 변수를 참조하면 그 참조 값을 통해 실제 객체에 접근하게 된다.

 

3-3. 참조에 의한 전달

객체가 할당된 변수를 다른 변수에 할당하면 원본의 참조 값이 복사돼 저장된다.

따라서 두 개의 변수는 동일한 참조 값을 갖는 서로 다른 변수가 된다.

두 개의 변수가 같은 메모리 공간을 참조하고 있기 때문에 하나의 변수를 통해 객체를 변경하면

다른 변수를 통해 참조했을 때도 변경된 객체가 나타나게 된다.

 

4. 얕은 복사와 깊은 복사

4-1. 배열의 복사

배열은 slice 메서드spread 연산자로 복사할 수 있다.

어떤 방식을 사용하든 복사본과 원본은 서로 다른 주소값을 가지게 된다.

즉, 서로 다른 주소값을 가진 서로 다른 배열이 생성된다.

하나를 변경해도 다른 하나에 영향을 미치지 않는다.

 

4-2. 객체의 복사

객체는 배열과 마찬가지로 slice 메서드, spread 연산자로 복사할 수 있고

Object.assign을 사용해서도 복사할 수 있다.

어떤 방식을 사용하든 복사본과 원본은 서로 다른 주소값을 가지게 된다.

 

그러나 이 방식들은 얕은 복사만을 수행한다.

참조 자료형 내부에 또다른 참조 자료형이 중첩돼 있을 경우

중첩된 객체는 참조에 의한 전달만 이뤄진다.

즉, 같은 주소값을 참조하는 객체가 만들어지기 때문에

한 객체를 변경했을 때 다른 객체도 마찬가지로 변하게 된다.

 

만약 이런 효과를 피하기 위해 깊은 복사를 수행하려 한다면

JSON.stringify()JSON.parse()를 사용할 수 있다.

그러나 이 방법 또한 함수가 포함되어 있을 경우 null로 바뀌는 단점이 있다.

완전한 깊은 복사를 반드시 해야 하는 경우라면, 외부 라이브러리인 lodash, 또는 ramda를 이용한다.