JS에서 ||는 boolean이 아닐 수 있다.

```js

let a = {}

a.none || "abc"

// "abc"가 출력된다.

 

let b = a.none || "abc"

// b에 "abc"가 할당된다.

 

a.none === undefined || "abc"

// true가 출력된다

```

이렇게 할당에 사용할 수 있음

 

Object 유틸 관련

IE에서 지원 안되므로 babel polyfill (preset-env) 필요함.
/* Object.assign 객체 병합 */

const a = {a: 1, b:3}
a
>>> {a: 1, b: 3}
Object.assign(a, {c:4})
>>> {a: 1, b: 3, c: 4}
Object.assign(a, {b:5})
>>> {a: 1, b: 5, c: 4}
a
>>> {a: 1, b: 5, c: 4}


/* ES6 spread로도 가능. 단, spread는 새로운 객체를 반환하므로...
기존 객체 레퍼런스에 병합이 아닌, 병합된 새로운 객체를 반환하는 것이다.
Object.assign에서 병합이 아닌 새 객체 반환하려면, 맨 앞에 {} 넘겨 주어야 함. */

const as = Object.assign({}, a, {c:4})
    is equal to 
const sp = {...a, ...{c:4}}
/* map, filter, reduce 등을 사용하기 위해 Array로 바꿀 때 유용 */

Object.keys(obj) – returns an array of keys.
Object.values(obj) – returns an array of values.
Object.entries(obj) – returns an array of [key, value] pairs.
/* 불변 객체를 만들기 */
Object.freeze()
객체의 멤버 객체 까지 불변이 되는건 아니다. 이 경우 deepFreeze 필요함.
참고) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#examples

 

객체 >> query string 변환

/* query string으로 만들면서 encoding이 필요하다면 URLSearchParams 사용 */
new URLSearchParams(object).toString()

/* query string으로 만들면서 encoding이 필요하지 않은 경우 (이미 encoding 되어 있는 경우) */
export const makeQueryString = (params) => Object.entries(params)
        .reduce((acc, [k, v]) => acc + `${k}=${v}&`, '')
        .slice(0, -1);
        
export const makeQueryString = (params) => Object.entries(params)
        .map(([k, v]) => `${k}=${v}`)
        .join('&');

URLSearchParams는 공백을 +로
encodeURIComponent는 공백을 %20으로 인코딩하지만 둘 다 상관 없다.
https://stackoverflow.com/questions/1211229/in-a-url-should-spaces-be-encoded-using-20-or
 

형변환

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

스트링 자르기

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

innterText 보다는 textContent

 

undefined 방지

``a_s``처럼 유효한 이름일 경우 ``js ""``로 감싸주지 않아도 되며, ``.``연산자로 접근할 수 있다. 객체 접근은 보통 ``.``연산자를 사용하는 것이 좋다.

존재하지 않는 속성(``undefined``)의 속성을 참조하려 하면 ``TypeError``가 발생한다.

이를 방지하기 위해 ``&&``를 사용하면 좋다.

```js

obj.und                      // undefined

obj.und.value                // throw "TypeError"

obj.und && obj.und.value     // undefined

```

 

성능우위 문법

보면, 그냥 사람들이 많이 사용하는 일반적인 문법이 제일 빠른 방법이다.
내부 로직 최적화 하시는 분들이 제일 보편적인 방법을 최적화 하는데 매진하기 때문이 아닐까...
 

- 배열 생성 : ``js var arr = new Array();`` 보다 ``js var arr = [];``

 

- 배열 접근 : ``js arr.push(value)`` 보다 ``js arr[i] = value``  근데 이건 쓰임이 다른거라.

 

- 객체 생성 : ``js var obj = new Object();`` 보다 ``js var obj = {};``

 

- 객체 접근 : ``js obj["a"] = 1`` 보다 ``js obj.a = 1;``

 

- 문자열 생성 : ``js var str = new String("aaa");`` 보다 ``js var str = "aaa";``

 

- 문자열 연산 : loop문에서 문자열 조작시 매번 + 연산자로 붙이지 말고, array에 추가해 두었다가 join으로 한번에 붙이는 것이 더 빠르다.

즉 ``js str += "test1" + "test2";`` 보다 다음을 사용하라는 것인데,

```js

arr=[];

loop{

    arr.push("test1", "test2"); 

};

arr.join("");

```

요즘은 ``+`` 결합을 최적화해주기 때문에 오히려 ``.join()``을 사용하는 것 보다 ``+``가 월등히 빠르다. ( jsperf )

 

전역 변수

- 전역변수 사용은 최소화 하는 것이 좋으며 굳이 사용해야 한다면 전역변수 컨테이너에 담아 쓰거나 클로저를 활용하는 것이 좋다.

- 스코프 체인 탐색 줄이기 : 전역 객체는 스코프 체인 하단에 위치해 있기 때문에 ``js var LocalVariable = GlobalVariable;``  로 할당해서 접근하면 스코프 체인 탐색 시간을 줄일 수 있다.

https://developer.mozilla.org/ko/docs/Web/API/Window/window 전역 변수는 window 객체의 필드다.

 

반복문 & 조건문

- ``js for...in`` 은 가급적 피하는 것이 좋다.

 

- ``js for (var i = 0; j < Array.length; i += 1)`` 처럼 작성하지 말고, 다음 방법을 사용한다.

```js

for (var i = 0, lines_length = lines.length; i < lines_length; i++)

for (var i = Array.length; i > 0; i -= 1) // index 순서가 상관 없는 경우

```

사실 이것도 생각해보니 큰 차이는 없겠다. 어떤 사람은 ``js Array.length``가 매번 호출된다고 적어놓았는데 ``length``는 메소드가 아니라 멤버 변수다. 따라서 저렇게 쓴다고 해서 매번 메소드가 호출된다거나 하지는 않는다. 사실 생각해보면 ``length``는 대부분의 타 언어에서도 메소드가 아니라 멤버 변수로 제공한다. 일부러 변수를 선언해 주는 것은 스코프 체인 탐색 시간을 줄이기 위해서다.