2020. 3. 2. 15:12ㆍ웹/Javascript Pattern
Javascript Patterns - 기본
1. 유지보수 가능한 코드 작성
-
읽기 쉽다
-
일관적이다
-
예측 가능하다
-
한 사람이 작성한 것처럼 보인다.
-
문서화되어 있다.
2. 전역 변수 최소화
-
전역변수의 문제점
-
자바스크립트 애플리케이션이나 웹페이지 내 모든 코드 사이에 공유된다는 점.
-
모든 전역 변수는 동일한 전역 네임스페이스 안에 존재하기 때문에, 애플리케이션 내의 다른 영역에서 목적이 다른 전역 변수를 동일한 이름으로 정의할 경우 서로 덮어쓰게 된다.
-
/*
* result는 선언되지 않은 상태로 사용.
* 이 코드는 잘 동작하지만, 이 함수를 호출하고 나면 전역 네임스페이스에 result라는 변수가 남아 문제를 유발
*/
function sum(x, y) {
result = x + y;
return result;
}
-
변수를 선언할 때 항상 var 명시
-
자바스크립트에서 변수를 선언하지 않고도 사용
-
암묵적 전역이라는 개념이 존재
-
/*
* 안티패턴, 사용하지 말것
* a 는 지역 변수, b는 전역변수가 된다.
*/
function foo() {
var a = b = 0;
}
※ 암묵적 전역 변수를 피해야하는 이유
이식성(portability) : 코드를 다른 실행 환경(호스트)에서 실행할 경우, 원래의 실행 환경에서는 존재하지 않았던 암묵적 전역 변수가 새로운 실행 환경의 호스트 객체를 의도치 않게 덮어쓸 수 있기 때문.
-
var 선언을 빼먹었을 때의 부작용
-
암묵적 전역 변수와 명시적으로 선언된 변수 사이에 존재하는 차이점은 delete 연산자를 사용하여 변수의 정의를 취소할 수 있는지 여부
-
var를 명시적으로 선언된 전역 변수는 삭제 X
-
var를 사용하지 않고 생성한 암묵적 전역 변수는 삭제 O
-
암묵적 전역 변수가 엄밀히 말하면 변수가 아니라 전역 객체의 프로퍼티라는 사실
-
// 세개의 전역 변수 정의
var global_var = 1;
global_novar = 2;
(function () {
global_fromfunc = 3;
});
// 삭제
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true
// 삭제 되었는지 확인
typeof global_var; // number
typeof global_novar; // undefined
typeof global_fromfunc; // undefined
-
전역 객체에 대한 접근
-
브라우저에서는 window 속성을 통해 전역 객체에 접근, 그러나 다른 환경에서는 존재하지 않을 수 있다.
-
// window 라는 식별자를 직접 사용하지 않고, 전역객체에 접근
var global = (function() {
return this;
});
-
단일 var 패턴
-
함수에서 필요로 하는 모든 지역 변수를 한군데서 찾을 수 있다.
-
변수를 선언하기 전에 사용할 때 발생하는 로직상의 오류를 막아준다.(hosting으로 인한 오류 유발)
-
변수를 먼저 선언한 후에 사용해야 한다는 사실을 상기시키기 때문에 전역 변수를 최소화하는데 도움이 된다.
-
코드량이 줄어든다.
-
function func() {
var a = 1,
b = 2,
sum = a + b,
myobject = {},
...
}
-
호이스팅(hosting) : 분산된 var 선언의 문제점
-
함수 내에 여기저기서 여러 개의 var 선언을 사용할 수 있지만, 실제로는 모두 함수 상단에서 변수가 선언된 것과 동일하게 동작 => 호이스팅
-
호이스팅으로 인해 함수 안에서 변수를 사용한 다음에 선언하면 로직상의 오류를 일으킬 수 있다.
-
// 안티 패턴
myname = "global"; // 전역변수
function func() {
alert(myname); // undefined
var myname = "local"; // 지역변수
alert(myname); // local
}
func();
// 위의 코드는 아래와 같이 동작
myname = "global"; // 전역변수
function func() {
var myname;
alert(myname); // undefined
myname = "local";
alert(myname); // local
}
func();
3. for 루프
-
HTMLCollection의 length를 캐시해야한다.
// 최적화되지 않은 루프
for(var i=0; i<array.length; i++ {
..
}
이 패턴의 문제점은 루프 순회시 마다 array.length(배열의 length)에 접근한다는 점
array가 배열이 아니라 HTMLCollection 이라면 이것으로 인해 코드가 느려질수 있다.
HTMLCollection은 length에 접근할 때마다 실제 DOM에 질의를 요청하는 것과 같으며, DOM 접근은 일반적으로 비용이 크다.
※ DOM 메서드에서 반환되는 HTMLCollection 객체
- document.getElementByName()
- document.getElementByClassName()
- document.getElementByTagName()
- 기타 등등..
for(var i=0, max=array.length; i<max; i++){
...
}
따라서 for 루프를 좀더 최적화하기 위해서는 배열의 length를 캐시해야한다.
-
미세 최적화
-
변수를 하나 덜 쓴다.(max 변수 사용 X)
-
카운트를 거꾸로 하여 0으로 내려간다. 0과 비교하는 것이 배열의 length 또는 0이 아닌 값과 비교하는 것보다 대개 더 빠르기 때문.
-
++, -- 은 JSLint에서 권장 하지 않는다.( i = i+1, i += 1 로 대체)
-
방법 1)
var i, array = [];
for(i=array.length; i--;){
..
}
방법 2)
var array = [], i=array.length;
while(i--){
...
}
4. For-in 루프
-
배열이 아닌 객체를 순환할때만 사용.
※ 배열도 객체이기 때문에 기술적으로 배열을 순회할수 있지만, 권장사항은 아니다.
-
hasOwnProperty
-
프로토타입 체인의 변경사항은 실시간으로 반영되기 때문에, 자동적으로 모든 객체가 이 새로운 메서드를 사용할 수 있다.
-
프로토타입의 프로퍼티를 스킵하기 위해서는 hasOwnProperty 함수 사용
var man = {
hand: 2,
legs: 2,
heads: 1
};
for(var i in man){
if(man.hasOwnProperty(i)){
console.log(i, " : ", man[i]);
}
}
for(var i in man){
console.log(i, " : ", man[i]);
}
console.log("============== clone 추가 ================");
if(typeof Object.prototype.clone === "undefined"){
Object.prototype.clone = function() {};
}
for(var i in man){
if(man.hasOwnProperty(i)){
console.log(i, " : ", man[i]);
}
}
for(var i in man){
console.log(i, " : ", man[i]);
}
-- 출력 결과 --
Hand : 2
Leg : 2
Heads : 1
Hand : 2
Leg : 2
Heads : 1
============== clone 추가 ================
Hand : 2
Leg : 2
Heads : 1
Hand : 2
Leg : 2
Heads : 1
Clone : f()
5. 내장 생성자 프로토타입 확장
Object, Array, Function과 같은 내장 생성자의 프로토타입을 확장하는 것은 코드의 지속성을 심각하게 저해시킬수 있다.
따라서, 내장 생성자 프로토타입을 확장하지 않는 것이 최선이다.
※ 예외가 허용되는 조건(3가지 조건 모두 만족 시)
-
해당 기능이 ECMAScript의 향후 버전이나 자바스크립트 구현에서 일관되게 내장 메서드로 구현될 예정이다.
예를 들어 ECMAScript 5에 기술되었으나 아직 브라우저에 내장되지 않은 메서드라면 추가할 수 있다.
이 경우에는 유용한 메서드를 미리 정의하는 것이라고 할 수 있다.
-
이 프로퍼티 또는 메서드가 이미 존재하는지, 이미 코드 어딘가에 구현되어 있거나, 지원 브라우저 중 일부 자바스크립트 엔진에 내장되어 있는지 확인
-
이 변경사항을 문서화하고 팀 내에 공유
`
출처 : JavaScript Patterns
'웹 > Javascript Pattern' 카테고리의 다른 글
코드 재사용 패턴(새로운 방식의 상속) - 프로퍼티 복사를 통한 상속 패턴 (0) | 2020.03.02 |
---|---|
코드 재사용 패턴(새로운 방식의 상속) - 프로토타입을 활용한 상속 (0) | 2020.03.02 |
코드 재사용 패턴(클래스 방식의 상속) - 프로토타입 공유 (0) | 2020.03.02 |
코드 재사용 패턴(클래스 방식의 상속) - 생성자 빌려쓰기 (0) | 2020.03.02 |
코드 재사용 패턴(클래스 방식의 상속) - 기본패턴 (0) | 2020.03.02 |