엄범


JS에서 숫자 타입은 Number인데, 이건 소수점 타입이다.


``js parseInt()``를 사용할 때는 항상 기수를 지정해 주는 것이 좋다.

``js parseInt("08")``로 쓰면 8진수로 인식해 결과가 ``0``이다.

명시적 형변환은 ``js String()``, ``js Number()``를 사용하는데, 이보다는 ``js parseInt(string), parseFloat(string)`` 이를 사용하는게 좋다. 16진수 등도 인식한다.



자료형

  • 어떤 수를 0으로 나눠도 문제가 발생하지 않는다.

  • JS는 ``js null, undefined, NaN, 빈 문자열 '', 0, false``를 ``js false``로 본다.
    * 이 외의 값은 모두 참이다.

  • NaN은 자기 자신을 포함해서 어떤 값과도 같지 않다.
    그래서 NaN인지 확인하려면 반드시 ``js isNaN()``을 사용해야한다.

  • 항상 ``js ===``나 ``js !==``를 사용하는 편이 좋다.
    이는 변수 값 비교 시 auto casting을 비활성화 해 타입을 엄격하게 검사한다.
    ``js NaN == false``는 ``js true``지만, ``js NaN === false``는 ``js false``다.
    ``js ==, !=``를 사용해야 하는 경우 ``js isFinite(), isNaN()``또는 ``js (foo), (!foo)``로 변경해서 작성한다.


문자열

문자열은 유사 객체이며 immutable이다. 일단 한 번 만들어지면 변경되지 않는다. 

``js str[0] = "b";`` 같은 코드는 동작하지 않는다.


``+`` 연산자로 문자열 결합이 가능한데, `` number + char`` 결합에서 타입에러가 발생하지 않고 자동으로 형변환해서 처리해준다. 
``+`` 연산은 문자열이 우선순위가 높아 숫자가 문자열로 변환된다.

일반적으로 ``js substring()``보다 ``js slice()``를 사용하는 것이 좋다.

템플릿 문자열

아래처럼 `` ""``가 아니라 backtick으로 묶으면 된다.
```js
var body_str = "body"
var head_str = "head"
var panelFormatStr = `<div class=\"panel panel-primary\">
                         <div class=\"panel-heading\">${head_str}</div>
                         <div class=\"panel-body\">${body_str}</div>
                      </div>`
```

구조 분해 할당

```js
const [a, b] = [1, 2];
```

배열

JS의 배열은 연속적인 공간에 메모리를 할당하는게 아니고 배열 첨자를 문자열로 변환해서 속성으로 만들기 때문에, 실제 배열이 아니라 배열같은 객체다.
속성을 읽고, 갱신하는 작업은 일반 객체와 똑같이 처리된다.
그러나 객체는 ``Object.prototype``을, 배열은 ``Array.prototype``을 상속한다. 그래서 Array를 다룰 수 있는 메소드와 ``length`` 속성 등을 상속하게 된다.
그래서 배열이 필요한 순간에는 객체가 아니라 배열을 사용하는게 바람직하다.

```js

var arr = ['a', 'b', 'c'];  // 배열 리터럴

arr[3] = 'd'; 

arr.push('e');      //push pop은 index를 따로 구할 필요가 없어 편할 때가 있다.

arr.push('f');

arr.pop();        //a, b, c, d, e

arr.unshift('0'); //0, a, b, c, d, e     앞에 0 추가

arr.splice(2, 2); //0, a, d, e    삭제하면서 인덱스를 당긴다. 그래서 배열이 큰 경우 느릴 수 있다.

delete arr[2];    //0, a, , e    삭제하면서 인덱스를 당기지 않는다.

arr[5] = 'g';     //0, a, , e, , g     index를 건너 뛰고 바로 [5]에 넣을 수 있다.

// arr.length == 6


// typeof arr == object

```

``js typeof``하면 ``object``로 알려주기 때문에 ``is_array()`` 함수를 만들어 보완할 수 있다.


배열 초기화

이렇게 하면 절대 안됨!

```js

const stars = new Array(30).fill(new Star());

// stars[0] == stars[1]이 된다. 같은 객체가 들어감.

```


``js new Array(30);``은 실제로 30개의 element를 가진 배열이 만들어지는게 아니라, length:30만 가지고 있는 객체가 만들어진다.

이걸 30개의 element를 가진 배열로 만드려면 spread ``js [...obj]`` 또는 ``js Array.fill()``을 사용한다.

그래서 그 다음에 map으로 초기화해주어야 의도한 대로 초기화 된다.

```js

const stars1 = Array(30).fill().map(() => new Star());

const stars2 = [...Array(30)].map(() => new Star());

```


가장 빠르고 좋은건 from을 쓰는 것이다.

```js

let sampleData = Array.from({length: 10}, (_, id) => ({id}))

```

is_array()

```js

var is_array = function (value) {

return value &&

  typeof value === 'object' &&

    typeof value.length === 'number' &&

    typeof value.splice === 'function' &&

    !(value.propertyIsEnumerable('length'));

}

```


sort(비교함수)

기본 sort()는 [4, 32, 12]를 [12, 32, 4]로 정렬한다. 제대로 사용하려면 비교함수를 지정해주어야 한다.
```js
m.sort(function (a, b) {
    if (a === b) {
        return 0;
    }
    if (typeof a === typeof b) {
        return a < b ? −1 : 1;
    }
    return typeof a < typeof b ? −1 : 1;
});
```

반복문

함수형을 쓸 수 있나 고민.
``js while / do while / for / for in / for of``을 지원하고 array의 method 형태로 ``forEach()``도 지원한다.

JQuery의 each. 기본 forEach는 array에서만 사용 가능한 반면 이건 object에서도 사용 가능해서 이 방식이나 함수형이 제일 편한 듯.
```js
$.each(object, function(index, item) {})
```

forEach

```js
var numbers = [4, 9, 16, 25];

numbers.forEach(function (item, index) {
    demoP.innerHTML = demoP.innerHTML + "index[" + index + "]: " + item + "<br>"; 
});
```

for in 

  • ``js for in``은 프로토타입 체인의 속성을 포함한 객체의 모든 속성을 포함해 반복한다. 그래서 프로토타입 체인 탐색이 필요하지 않은 일반적인 반복에서는 ``js for in`` 사용을 피하고 그냥 함수형을 사용하는 것을 권장.
  • 브라우저에 따라 Array의 index 순서가 아니라 Array에 추가된 순서로 반환되는 경우가 있어 순서가 꼬인다.
  • 속도도 ``js for``보다 더 느리다.

``js for in``을 사용할 필요가 있을 때는 보통 ``js typeof``와 함께 사용하게 되는 경우.

굳이 ``js for in``을 사용해야 하는 경우 다음과 같이 ``js object.hasOwnProperty(variable)`` 메소드로 속성이 실제로 객체의 속성인지, 아니면 프로토타입 체인(prototype chain) 상에 있는 것인지를 확인하며 사용해야 한다.

```js

for (bar in obj) {

    if (obj.hasOwnProperty(bar)) {

...

}

}

```