Javascript 배열과 유사 객체 배열

pds·2022년 11월 25일
0

TIL

목록 보기
11/60

유사 배열

배열은 아니지만 인덱스로 접근할 수 있고length 속성을 가지는 특수한 배열 처럼 보이는 객체

배열에 있는 기본 기능을 제공하지 않게 하거나 기존 배열과 차별화하여 특정 기능만을 제공하게 한다거나 할 때 사용한다고 한다.


const nodes = document.querySelectorAll('input')
const customLikes = {"0": "hello", "1": "hi", length: 2}
const array = [1,2,3];

typeof nodes; // 'object'
typeof array; // 'object'

Array.isArray(array); // true
Array.isArray(nodes); // false
Array.isArray(customLikes); // false

배열처럼 인덱스로 접근하여 값을 가져올 수 있고 길이를 가지고 있어 배열처럼 생겼지만

실제로 배열은 아니라 Array.prototype 의 각종 유용한 함수들을 사용하여 다룰 수가 없다.

nodes.map(v => v);  // Uncaught TypeError: nodes.map is not a function at <anonymous>:1:7

유사 배열 조작하기

Array.from

유사 배열 객체(array-like object)나 반복 가능한 객체(iterable object)를 얕게 복사해 새로운Array 객체를 만듭니다.

Array.from(arrayLike,mapFn,thisArg)

arrayLike

배열로 변환하고자 하는 유사 배열 객체 또는 Iterable 객체

mapFn

배열의 모든 요소에 대해 호출할 매핑 함수

thisArg

mapFn 실행 시 this로 사용할 값

return

새로운 Array 객체

const customLikes = {"0": "hello", "1": "hi", length: 2}
const customObj = {"0": "hello", "1": "hi"};
const customArray = Array.from(customLikes); // [hello, hi];
const customArray2 = Array.from(customLikes, v => v + " world!");
const customObjToArray = Array.from(customObj); // []

customArray.filter(v => v === "hi"); // ["hi"]

유사 배열을 새로운 배열로 만들어줬기 때문에 map, reduce 같은 고차함수를 사용할 수 있게 되었다.


Function.apply

주어진 this 값과 배열 (또는 유사 배열 객체) 로 제공되는 arguments 로 함수를 호출합니다.

func.apply(thisArg, argsArray)

다른 객체에 내재된 함수를 내 것 처럼 사용할 수 있게 해준다.

thisArgs

함수를 호출할 대상이 되기 위해 제공되는 this

argsArray

func 가 호출되어야하는 인수를 지정하는 배열

return

지정된 this로 함수를 호출해 얻은 결과


유사배열 다루기

const customLikes = {"0": "hello", "1": "hi", length: 2}

Array.prototype.push.apply(customLikes, ["hell", "hall"]);
console.log(customLikes); // {0: 'hello', 1: 'hi', 2: 'HELL', 3: 'HALL', length: 4}

const concat = 
      Array.prototype.reduce.apply(customLikes, [(prev, next) => prev + " " + next]); 
// "hell hi HELL HALL"

기존 유사배열의 상태를 직접 조작 가능하고 배열 함수도 사용 가능해진다!


apply만 소개했지만 Func.call, Func.bind도 사용가능

Array.prototype.push.call(customLikes,"hell", "hall");
console.log(customLikes); // {0: 'hello', 1: 'hi', 2: 'HELL', 3: 'HALL', length: 4}

// this를 customLikes로 한 array map 함수를 사용하게끔 원본함수를 복제하여 할당 
const likesMapFn = Array.prototype.map.bind(customLikes);
const LikesArray = likesMapFn(v => v + "HELLO");
// ['helloHELLO', 'hiHELLO', 'hellHELLO', 'hallHELLO']

Spread Operator

iterable 한 객체의 경우 전개 구문으로 배열로 쉽게 만들 수 있다.

const nodes = document.querySelectorAll('input');
const customLikes = {"0": "hello", "1": "hi", length: 2}

const a = "hell";
const b = [1,2,3];

typeof nodes[Symbol.iterator]; // 'function'
typeof customLikes[Symbol.iterator]; // 'undefined'

typeof a[Symbol.iterator]; // 'function'
typeof b[Symbol.iterator]; // 'function'
const nodeArray = [...nodes]; // [input#id-fname.form-control, input#id-lname.form-control, ...]
const aArray = [...a]; // ['h', 'e', 'l', 'l']
const customLikesToArray = [...customLikes]; // Uncaught TypeError: customLikes is not iterable

const sequence = [...Array(10).keys()].map(v => v + 1);
// [1,2,3,4,5,6,7,8,9,10];

솔직히 아직 유사배열을 직접 사용해야 하는 상황이 있을까? 왜 쓸까? 라는 것에 대해는 잘 이해가 되지 않고 잘 와닿지 않는다.

많이 경험해보고 많은 코드를 보다보면 이해가 될 것이라 믿는다!


Reference

profile
강해지고 싶은 주니어 프론트엔드 개발자

0개의 댓글