Array의 생성방법들

1. 기본이고 기초인 array literal

 let arr = [1, 2, 3, 4, 5];

2. Array constructor

1). only one(number) argument

let arr1 = new Array(4) // [empty x 4] (length: 4)
  • '4' 자리에는 무조건 양의 정수만 들어가야 하며, 음수가 들어가면 error가 난다고 한다.

  • 이렇게 만들어진 Array는 length를 제외하면 property가 없다. 즉, index도 없는 상태이다. forEach와 map은 사용하면 에러가 나지는 않지만, reduce는 에러를 발생시킨다.

    arr1.forEach((curr, index, arr) => { console.log(index) })

    와 같이 코드를 짜보아도 아무값도 반환되지 않는다.

    `arr1[2]`

    위와 같은 구문도 어떤 에러도 발생시키지 않아서 각 자리에 undefined가 들어있는 것 아니냐는 의문이 생길 수가 있는데

    Object.getOwnPropertyNames(arr1)

    을 해봐도 ['length']만 나온다고 한다. 정말 index가 없는 배열인 것이다.

2) only one(non-number) argument

let arr2 = new Array('4') // length: 1이고, ["4"]인 배열이 만들어진다.

3) more than one arguments

let arr3 = new Array(1, 2, 3, 4) // 1, 2, 3, 4가 들어있는 정상적인 배열이 반환된다.

3. 다른 방법들 ( 2-1번의 한계를 해결하는 방법들, 주로 Array의 methods들이다.)

1) Array.prototype.fill() (ES6를 지원하는 브라우저에서만 작동한다고 한다.)

let arr1 = Array(5).fill(5) // [5, 5, 5, 5, 5]이고 index도 정상적으로 모두 존재한다.
  • 하지만 fill()은 추가적인 기능도 있다. MDN Array.prototype.fill()를 보면 자세한 사용법을 알 수 있다.

    let arr1 = new Array(5); arr1.fill(5); // [5, 5, 5, 5, 5]
  • 또 위와 같이 사용할수도 있다. 즉, mutable한 function이다.

2) Array.from() (ES6를 지원하는 브라우저에서만 작동한다고 한다. MDN Array.from()

```
Array.from([1, 2, 3, 4]); // [1, 2, 3, 4]
Array.from("foo") // ['f', 'o', 'o']
Array.from([1, 2, 3, 4], x => x * x) // [1, 4, 9, 16]
let arr1 = Array.from(new Array(5)) // [undefined, undefined, undefined, undefined, undefined]

```
  • 맨 아래 arr1은 이제 index를 갖는다.
  • 여러모로 특이한 method인 것 같다. 인자로 arrayLike하거나 iterable한 object를 받는다.
  • 2번째인자로 map function을 받아서 이를테면 arr1.map(...)으로 어떤 작동을 해주는 것과 똑같이 해줄 수 있다.
  • 또, Array.prototype.from() 이 아니다. Array constructor에 내장이다.
  • 자세히 보려면 MDN링크를 참조해야 한다.

3) spread operator (ES6를 지원하는 브라우저에서만 작동한다고 한다.)

```
let arr1 = [...new Array(5)] // [undefined, undefined, undefined, undefined, undefined]
```

이제 정상적으로 index를 가지는 빈(undefined로 채워진) 배열을 반환한다.

4) Array.of() (ES6를 지원하는 브라우저에서만 작동한다고 한다.)

- Array constructor와 거의 비슷하게 작동한다고 한다. 
- Array(5)가 length 5의 빈 배열을 반환하지만, Array.of(5)는 [5]를 반환하는 결정적인 차이가 있다고 한다.

5) Array.from({length: 5}) - 추가사항

  • mdn의 예제로 있는 방법이다.
  • array-like object를 판별할때, 객체이고 length: indexed elements 인 property를 가지고 있으며 된다고 한다. 그래서 쓸 수 있는 방법이다.
  • 길이는 5이고 index가 있고 undefined로 차있는 배열을 반환한다.

출처 : https://www.freecodecamp.org/news/https-medium-com-gladchinda-hacks-for-creating-javascript-arrays-a1b80cb372b/

4. 요약

let arr1 = Array(5).fill(undefined) 
let arr2 = Array.from(new Array(5))
let arr3 = [...new Array(5)]
let arr4 = Array.from({length:5})

// 모두 [undefined, undefined, undefined, undefined, undefined] 를 반환한다. 

Nonenumerable property

6월 18일에는 Enumerability에 대해서 알아봤었다. for ... in 이 prototype의 enumerable한 property들까지 도달하므로 hasOwnProperty를 함께 이용해줘야 안전하게 사용할 수 있다는 것까지는 알았는데, 자동으로 걸러진다며 신경쓰지 않았던 nonenumerable한 property들이 무엇인지에 대해 궁금했었다.
구글링해보니 stackoverflow : what-does-enumerable-mean에서 예시로 들어준 것을 봤다. 이를테면 object에 원래 존재하는 constructor, toString같은 것들은 nonenumerable한 property들이다. 어떤 느낌의 property들인지 대충 알았고, for ... in 으로 object를 탐색할 때 자동으로 걸러주는 것은 다행인 일이다.

궁금점, 더 공부할 것들

  • nonenumerable한 property들이 어떤 것들인지 훑어본다면 의미가 있을까? MDN에서 enumerable flag의 default를 적어놓지 않은 것 보니 안봐도 될 것 같다.
  • 예시코드를 보면 let arr = Array(5); 와 같이 new를 안 붙이고 그냥 만들어준다. 왜 이렇게 해도 될까?
  • Shallow copy, deep-copy 에 대해 다음에 알아보자.
  • spread operator에서도 자세히 봐야할 것 같다.
  • Array 생성방법들 출처를 들어가보면 1) Converting to Arrays: Array-likes and iterables 2) Case study: Range Function 3) Cloning Arrays: The challenge 4) Cloning Arrays: The Hacks 5) The JSON techniques 6) Deep copy Helper 7) Using Javascript libraries 8) Conclusion 등이 더 있다. 추후에 읽어보자.