- 9-1. [JavaScript] 자료형, 복사2023년 10월 27일 12시 03분 04초에 업로드 된 글입니다.작성자: 만두33
원시 타입과 참조 타입
자료형(type) : 값(value)의 종류 원시 타입 (primitive type) 참조 타입 (reference type) number, string, boolean, undefined, null, symbol 원시 자료형이 아닌 모든 자료형
(배열, 객체,함수 ...)* 원시 자료형을 변수에 할당시 메모리 공간에 값 자체가 저장
* 원시 값을 갖는 변수를 다른 변수에 할당시 원시 값 자체가 복사후 전달
* 원시 자료형은 변경 불가능한 값(immutable value)
즉, 한 번 생성된 원시 자료형은 읽기 전용(read only) 값특징 * 참조 자료형을 변수에 할당하면 메모리 공간에 주소값이 저장
* 참조 값을 갖는 변수를 다른 변수에 할당시 주소값이 복사후 전달
* 참조 자료형은 변경이 가능한 값(mutable value)JavaScript는 특별한 저장 공간에 참조 자료형을 저장한 후, 그 저장공간을 참조할 수 있는 주소값을 변수에 저장합니다.
이때 참조 자료형을 저장하는 특별한 저장 공간을 힙(heap)이라고 부르기도 합니다.
따라서 변수 arr에 해당하는 저장공간에는 주소값이 저장되어 있고, 그 주소값을 통해 참조 자료형에 접근할 수 있습니다.
이를 참조한다(refer)고 합니다.
원시 자료형은 원본(num)에 다른 값을 재할당해도 복사본(copiedNum)에 영향을 미치지 않습니다.
반면에 참조 자료형은 원본(arr)을 변경하면 복사본(copiedArr)도 영향을 받는 것을 확인할 수 있었습니다.
값 자체를 복사하는 원시 자료형과는 달리, 참조 자료형을 할당한 변수를 다른 변수에 할당할 경우 같은 주소를 참조하고 있기 때문입니다.참조 자료형을 변수에 할당하면 특정 저장 공간(heap)에 참조 자료형을 저장하고 그 공간의 주소를 변수에 저장한다.
배열 복사하기
- 원시 자료형이 할당된 변수를 다른 변수에 할당하면 값 자체의 복사가 일어난다. 따라서 원본과 복사본 중 하나를 변경해도 다른 하나에 영향을 미치지 않는다.
- 참조 자료형이 할당된 변수를 다른 변수에 할당하면 주소가 복사되어 원본과 복사본이 같은 주소를 참조한다.
- 참조 자료형의 주소값을 복사한 변수에 요소를 추가하면 같은 주소를 참조하고 있는 원본에도 영향을 미친다.
- 참조 자료형이 저장된 변수를 다른 변수에 할당할 경우, 두 변수는 같은 주소를 참조하고 있을 뿐 값 자체가 복사되었다고 볼 수 없다.
배열 복사 방법
- 배열 내장 메서드인 slice() 사용
- spread문법을 사용
Slice()로 복사하기
let arr = [0, 1, 2, 3]; let copiedArr = arr.slice(); console.log(copiedArr); // [0, 1, 2, 3] console.log(arr === copiedArr); // false
spread syntax로 복사하기
... + 변수명 으로 배열을 펼칠 수 있다.
let arr = [0, 1, 2, 3]; console.log(...arr); // 0 1 2 3
객체 복사하기
Object.assign()
객체를 복사하기 위해서는 Object.assign()을 사용한다.
let obj = { firstName: "mandoo", lastName: "an" }; let copiedObj = Object.assign({}, obj); console.log(copiedObj) // { firstName: "mandoo", lastName: "an" } console.log(obj === copiedObj) // false
얕은복사
spread syntax는 배열뿐만 아니라 객체를 복사할 때도 사용할 수 있습니다.
let obj = { firstName: "mandoo", lastName: "an" }; let copiedObj = {...obj}; console.log(copiedObj) // { firstName: "mandoo", lastName: "an" } console.log(obj === copiedObj) // false
slice(), Object.assign(), spread syntax 등의 방법으로 참조 자료형을 복사하면, 참조 자료형 내부에 중첩된 참조 자료형의 구조 중 한 단계까지만 복사합니다.
이것을 얕은 복사(shallow copy)라고 합니다.
깊은복사
JSON.stringify()와 JSON.parse()
JSON.stringify()는 참조 자료형을 문자열 형태로 변환하여 반환JSON.parse()는 문자열의 형태를 객체로 변환하여 반환
사용예시 = JSON.parse(JSON.stringify( ))
① 먼저 중첩된 참조 자료형을 JSON.stringify()를 사용하여 문자열의 형태로 변환
② 반환된 값에 다시 JSON.parse()를 사용
③ 깊은 복사와 같은 결과물을 반환
const arr = [1, 2, [3, 4]]; const copiedArr = JSON.parse(JSON.stringify(arr)); console.log(arr); // [1, 2, [3, 4]] console.log(copiedArr); // [1, 2, [3, 4]] console.log(arr === copiedArr) // false console.log(arr[2] === copiedArr[2]) // false
깊은 복사의 예외) 대표적인 예로 중첩된 참조 자료형 중에 함수가 포함되어 있을 경우 위 방법을 사용하면 함수가 null로 바뀌게 됩니다.
const arr = [1, 2, [3, function(){ console.log('hello world')}]]; const copiedArr = JSON.parse(JSON.stringify(arr)); console.log(arr); // [1, 2, [3, function(){ console.log('hello world')}]] console.log(copiedArr); // [1, 2, [3, null]] console.log(arr === copiedArr) // false console.log(arr[2] === copiedArr[2]) // false
외부 라이브러리 사용
완전한 깊은 복사를 반드시 해야 하는 경우라면, node.js 환경에서 외부 라이브러리인 lodash, 또는 ramda를 설치하면 됩니다.const lodash = require('lodash'); const arr = [1, 2, [3, 4]]; const copiedArr = lodash.cloneDeep(arr); console.log(arr); // [1, 2, [3, 4]] console.log(copiedArr); // [1, 2, [3, 4]] console.log(arr === copiedArr) // false console.log(arr[2] === copiedArr[2]) // false
정리
- 배열의 경우 slice() 메서드 또는 spread syntax 등의 방법으로 복사할 수 있다.
- 객체의 경우 Object.assign() 또는 spread syntax 등의 방법으로 복사할 수 있다.
- 위 방법으로 참조 자료형을 복사할 경우, 중첩된 구조 중 한 단계까지만 복사된다. (얕은 복사)
- JavaScript 내부적으로는 중첩된 구조 전체를 복사하는 깊은 복사를 구현할 수 없다. 단, 다른 문법을 응용하여 같은 결과물을 만들 수 있다.
- 대표적인 JSON.stringify()와 JSON.parse()를 사용하는 방법이 있지만, 예외의 케이스가 존재한다. (참조 자료형 내부에 함수가 있는 경우)
- 완전한 깊은 복사를 반드시 해야 하는 경우, node.js 환경에서 외부 라이브러리인 lodash, 또는 ramda를 사용하면 된다.
끝 😎
'💻 코드스테이츠 x 경남abclab > Section 1' 카테고리의 다른 글
11. DOM (1) 2023.11.01 10-2. [JavaScript] JavaScript Koans (0) 2023.10.30 9-2. [JavaScript] 스코프 (1) 2023.10.27 8-2. [JavaScript] 객체 (1) 2023.10.26 8-1. [JavaScript] 배열 (0) 2023.10.25 다음글이 없습니다.이전글이 없습니다.댓글