TIL

2024.01.18 TIL #Spread Operator #Splice(a,b,c) #forEach와 for문의 return

inz1234 2024. 1. 18. 23:23

1. ... Spread Operator (전개연산자)

- let str = "12345" 일 때 [ ...str ] 은 뭐가 될까?

  (1) 하나의 문자열을 배열에 담았으니 [ 12345 ] 이렇게 한번에 들어갈까?

  (2) 아니면 배열로 넣는 거니까 [ '1', '2', '3', '4', '5' ] 일까?

 

  =>  정답은 (2)   [ '1', '2', '3', '4', '5' ]  이다.

 

- let arr1 = [ a,b,c,d,e ] 일 때, (1)번과 (2)은 뭐가 다를까?

  (1)  arr2 = arr1 

  - arr1 의 주소를 arr2 주소에 할당함 

    즉, 두 배열의 데이터 저장 주소가 같아짐

  - 둘 중 하나가 변경되면 둘 다 변경 되어버림

 

  (2)  arr2 = [ ...arr1 ]  : 얕은 복사

  - 새로운 배열을 만들어서 그 내용물을 arr2와 같게 함

    즉, 새로운 저장공간을 만들기 때문에 다른 주소를 갖게 됨

  - arr1의 내용이 변경되어도 arr2의 내용이 변하지 않음. 하지만 이것은 언제까지나 배열의 요소가 숫자가 문자일 때만!!

 

  - 만약 arr1의 요소가 배열 또는 객체일 때는 얘도 이야기가 달라진다.

 let arr1 = [ { a: 1 }, { b: 2 } ];
 let arr2 = [ ...arr] ;

 arr1 [ 0 ]. a = 99;

 console. log ( arr2 [0]. a); // 출력: 99

 

이렇게 arr 의 요소가 객체나 배열일 때는 이 방법도 arr 2가 arr 1의 변경사항에 영향을 받는다.

 

그렇기 때문에 Spreator Operator를 이용한 복사는 얕은 복사로, 배열이나 객체 안에 있는 요소가 그냥 하나의 숫자나 문자면 상관 없지만, 그 안의 요소가 또 다른 배열이나 객체라면 (1)번 방법처럼 변경사항에 복사된 대상도 영향을 받는다.

깊은 복사를 사용해야 한다. 이건 다음 TIL에 다루겠다.

 

 

2. splice( a, b, c )

- 저번 TIL에서 splice를 한 번 다루기는 했는데, 추가로 알게된 점이 있어서 기록한다.

  a : 제거를 시작할 index => 숫자

  b : 제거하고자 하는 요소의 갯수

  c : 추가할 요소 단, a번째 앞에 추가가 된다.

 
 let fruits = ["apple", "banana", "cherry"];

 // 인덱스 1에 "orange"를 추가
 fruits.splice(1, 0, "orange");

 console.log(fruits);
 // 출력: ["apple", "orange", "banana", "cherry"]
 

 

이와 같이 "orange""banana"  뒤에 가 아니라, 앞에 추가된다.

 

- 또한, 제거된 요소들의 배열이 반환된다.

위에서 console.log(  fruits.splice(1, 1, "orange");  )를 하면 콘솔창에 ["orange"] 가 반환된다.

따라서 반환 또는 출력을 할 때 무엇을 반환하고 싶은지 - 제거된 요소들의 배열을 반환하고 싶은 건지, 제거된 후의 원본배열을 반환하고 싶은건지 잘 생각해서 

console.log( fruits.splice(1, 0, "orange");  ) 또는

console.log(fruits);

를 잘 출력해야 한다.

3. forEach 문과 for문 에서의 return

(1) forEach 문에서의 return

  - forEach 메서드에서 return을 사용하면 해당 loop만 중단되고, 다음 요소에 대한 loop는 계속 진행

예를 들면,

 
 let arr = [1, 2, 3, 4, 5];
 
 function A(arr) {
  arr.forEach((num) => {
    if (num === 3) {
      console.log("Skipping 3");
      return; // 중단되지만 다음 요소로 계속 진행
    }
    console.log(num);
  });
 }

  A([1, 2, 3, 4, 5]);  // 출력 결과: 1, 2, Skipping 3, 4, 5
 

 

(2) for 문( 일반 for문 + for ... of arr ) 에서의 return

- for 루프에서 return을 사용하면 해당 함수 전체가 중단되어 루프를 포함한 함수의 실행이 즉시 종료된다.

 
 function B(arr) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === 3) {
      console.log("Stopping at 3");
      return; // 함수 전체가 중단됨
    }
    console.log(arr[i]);
  }
 }

 B([1, 2, 3, 4, 5]);  // 출력 결과: 1, 2, Stopping at 3
 
 

 

 

=> 그렇기 때문에 forEach 문에서 return문을 쓰면 그냥 그 순번만 지나쳐 버린다.

 

그럼 나 반복문 중단하고 싶은데 어떡해!?

 

forEach 문에 break를 써볼까?

 

" break는 for 문과 while 문에서 밖에 쓰지 못 한다. "

 

그러므로, 반복문을 중단하고 싶을 때는 forEach 문 말고

웬만하면 for 문으로 break를 써서 함수를 중단시키는 방법이 가장 best 인 것 같다.