(JS) TIP
JS에서 ||는 boolean이 아닐 수 있다.
1
2
3
4
5
6
7
8
9
10
11
let a = {}
a.none || "abc"
// "abc"가 출력된다.
let b = a.none || "abc"
// b에 "abc"가 할당된다.
a.none === undefined || "abc"
// true가 출력된다
이렇게 할당에 사용할 수 있음
Object 유틸 관련
IE에서 지원 안되므로 babel polyfill (preset-env) 필요함.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* 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}}
1
2
3
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.
1
2
3
4
/* 불변 객체를 만들기 */
Object.freeze()
객체의 멤버 객체 까지 불변이 되는건 아니다. 이 경우 deepFreeze 필요함.
참고) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#examples
객체 » query string 변환
1
2
3
4
5
6
7
8
9
10
11
12
13
/* 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
형변환
명시적 형변환은 String()
, Number()
를 사용하는데, 이보다는 parseInt(string), parseFloat(string)
이를 사용하는게 좋다. 16진수 등도 인식한다.
스트링 자르기
일반적으로 substring()
보다 slice()
를 사용하는 것이 좋다.
innterText 보다는 textContent
- innerText는 IE에서 나온 비표준으로 사용하지 않도록 한다. 대신
textContent
를 사용한다. - text를 가져오는 결과도 안에 태그가 있느냐에 따라 다른데, textContent가 더 직관적으로 동작한다.
- https://stackoverflow.com/questions/35213147/difference-between-textcontent-vs-innertext
undefined 방지
a_s
처럼 유효한 이름일 경우 ""
로 감싸주지 않아도 되며, .
연산자로 접근할 수 있다. 객체 접근은 보통 .
연산자를 사용하는 것이 좋다. 존재하지 않는 속성(undefined
)의 속성을 참조하려 하면 TypeError
가 발생한다. 이를 방지하기 위해 &&
를 사용하면 좋다.
1
2
3
obj.und // undefined
obj.und.value // throw "TypeError"
obj.und && obj.und.value // undefined
성능우위 문법
보면, 그냥 사람들이 많이 사용하는 일반적인 문법이 제일 빠른 방법이다. 내부 로직 최적화 하시는 분들이 제일 보편적인 방법을 최적화 하는데 매진하기 때문이 아닐까…
배열 생성 :
var arr = new Array();
보다js var arr = [];
배열 접근 :
arr.push(value)
보다js arr[i] = value
근데 이건 쓰임이 다른거라.객체 생성 :
var obj = new Object();
보다js var obj = {};
객체 접근 :
obj["a"] = 1
보다js obj.a = 1;
문자열 생성 :
var str = new String("aaa");
보다js var str = "aaa";
문자열 연산 : loop문에서 문자열 조작시 매번 + 연산자로 붙이지 말고, array에 추가해 두었다가 join으로 한번에 붙이는 것이 더 빠르다.
즉 str += "test1" + "test2";
보다 다음을 사용하라는 것인데,
1
2
3
4
5
arr=[];
loop{
arr.push("test1", "test2");
};
arr.join("");
요즘은 +
결합을 최적화해주기 때문에 오히려 .join()
을 사용하는 것 보다 +
가 월등히 빠르다. ( jsperf )
전역 변수
- 전역변수 사용은 최소화 하는 것이 좋으며 굳이 사용해야 한다면 전역변수 컨테이너에 담아 쓰거나 클로저를 활용하는 것이 좋다.
- 스코프 체인 탐색 줄이기 : 전역 객체는 스코프 체인 하단에 위치해 있기 때문에
var LocalVariable = GlobalVariable;
로 할당해서 접근하면 스코프 체인 탐색 시간을 줄일 수 있다.
https://developer.mozilla.org/ko/docs/Web/API/Window/window전역 변수는 window 객체의 필드다.
반복문 & 조건문
for...in
은 가급적 피하는 것이 좋다.for (var i = 0; j < Array.length; i += 1)
처럼 작성하지 말고, 다음 방법을 사용한다.
1
2
for (var i = 0, lines\_length = lines.length; i < lines\_length; i++)
for (var i = Array.length; i > 0; i -= 1) // index 순서가 상관 없는 경우
사실 이것도 생각해보니 큰 차이는 없겠다. 어떤 사람은 Array.length
가 매번 호출된다고 적어놓았는데 length
는 메소드가 아니라 멤버 변수다. 따라서 저렇게 쓴다고 해서 매번 메소드가 호출된다거나 하지는 않는다. 사실 생각해보면 length
는 대부분의 타 언어에서도 메소드가 아니라 멤버 변수로 제공한다. 일부러 변수를 선언해 주는 것은 스코프 체인 탐색 시간을 줄이기 위해서다.