JS에서 객체와 배열 복사하기_얕은 복사

holymoly.jun·2021년 6월 4일
3

JavaScript 완전 정복

목록 보기
3/5
post-thumbnail

객체의 얕은 복사와 깊은 복사 _ 얕은 복사편



객체의 복사

JS에서 변수에는 크게 객체(객체, 배열)와 객체가 아닌 원시값으로 구분할 수 있다. 객체가 아닌 변수 값에는 문자, 숫자, 그리고 boolean 등이 있으며, 이러한 원시값에는 참조 의 개념이 존재하지 않는다. (c 에서는 포인터로 참조했던 기억이..)
그러나, 객체에는 데이터 불변성을 유지시키기 위해 참조 의 개념이 존재한다. 객체에서 원시값처럼 = 을 통해 복사하게 된다면, 복사가 아닌 참조가 된다.
이와 같이, 참조의 개념으로 인해 JS에서는 객체의 복사본을 만든 뒤, 복사본에 대해서 수정할 때는 주의할 점이 여러가지 있다.

let arr = [1,2,3,4];
let copy = arr;

copy[0] = 'a'; 

console.log(arr); // ['a',2,4,5]
console.log(arr); // ['a',2,4,5]
console.log(arr === copy) // true

위와 같이, 객체의 복사본을 수정하게 되면 원본도 함께 수정이 된다. 그 이유는 객체는 값을 복사하는 것이 아니라, 참조 를 하기 때문이다.

또한, 이러한 참조 성질으로 인해 arr과 copy는 완전히 동일한 객체가 되면서 arr===copy 는 true가 되는 것이다.



1. 일반 객체(Object) 복사하기

1-1. assign 을 이용한 객체 복사

assign 첫번째 인자 값(대상 객체)에 빈 객체를 준다면, 두번 째 값에 들어오는 출처 객체가 그대로 복사된다.

let obj = { name : 'jun', age : 18 };
let copy = Object.assign({}, obj);

console.log(obj === copy) // false (참조가 아닌 복사이므로)

copy.name = 'kim';

console.log(obj); // { name : 'jun', age : 18 }
console.log(copy); // { name : 'kim', age : 18 }

  • 참고 _ Object.assign(obj1, obj2) :
    assign은 객체 메소드로써, obj1에 obj2를 덮어쓸 때 사용된다.
let obj1 = { name : 'jun', age : 18 };
let obj2 = { age : 26, job : 'student' };

Object.assign(obj1, obj2); // {name: 'jun', age: 26, job: 'student'}

1-2. Spread(...) 연산자를 이용한 객체 복사

비교적 최신 문법(ES6)인 spread 연산자는 간단한 코드 길이와 메소드 호출이 따로 필요 없어 빠른 처리가 가능하다.
Spread는 '펼치다'라는 뜻을 가지고 있다. 말 그대로 연산자 뒤의 객체를 펼쳐서 복사해 준다고 생각하면 편하다.

let obj = { name : 'jun', age : 18 };
let copy = { ...obj };

console.log(obj === copy) // false (참조가 아닌 복사이므로)

copy.name = 'kim';

console.log(obj); // { name : 'jun', age : 18 }
console.log(copy); // { name : 'kim', age : 18 }



2. 배열(Array) 복사하기

2-1. slice와 concat을 이용한 배열 복사

slice와 concat 함수에 인자값을 주지 않음으로써, 배열의 얕은 복사가 가능하다.

let arr = [1,2,3];
let copy1 = arr.concat();
let copy2 = arr.slice();

console.log(arr===copy1, arr===copy2) // false false

copy1[0] = 'a';
copy2[2] = 'c';

console.log(arr) // [1,2,3]
console.log(copy1) // ['a',2,3]
console.log(copy2) // [1,2,'c']

  • 참고 _ Array.prototype.slice(begin,end) :
    slice 함수는 index값이 begin부터 end 전까지 얕은 복사하여 새로운 배열을 반환한다.
let arr = [0,1,2,3,4,5];

console.log(arr.slice(2,4)); // [2,3]
console.log(arr.slice(3)); // [3,4,5]

  • 참고 _ Array.prototype.concat(arr2) :
    concat 함수는 기존 배열 뒤에 새로운 배열을 이어 붙혀, 새로운 배열을 반환한다.
let arr = [0,1,2];
let arr2 = [3,4,5];

console.log(arr.concat(arr2)); // [0,1,2,3,4,5]

2-2. Spread(...) 연산자를 이용한 배열 복사

위의 객체와 같이 spread 연산자를 이용하여 얕은 복사가 가능하다.

let arr = [1,2,3];
let copy = [...arr];

console.log(arr===copy) // false 

copy[0] = 'a';

console.log(arr) // [1,2,3]
console.log(copy) // ['a',2,3]]



출처

profile
Front-End Developer

0개의 댓글