너무 좋은 인사이트가 많이 담긴 글을 봐서 공유한다.
Ternary Conditional (삼항 연산자)
1 2 3 4 5 6 7 8 9 10 11 |
// 두개 이상의 변수를 이용하여 값을 받는 경우 isArthur && isKing ? (weapon = "Ex", helmet = "Goose") : (weapon = "ln", helmet = "Iron")
// 즉시 실행함수로 값을 받는 경우 isArthur && isKing ? function () { // ... }( ); : function () { // ... }( ); |
Logical Assignment 1 (OR)
- OR 연산자 : “falsy” 하지 않은 가장 첫번째 마주친 값을 갖는다.
- 아래의 삼항 연산자를 OR 연산자를 이용하여 다음과 같이 줄일 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// 삼항연산자 사용 function addSword(sword) { this.swords = this.swords ? this.swords : [ ]; this.swords = push.(sword); }
// OR 연산자 사용 function addSword(sword) { this.swords = this.swords || [ ]; this.swords = push.(sword); }
// OR 연산자 잘못 사용한 예 function addSword(sword) { this.swords = [ ] || this.swords; this.swords = push.(sword); } // 위의 경우 계속 new array 를 할당함. |
- OR 연산자의 잘못된 사용 예를 더 본다.
1 2 3 4 5 6 7 8 9 |
// 잘못된 OR 연산자 사용 예 var result1 = 42 || undefined; // undefined 를 절대로 마주치지 않는다. var result2 = ["Sweet", "array"] || 0; // 0을 절대로 마주치지 않는다. var result3 = {type: "ring", stone: "diamond"} || ""; // "" 를 절대로 맞추지지 않는다.
// 위를 고쳐보면, var result1 = undefined || 42; var result2 = 0 || ["Sweet", "array"]; // 0을 절대로 마주치지 않는다. var result3 = "" || {type: "ring", stone: "diamond"}; // "" 를 절대로 맞추지지 않는다. |
Logical Assignment 2 (And)
- OR 연산자와는 다르게 두개의 “truthy” 값이 있으면, 마지막으로 확인한 truthy 값이 리턴된다.
- “falsy” 값의 경우에는 OR 연산자와 동일하게 동작한다.
1 2 3 4 |
var result1 = "King" && "Arthur"; console.log(result1); //Arthur var result2 = "Arthur" && "King"; console.log(result2); // King |
Switch Blocks
- 반복되는 if else 문과 switch 문의 차이점은, 순차적으로 모든 if 문을 도느냐. 아니면 해당하는 case 로 바로 가서 불필요한 연산을 줄이느냐의 차이이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var regimnet = 3;
if (regiment == 1) { ... } else if (regiment == 2) { ... } else if (regiment == 3) { // 앞 1,2 를 거쳐 3으로 온다. ... }
switch (regiment) { case 1: ... case 2: ... case 3: // 3으로 바로 온다. ... } |
- break 문을 사용하지 않고, 공통된 property 를 상위 case 에서 부터 순차적으로 접근하여 추가하는 방법도 있다.
Loop Optimization
- 컴퓨터 메모리 관점에서 일반적인 for 문의 연산 순서를 보자.
1 2 3 4 5 6 7 |
treasureChest = { necklaces: ["A", "B", "C", "D"]; };
for (var i = 0; i < treasureChest.necklaces.length; i++) { console.log(treasureChest.necklaces[i]); } |
- 위 for 문에서 메모리 연산이 필요한 부분은 다음과 같다.
- i 값 탐색
- treasureChest 객체 탐색
- necklaces 속성 탐색
- necklaces 속성의 배열 인덱스 탐색
- length 프로퍼티 검색 > 위의 연산을 최적화 해보자 : Cache the necessary values in the local variables
1 2 3 4 5 |
// 1. length property 를 한번만 접근 (기존 for 문은 반복시 마다 접근) var x = treasureChest.necklaces.length; for (var i = 0; i < x; i++) { console.log(treasureChest.necklaces[i]); } |
- 위의 리팩토링으로 연산 수가 다음과 같이 줄어들었다.
- 위 코드는 더 개선할 수 있다.
1 2 3 4 |
// 2. for 문의 초기 선언문 쪽에서 x 값을 선언하면, 전역 변수로 var x 를 선언하지 않아도 되어 메모리가 더 효율적이게 된다. for (var i = 0, x = treasureChest.necklaces.length; i < x; i++) { console.log(treasureChest.necklaces[i]); } |
-
주의할 점 : 자바스크립트는 {} 로 스코핑이 되어 있지 않기 때문에, 위의 for 반복문이 끝나면 x 값은 최종 값으로 할당되어 있다는 사실
-
또 다른 개선 포인트
1 2 3 4 |
// 3. 각 반복 싸이클마다 treasureChest 객체의 속성에 접근을 할 필요가 없다. var list = treasureChest.necklaces; for (var i = 0, x = treasureChest.necklaces.length; i < x; i++) { console.log(list[i]); } |
모든 인덱스를 접근할 때에는 for loop 문이 좋고, 때로는 for in 보다 성능이 나은 경우가 있다. for in 은 prototype 에 접근하여 기존의 기 정의된 메서드까지 포함하여 출력하므로 비효율적
Performance (Script Loading)
- Work Intensive javascript 는 body 마지막 태그 맨 위나 async 속성 이용하여 페이지 첫 로딩을 빠르게 한다.
Performance (Inheritance)
- 자바스크립트에서 상속은 prototype 을 이용
- 공통으로 쓰는 메서드는 모두 prototype 에 집어 넣는다.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function SignalFire(id, logs) { this.id = id; this.logs = logs; this.functionality1: function() {
}, this.functionality2: function() {
}, this.functionality3: function() {
}, } |
- 위 함수의 경우 매번 객체를 생성할 때 마다 사용하지 않는 메서드들을 메모리에서 사용하는 낭비가 발생한다.
- 따라서, 매번 객체 생성시 필요한 속성이나 메서드만 가져가도록 하고, 공통 메서드는 다음과 같이 prototype 으로 뺀다.
1 2 3 4 5 6 7 8 9 10 11 |
SignalFire.prototype = { functionality1: function() {
}, functionality2: function() {
}, functionality3: function() {
}, } |
Performance (Indivdual DOM)
- list 를 배열로 갖는 DOM 요소에 append 메서드를 이용하여 DOM 을 추가하면 전체 리스트가 reflow 된다. 이는 성능에 악영향을 준다.
- 성능 향상을 위한 해결법은 Fragment 를 사용한다.
1 2 3 |
var fragment = document.createDocumentFragment(); fragment.appendChild(element); list.appendChild(fragment); |
Performance (Get rid of var redundancy)
- var 지정어를 사용할 떄, 다음과 같이 코드량을 줄일 수 있다.
1 2 3 4 5 6 7 8 9 |
var a = 1; var b = "hello"; var c = ["a","b","c"];
var a = 1, b = "hello", c = ["a","b","c"];
// 코드의 가독성이 높아지고, 간결하다. |
Performance (String Concatenation)
- 문자열의 길이에 따라 += 연산자와 join() 메서드의 성능차이가 발생한다.
- 문자열이 짧을 떄 : += 연산자가 성능이 더 빠르다.
- 문자열이 길고, 문자열이 배열안에 리스트 형태로 저장되어 있을 때 : join("\n") 메서드가 성능이 우월하다.
1 2 3 4 5 6 7 |
var page = ""; for (var i = 0, x = newPageBuild.length ; i < x ; i++) { page += newPageBuild[i]; }
// join() 메서드 활용 page = newPageBuild.join("\n"); |
Namespacing
- 팀 프로젝트 시 많은 양의 자바스크립트 코드를 작성할 때, 타 팀원이 작성한 전역변수가 overwrite 되는 경우가 발생한다.
- 이를 막기 위해 namespacing 을 활용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var a = ["Apple", "Banana", "Coil"]; var c = function () { console.log("this is not what I want."); };
var nameSpace = { a : "1", b : 23, c : function() { // ... } };
// HTML Element click event onClick=nameSpace.c(); |
출처 : joshuajangblog.wordpress.com/2016/11/21/javascript-coding-pattern-for-junior-web-developer/
'개발 > javascript' 카테고리의 다른 글
React Array Toggle Element (리액트 배열 값 토글하기!) (0) | 2021.07.16 |
---|---|
React useState() Object 내부 값 변경 (0) | 2021.07.05 |
[Javascript] 당신의 머리를 터지게 만들 Instanceof (0) | 2020.12.17 |
[Javascript] instance of, arguments, callee, this, new (0) | 2020.12.16 |
자바스크립트만의 특징 몇가지 (ft. 호이스팅) + 예시 퀴즈 (0) | 2020.12.07 |