Array & Immutable

August 15, 2022

배열과 불변성에 대해

첫번째 질문.

const arrayOne = ["a", "b", "c"];
const arrayTwo = ["a", "b", "c"];

Boolean(arrayOne === arrayTwo); // 반환되는 값은 true, false 중 무엇일까?

해당 질문의 답을 알기 위해선 배열의 메모리 저장위치불변성에 대해 알 필요가 있다.

아래의 그림을 보면

immutable-1

arrayOnearrayTwo의 배열의 메모리 저장 위치가 다르다.

그렇기 때문에 Boolean(arrayOne === arrayTwo)의 값은 false이다.


두번째.

let array = ["a", "b", "c"];
let copyArr = array;

Boolean(array === copyArr); // 반환되는 값은 true, false 중 무엇일까?

immutable-2

arraycopyArr는 메모리의 같은 위치를 가리키고 있기 때문에 true이다.

같은 위치를 공유하고 있기에 copyArr에 문자열 ‘d’를 추가하면 array에도 문자열 ‘d’가 추가 되어 ****

[’a’, ‘b’, ‘c’, ‘d’]가 된다.

여기서 유의하여 볼 점은 원본배열의 수정이다.

let array = ["a", "b", "c"];
let copyArr = array;

copyArr.push("d");
array = ["a", "b", "c", "d"];
copyArr = ["a", "b", "c", "d"];

// 같은 공간의 메모리를 참조하기 때문에 함께 변화한다.
// 원본 배열인 array에도 'd'가 추가되었다.

push라는 메소드를 통해 원본 배열이 수정되어 불변성이 훼손되었다.

배열의 메소드엔 불변성을 지키는 메소드(원본 배열을 수정하지 않는)와 불변성을 훼손하는 메소드(원본 배열을 수정하는) 메소드가 존재한다.

아래엔 각 해당하는 메소드 4가지씩을 소개하고자 한다.


Array method

불변성을 훼손하는 4가지 메소드(원본 배열을 수정하는)
  • unshift method : 배열의 첫 번째 위치에 새로운 요소를 추가하여, 추가된 배열을 반환한다.
let array = ["a", "b", "c"];
let copyArr = array;

copyArr.unshift("zero"); // copyArr란 배열의 0번째 인덱스에 문자열 'zero'를 추가한다.

// 원본 배열(array)도 수정된다.
copyArr = ["zero", "a", "b", "c"];
array = ["zero", "a", "b", "c"];
  • shift method : 배열의 첫 번째 요소를 제거한 뒤, 제거한 요소를 반환한다.
let array = ['zero', 'a', 'b', 'c']
let copyArr = array

copyArr.shift() // copyArr란 배열의 0번째 인덱스에 문자열 'zero'를 제거한다.

**// 원본 배열(array)도 수정된다.
copyArr = ['a', 'b', 'c']
array = ['a', 'b', 'c']
  • push method : 배열의 마지막에 새로운 요소를 추가하여, 추가된 배열을 반환한다.
let array = ["a", "b", "c"];
let copyArr = array;

copyArr.push("d"); // copyArr란 배열의 0번째 인덱스에 문자열 'd'를 추가한다.

// 원본 배열(array)도 수정된다.
copyArr = ["a", "b", "c", "d"];
array = ["a", "b", "c", "d"];
  • pop method : 배열의 마지막 요소를 제거한 뒤, 제거된 요소를 반환한다.
let array = ["a", "b", "c"];
let copyArr = array;

copyArr.pop("d"); // copyArr란 배열의 0번째 인덱스에 문자열 'd'를 제거한다.

// 원본 배열(array)도 수정된다.
copyArr = ["a", "b", "c"];
array = ["a", "b", "c"];

불변성을 지키는 메소드(원본 배열을 수정하지 않는)

기존의 배열을 수정하지 않는(원본유지) 메소드 : slice, split, join, concat

  • slice method : 배열의 일부분을 잘라내어 새로운 배열을 반환한다.
let array = ["a", "b", "c", "d"];
let copyArr = array;

copyArr.slice(start, end); // slice의 첫번째 파라미터는 자르고 싶은 배열의 인덱 시작지점이고,
copyArr.slice(0, 1); // 두번째 파라미터는 자르고 싶은 배열의 인덱스 종료지점이다.

// 원본 배열(array)이 수정되지 않는다.
copyArr = ["a", "b"];
array = ["a", "b", "c", "d"];

그럼 위에서 언급되는 불변성은 무엇일까?

Immutability (불변성)

불변성은 기존의 값을 그대로 유지하면서 새로운 값을 추가하거나 제거하는 것으로 객체가 생성된 후 상태를 변경할 수 없는 디자인 패턴을 의미한다.

불변성이 중요한 이유는 불변성을 지키지 않고 코드를 작성하면 데이터들이 어디서 변화하는지 흐름을 따라가기 어려워 sideEffect나 버그를 유발한다.

불변성을 지키며 코드를 작성하면 불필요한 sideEffect나 버그를 피할 수 있고 협업하는 과정에서도 데이터가 바뀔 것이라는 불필요한 의심없이 코드를 설계할 수 있기 때문에 중요하다 볼 수 있다.