본문 바로가기

프로그래머스 데브코스

[데브코스 1일차] JS 배열과 객체

🤔 아래 질문에 답을 해볼 수 있나요?

  1. 웹의 창시자는 누구일까요?
  2. 자바스크립트의 창시자는 누구일까요?
  3. 자바스크립트의 역사를 간단하게 설명할 수 있나요?
  4. 어떻게 하면 더 나은 개발자가 될 수 있을까 생각해봤나요?
  5. 브라우저의 동작원리를 설명할 수 있나요?
  6. 프론트엔드 개발자의 필수 역량은 무엇일까요?
  7. 호이스팅에 대해 설명할 수 있나요?
  8. 자바스크립트의 변수에 대해 설명할 수 있나요? (메모리 관점으로)
  9. 자바스크립트의 자료형에 대해서 설명할 수 있나요? (원시 자료형과 객체 자료형에 대해서)
  10. undefined과 null의 차이를 간단하게 설명할 수 있나요?
  11. 참조가 무엇인가요?
  12. 자바스크립트 엔진은 어떻게 구성되어있나요?

JS 배열과 객체

코딩테스트 알고리즘 문제를 풀다보면 문제를 풀기 위해서 모든 원소가 0이고 크기가 n인 배열을 만들어 사용할 일이 많다. 파이썬에서는 아래와 같이 간편하게 빈 배열을 생성할 수 있다.

arr = [0] * 3

print(arr)
# [0, 0, 0]

역시 파이썬이다. 그러면 이제 자바스크립트로 동일한 작업을 수행해보자.

new Array

new Array의 인자를 1개 넣게 되면 해당 인자의 크기 만큼 빈 배열이 생성된다. 이 때 원소는 존재하지 않는다. (정확히 말하자면 ‘값’은 존재하지만) 즉 undefined 이다.

const arr = new Array(3)

console.log(arr)
// [ <3 empty items> ]
console.log(arr[0])
// undefined

인자를 여러 개 넣는다면?

new Array에 인자를 2개 이상 넣는다면, 해당 값을 배열의 원소로 본다.

const arr1 = new Array(1, 2, 3);
const arr2 = new Array([1, 2, 3]);
const arr3 = new Array(...[1, 2, 3]); // ES6 스프레드 문법

console.log(arr1) // [1, 2, 3]
console.log(arr2) // [ [1, 2, 3] ]
console.log(arr3) // [1, 2, 3]

new Array + fill

fill은 Array.prototype(배열 메소드)이다. fill은 배열의 시작 인덱스부터 끝 인덱스까지 하나의 값으로 채운다.

const arr = new Array(3).fill(0)

console.log(arr)
// [0, 0, 0]

Array.from

Array.from 메서드는 첫번째 인자로 객체를, 두번째 인자로 map함수를 정의할 수 있다.

이 때, 첫번째 인자에 들어가는 객체는 이터러블-이터레이터 프로토콜을 준수하는 객체와 유사배열객체여야 한다. 반환은 인자로 들어간 객체를 얕은 복사한다.

두번째 map함수에서 첫번째 인자는 원소, 두번째 인자는 인덱스이다.

길이가 5이고 모든 원소가 0인 배열을 만드는 예

const arr = Array.from({ length: 5 }, (v) => 0);
console.log(arr); // [0, 0, 0, 0, 0]
console.log(arr[0]); // 0

Array.length

Array의 길이를 반환하는 Array의 property key이다. 결론적으로 Array.length에 직접 접근해서 값을 변경하는 것은 좋지 않다. Array.length는 readonly여야 한다. 직접적으로 접근해서 값을 변경하게 되면 아래와 같은 문제가 생긴다.

const arr = [1, 2, 3, 4, 5];
console.log(arr.length); // 5

arr.length = 10;
console.log(arr); // [ 1, 2, 3, 4, 5, <5 empty items> ]

arr.length = 3;
console.log(arr); // [1, 2, 3]

length 값을 바꾼 것만으로도 배열 자체에 변형이 생겨버린다.

자바스크립트에서 배열은 Object다

사실 자바스크립트에서 배열은 객체이다. 만약 [1, 2, 3] 이라는 배열이 있다면 이 배열은 아래 형태의 객체이다.

const arr = [1, 2, 3]
/*
arr {
    0: 1,
    1: 2,
    2: 3,
    length: 3
}
*/

재미있는 사실 1

여기서 재미있는 사실은, 배열은 객체이므로 새로운 key-value를 추가할 수 있다.

const arr = [1, 2, 3]
arr.id = '1';

/*
arr {
    0: 1,
    1: 2,
    2: 3,
    id: '1',
    length: 3
}
*/

이 때, length는 변하지 않는다.

재미있는 사실 2

객체에 key를 추가할 때, key가 문자열이라면 length가 변하지 않는다. 하지만 숫자를 추가하면 index로 보고 크기가 변한다.

const arr = [1, 2, 3]
arr[3] = 4;

/*
arr {
    0: 1,
    1: 2,
    2: 3,
    3: 4,
    length: 4
}
*/

재미있는 사실 3

empty items도 생기는데, 그 만큼 length에 반영된다.

const arr = [1, 2, 3];
arr[6] = 7;

console.log(arr); // [1, 2, 3, empty × 3, 7]

/*
arr {
    0: 1
    1: 2
    2: 3
    6: 7
    length: 7
}
*/

따라서 이렇게 배열을 조작하는 것은 혼란을 야기시키기 때문에 지양 해야한다.

다시 짚고 넘어간 내용

Array.prototype.concat

배열 2개를 합쳐서 새로운 배열을 반환한다. 하지만 ES6 스프레드 연산자가 더 가독성이 좋다. (concat을 잊지만 말아줘~)

Array.prototype.slice

배열을 나누어 새로운 배열을 반환한다.

Array.prototype.splice

원본 배열 자체에 원소를 집어 넣거나 삭제하는 등 원본 배열을 직접 조작한다.

in 연산자, for-of 순회, for-in 순회

in 연산자는 boolean을 반환한다.


const obj = {
  id: '1',
  name: 'yong',
}

for(const key in obj){
  if (key in obj) console.log(key); // 'id' 'name'
}

💡 회고

맨 위의 몇 가지 질문에 답을 할 수 있는 개발자가 되자.

그동안 코딩테스트를 파이썬으로만 봐왔기 때문에 빈 배열을 만들 때 항상 Array.from으로 map 함수를 설정해서 배열을 생성했었다. Array.from({length: 5}, (v) ⇒ 0) 이런식으로...
하지만 new Array와 fill을 이용하는 것을 이제 알았다. (좀 더 간편한듯 하다.)