1차 공부/React공부

유사배열과 배열의 차이는? / 유사배열의 각 요소를 수정하고 싶다면?

공대탈출 2022. 11. 28. 18:02

배열

JavaScript의 배열은 여러 자료형을 가질 수 있는 특징이 있다.

배열을 사용하면 여러 자료형의 데이터를 관련성있게 관리할 수 있어 코드가독성이 높아지고, 생산성이 높다.

<!DOCTYPE html>
<html lang="en">
  <head> </head>
  <body>
    <script>
      let arr = [
        0, 1, 2,
        'a','b','c',
        { key: 1 },{ key: 2 },
        [1, 2],[3, 4],
      ];
      for (let i = 0; i < arr.length; i++) {
        console.log('arr[' + i + ']' + ' : ' + arr[i]);
        console.log('typeofarr[' + i + ']' + ' : ' + typeof arr[i]);
      }
    </script>
  </body>
</html>

 

유사배열(Array-Like Object)

유사배열은 말 그대로 배열과 유사한 객체를 의미한다.

함수에서 처리결과로 배열을 반환하고싶을때, 배열에서 기본으로 내포돼있는 기능을 제공하고 싶지 않고나, 매열에 내포되어있지 않은 기능을 제공하고 싶을 때 사용한다.

 

월드컵이라는 검색어로 나온 뉴스를 영역으로 NodeList를 받았고, length:10을 가지고 있었다.

근데? 배열이 아니다.

NodeList에 대한 typeof가 배열과 같게 'object'가 반환되었지만, Array.isArray(arr)이 false로 반환되었다.

 

JS에서 유사배열을 사용하기 위해서는 최소한의 조건이 필요하다.

1) 숫자 형태의 index가 존재해야한다.

2) length속성을 포함해야한다.

위의 두가지 조건을 따른다면 유사배열을 선언하여 사용할 수 있다.

 

<!DOCTYPE html>
<html lang="en">
  <head> </head>
  <body>
    <script>
      let arr_l_obj = {
        0: 'kim',
        1: 'park',
        2: 'lee',
        length: 3,
      };
      for (let i = 0; i < arr_l_obj.length; i++) {
        console.log(`arr_l_obj[${i}] ${arr_l_obj[i]}`);
      }
      console.log(arr_l_obj.length);
    </script>
  </body>
</html>

인덱스처럼 사용 가능하게 키 값을 0부터 시작하는 숫자로 배정하였고, length를 직접 입력해 주었다.

 

유사배열의 각 요소를 수정하고싶다면?

 

하지만 유사배열은 엄밀히 말하면 배열이 아니다. 따라서 배열내에 포함된 메소드들을 사용할 수 없다.

그래서 배열내에 포함된 메소드를 유사배열에서 사용하기위해 Array.from(),call, apply, bind를 사용한다.

 

<script>
  let arr_l_obj = {
    0: 'kim',
    1: 'park',
    2: 'lee',
    length: 3,
  };
  Array.from(arr_l_obj).map((element)=>console.log(element));
</script>

배열에만 사용가능한 map을 사용하기위해 Array.from을 적용한 예시이다.

Array.from는 유사배열객체나 반복가능객체를 얕게 복사해 새로운 Array객체를 만든다.

 

 

<script>
  let arr_l_obj = {
    0: 'kim',
    1: 'park',
    2: 'lee',
    length: 3,
  };
  
  arr_l_obj.forEach()	//arr_l_obj.forEach() is not a function
  //forEach()는 배열에 사용되는 함수여서 유사배열에 사용하려면 오류가 발생한다.
  
  Array.from(arr_l_obj).forEach()	//정상적으로 작동
</script>

 

call,  apply, bind사용하는법

<script>
    let arr_l_obj0 = {
        0: 'kim',
        func: function() {console.log(this.0)},
    };
    let arr_l_obj1 = {
        0: 'park',
    };
    
    arr_l_obj0.func.call(arr_l_obj1, 1,2)	//park
    
</script>

 

 

Function.prototype.call() - JavaScript | MDN

call() 메소드는 주어진 this 값 및 각각 전달된 인수와 함께 함수를 호출합니다.

developer.mozilla.org

apply로 사용하려면 아래와같이 배열로 묶어 넣어야한다.

arr_l_obj0.func.call(arr_l_obj1, [1,2])	//park

 

let bindfunc = arr_l_obj0.func.bind(arr_l_obj1)
bindfunc()	//park

bind는 메소드가 호출되면 새로운 함수를 생성한다. 받게되는 첫 인자의 value로 this키워드를 설정한다.