이 포스팅을 이해하기 위해서는 Array.prototype.slice()
에 대한 선행학습이 필요하다
우선 설명을 읽어보자
copyWithin() 메서드는 ES6에서 도입된 새 메서드이다. 배열의 일부를 얕게 복사한 뒤, 동일한 배열의 다른 위치에 덮어쓰고 그 배열을 반환한다. 이 때, 크기(배열의 길이)를 수정하지 않고 반환한다.
설명을 읽어봐도 잘이해가 되지 않는다.
나는 이 메서드를 복사후 덮어쓰기 메서드라고 부르고 싶다.
arr.copyWithin(target[, start[, end]])
설명이 이해가 되지 않아서 몇번 사용해 보니, 첫 번째 매개변수는 splice
의 첫 번째 매개변수처럼 동작하고, 두 번째와 세 번째 매개변수는 slice
의 첫 번째 매개변수와 두 번째 매개변수처럼 동작한다.
그래서 두 번째 매개변수 이상, 세 번째 매개변수 이하를 복사하고, 음수 인덱스도 사용 가능하다.
const arr = [1, 2, 3, 4];
arr.copyWithin(1, 2); // arr[1]에 arr.slice(2)를 붙혀넣는다.
console.log(arr); // [1, 3, 4, 4]
첫 번째 예제를 보고 무척 혼란스러웠다.
오히려 예제를 보다보니 동작 원리가 더 헷깔렸다.
예제가 동작하는 방식은 우선 세 번째 인자가 없으니, arr[2]
부터 끝까지 복사한다.
그러면 3, 4
가 복사되었을 것이다.
그리고 첫 번째 인자의 위치인arr[1]
에 붙혀넣기를 하는 것이다.
그러므로 arr
는 [1, 3, 4, 4]
가 된 것이다.
const arr = [1, 2, 3, 4];
arr.copyWithin(2, 0, 2); // arr[2]에 arr.slice(0, 2)를 붙혀넣는다.
console.log(arr); // [1, 2, 1, 2]
이번에는 세 번째 인자가 존재한다.
copyWithin
의 두 번째 인자 이상 세 번째 인자 이하를 복사함으로 1, 2
가 복사되었다.
그리고 이 복사된 1, 2
를 arr[0]
의 자리에 붙혀넣기한다.
그러므로 arr
는 [1, 2, 1, 2]
가 된 것이다.
const arr = [1, 2, 3, 4];
arr.copyWithin(1); // arr[1]에 arr.slice()를 붙혀넣는다. 단, 배열의 길이를 변화시키지 않는다.
console.log(arr); // [1, 1, 2, 3]
이번에는 두 번째 인자와 세 번째 인자 모두 존재하지 않는다.
그러면 arr[1]
위치에 아무것도 붙혀넣지 않는 것이라고 생각할 수도 있다.
copyWithin
은 그렇게 동작하지 않는다.
두 번째와 세 번째 인자가 모두 없으면 arr.slice()
처럼 동작한다. 배열의 전체를 복사한다는 뜻이다.
그리고 첫 번째 인자가 가르키는arr[1]
번 위치에다가 붙혀넣기를 한다.
하지만 여기서 주의해야할 사항이 있다. 바로 배열의 길이를 수정하지 않는다는 것이다.
이게 무슨 말이냐면 배열의 끝을 만나면 붙혀넣기를 중단한다는 것이다.
그래서 arr.slice()
를 해서 1, 2, 3, 4
를 복사했지만, 4
를 붙혀넣을려면 배열을 넘어가서 4
는 붙혀넣지 못하는 것이다.
이 동작을 다 이해하면 copyWithin
을 다 알게 된 것이다.
아서브라운 - 러닝 자바스크립트: ES6로 제대로 입문하는 모던 자바스크립트 웹 개발
MDN - copyWithin