목차
<script>
를 <body>
최하단에 배치할 것 +
- 외부소스를 로컬로 관리할 것
- 전역변수 사용을 하지말 것 +
import
는 최상단에 배치할 것 +
- 선언없이 변수사용하지 말 것
- 생성자(
Array
/Object
/Function
)를 사용하지 말것 배열/객체 함수
==
비교연산자를 쓰지 말 것
- 중괄호(
{…}
)를 생략하지 말것
-
parseInt()
에 진법을 붙일것
-
switch
에서 연속되고 기능이 있는 case
사이에 break
를 생략하지 말것
- 배열 순회시,
for-in
를 사용하지 말 것
- 배열 내에서
delete
로 항목을 제거하지 말 것
- 반복문에서 절차에 따라 필요한 처리만 진행할 것
- 반복문에서
continue
처리를 피할 것(불확실)
- 반복문안에서
try-catch
를 처리하지 말 것
- 돔 객체는 한번만 조회 할 것
- 돔 조작을 최소화 할 것
- 돔 레이아웃 불필요하게 초기화 하지 말 것
- 인라인 메소드 안에서 이벤트 처리를 하지 말 것
eval()
를 사용하지 말 것
-
with()
를 사용하지 말 것
setTimeout
/setInterval
사용시 문자열로된 callback
사용하지 말 것
- 기본 객체를 수정하지 말 것
- 증감연산자(
++
/--
)를 사용하지 말 것
-
this
를 따로 할당해서 쓰지 말 것
- 코드끝에
;
을 생략하지 말 것
(ES5)
정의하기전에 사용하지 말 것
(Legacy)
배열 순회시, array.length
값을 정의해서 쓸 것
상세
<script>
를 <body>
최하단에 배치할 것
script 에 정의된 소스들을 다운받는 과정에서 렌더링이 지연됨 참조
script async
스크립트 다운로드가 완료된 경우, 스크립트 파싱 후 HTML 파싱 재개
script defer
스크립트 다운로드가 완료되더라도 HTML 파싱후, 스크립트 파싱
1. 외부소스를 로컬로 관리할 것
CDN 기능 오류 나 네트워크 문제등의 외부 문제로 오류가 발생하는 것을 방지
2. 전역변수 사용을 하지말 것
다른 위치에서 접근하거나 기능이 덮어써질 가능성이 있음
Namespacing
const name = 'Nicholas';
function sayName() {
alert(name);
}
const MyApp = {
name: 'Nicholas',
sayName() {
alert(this.name);
}
};
const today = new Date();
alert(`Today is ${today.getDate()}`);
(function() {
const today = new Date();
alert( `Today is ${today.getDate()}`);
})();
4. import
는 최상단에 배치할 것
가독성 문제
5. 선언없이 변수사용하지 말 것
전역변수로 생성됨으로 추가적인 문제 발생
function 의 경우, eval()
을 통해야 함으로 성능 저하 발생
6. 생성자(Array/Object/Function)를 사용하지 말것 배열/객체 함수
성능면이나 가독성 면에서 더 불리함
7. ==
비교연산자를 쓰지 말 것
암시적 형변환을 거치게 됨으로 타입오류나 가독성 문제가 발생===
을
8. 중괄호({…}
)를 생략하지 말것
가독성 문제
9. parseInt()에 진법을 붙일것
문자열이 0x
또는 0X
로 시작하면 16 진수를 사용하고 0
으로 시작하면 8 진수 또는 10 진수를 사용하여 문제가 발생할 수 있음
const month = parseInt('08');
const day = parseInt('09');
const month = parseInt('08', 10);
const day = parseInt('09', 10);
const month = Number('08')
const day = +'09';
10. switch에서 연속되고 기능이 있는 case사이에 break를 생략하지 말것
코드 누락인지 아니면 의도된 절차인지 가독성의 문제 발생
switch (foo) {
case 1:
A()
case 2:
B();
break;
...
}
11. 배열 순회시, for-in
를 사용하지 말 것
for-in
배열 사용시, 배열내의 빈값이 있을때 생략하는 문제가 발생하며. 배열순회 성능면에서도 for-in
을 지양하는 것이 좋음. 그러나 가독성 면에서 array.forEach()
가 유리한점도 있음.
12. 배열 내에서 delete로 항목을 제거하지 말 것
배열내에 delete
로 삭제된 항목이 undefined
로 남아 배열의 전체 길이는 동일하게 유지됨, 빈 배열 항목을 처리한다는 관점에서는 역으로 이용이 가능한 부분?
const numbers = ['zero', 'one', 'two', 'three', 'four', 'five'];
delete numbers[2];
const numbers = ['zero', 'one', 'two', 'three', 'four', 'five'];
numbers.splice(2, 1);
13. 반복문에서 절차에 따라 필요한 처리만 진행할 것
중복되는 변수나 조건에 부합하지 않는 처리를 반복문에서 제외하여 성능 저하를 막을것
14. 반복문에서 continue처리를 피할 것(불확실)
과도하게 사용될경우, 가독성의 문제와 함께 javascript 엔진이 별도의 컨텍스트로 관리하기에 성능문제가 발생할 수 있음
추가로 찾아봤을때, break
와continue
가 나쁜 프로그래밍 관행입니까?에서 처럼 무조건 안쓰는것이 옳다고는 할수 없는 것으로 보인다. What is the point of the no-continue rule?의 내용에서는 countinue
가 go to
처럼 continue label
로 처리되는것에 대해 금지한다는 의미인것으로 애기하고 있다.
차라리 filter()
의 형태로 정제된 리스트만 처리하면 되지 않을까?
let loopCount = 0;
for (let i = 1; i < 10; i += 1) {
if (i > 5) {
continue;
}
loopCount += 1;
}
for (let i = 1; i < 10; i += 1) {
if (i <= 5) {
loopCount += 1;
}
}
15. 반복문안에서 try-catch 를 처리하지 말 것
루프가 반복될때마다 예외 개체가 현재 범위에서 저장되기 때문
const {length} = array;
for (let i = 0; i < length; i += 1) {
try {
...
} catch (error) {
...
}
}
const {length} = array;
function doSomething() {
try {
...
} catch (error) {
...
}
}
for (let i = 0; i < length; i += 1) {
doSomething();
}
16. 돔 객체는 한번만 조회 할 것
성능저하 문제
17. 돔 조작을 최소화 할 것
innerHTML
, appendChild()
호출시마다 DOM을 다시 그리게되어 성능문제 발생
18. 돔 레이아웃 불필요하게 초기화 하지 말 것
layout thrashing
으로 인해 성능저하 문제
layout thrashing
layout thrashing을 강제하는 것
DOM 요소가 변경될 경우, 기존 layout은 무효화 되어 추가로 layout 호출시 새로 계산이 필요하여 성능지연이 발생
elementA.className = "a-style";
var heightA = elementA.offsetHeight;
elementB.className = "b-style";
var heightB = elementB.offsetHeight;
elementA.className = "a-style";
elementB.className = "b-style";
var heightA = elementA.offsetHeight;
var heightB = elementB.offsetHeight;
function resizeWidth(paragraphs, boxElement) {
const {length} = paragraphs;
for (let i = 0; i < length; i += 1) {
paragraphs[i].style.width = `${boxElement.offsetWidth}px`;
}
}
function resizeWidth(paragraphs, box) {
const {length} = paragraphs;
const width = boxElement.offsetWidth;
for (let i = 0; i < length; i += 1) {
paragraphs[i].style.width = `${width}px`;
}
}
19. 인라인 메소드 안에서 이벤트 처리를 하지 말 것
소스 관리나 이벤트 처리 관점에서 혼란을 일으킴
20. eval()를 사용하지 말 것
구문 분석을 처리하는 과정에서 성능 문제가 크게 발생하며 보안측면에서도 매우 문제가 많음
21. with()를 사용하지 말 것
처리되는 과정에 대해 가독성 문제가 있으며 별도의 영역을 생성하여 성능문제도 발생
with(document.getElementById('myDiv').style) {
background = 'yellow';
color = 'red';
border = '1px solid black';
}
const {style} = document.getElementById('myDiv');
style.background = 'yellow';
style.color = 'red';
style.border = '1px solid black';
22. setTimeout/setInterval 사용시 문자열로된 callback 사용하지 말 것
내부적으로 문자열 함수에 대해 eval()
이 처리 됨으로 20. 과 같은 문제 발생
function callback() {
...
}
setTimeout('callback()', 1000);
23. 기본 객체를 수정하지 말 것
예측할 수 없는 오류가 발생할 가능성이 큼, 하지만 polyfill
처럼 긍정적인 사용방향도 있음
Monkey Patch
몽키패치- 런타임 중에 코드를 수정하는 것
Polyfill 처럼 구형 브라우저를 지원하기 위해 구형 브라우저의 코드를 수정해야 하거나, 개발 후 테스트를 진행할때 임시로 데이터 요청을 다른곳으로 요청하던지 하는 방식으로 사용될 수 있다. 그러나 동적으로 수정한다는 점에서 문제의 소지가 될 수 있다는점
24. 증감연산자(++/–)를 사용하지 말 것
i++
나 ++i
와 같이 처리와 할당의 관점이 혼란을 야기해서 편의에 비해 문제소지가 있음
let a = 1;
console.log(a++);
console.log(++a);
let b = 1;
console.log(b--);
console.log(--b);
25. this 를 따로 할당해서 쓰지 말 것
클로저로 사용할 수 있지만 가독성의 문제, 관련하여 다른 의견에서는 오히려 명시적인 구분이 된다는점에서 장점도 있다는 의견이 있음
function() {
const self = this;
return function() {
console.log(self);
};
}
function() {
const that = this;
return function() {
console.log(that);
};
}
function() {
const _this = this;
return function() {
console.log(_this);
};
}
function printContext() {
return function() {
console.log(this);
}.bind(this);
}
function printContext() {
return () => console.log(this);
}
26. 코드끝에 ;을 생략하지 말 것
구문의 분리가 명확하지 않고 내부적으로 누락된 ;
을 처리하는 과정에서 성능 문제 발생
27. (ES5)정의하기전에 사용하지 말 것
가독성 문제와 함께 호이스팅으로 인해 혼란 발생
28. (Legacy)배열 순회시, array.length값을 정의해서 쓸 것
IE10 과 같은 브라우저에서는 큰 성능문제를 일으킴