1. 전역 변수 선언을 삼가라
전연 변수를 자주 사용하는 것은 모든 사람과 공유하는 공통의 네임스페이스를 더럽히고 뜻하지 않게
이름이 충돌할 만한 가능성을 만들 수 있다.
또한 프로그램의 구분된 요소들 간에 불필요한 결합을 초래하기에 모듈성에 반대되는 성향을 가지게 된다.
물론 라이브러리나 컴포넌트 같은 경우는 프로그램의 다른 부분에서도 사용을 가능하게 해야하므로 전역변수로
선언하는 것은 무리되지 않는다.
그런 경우가 아니라면 지역 변수로 모든 변수를 유지하는 것이 최선이다.
[예시]
<전역변수>
var i,n,sum;
function score(player){
sum = 0;
for(i = 0 '; i < player.levels.length ; i < n ; i++) {
sum += player.levels[i].score;
}
return sum;
}
<지역변수>
function score(player){
var i,n,sum;
sum = 0;
for(i = 0 '; i < player.levels.length ; i < n ; i++) {
sum += player.levels[i].score;
}
return sum;
}
아래 식대로 진행해야 발생할 수 있는 문제를 기존에 방지하고 올바르게 작동할 수 있도록 할 수 있을 것 입니다.
전역 객체는 프로그램의 최상단에서 this키워드로 접근할 수 있습니다.
웹 브라우저에서는 전역 객체가 전역 window 변수에도 바인딩되어 있습니다.
전역 변수를 추가하거나 수정하면 자동으로 전역 객체가 갱신됩니다.
var global = "global";
this.global = "local";
global; // local 출력
다음과 같이 만약 global이라고 명명한 변수가 전역 객체로 선언되어 있다면, window 변수에 바인딩 되어 있을테고,
해당 값을 this키워드로 접근하여 변경시킬 수 있다.
전역 변수를 수정하였기 때문에 global를 찍게 되면 개인되어서 local이라고 나오게 됩니다.
2. With를 사용하지 말아라 !
프로그램은 종종 하나의 객체에서 여러 메서드를 호출해야 하는데, 해당 객체에 대한 참조를 반복할 필요가 없는 경우에는
with를 사용하는 편이 편리하다.
[예시]
function status(info){
var widget = new Widget();
with(target) {
setBackground("blue");
setForeground("white");
setText("status : " + info);
show();
}
}
이렇게 하게 되면 객체에서 프로퍼티를 추출해 내어 블록 내의 지역 변수로 바인딩한 모양인데, 실제 문법 상으로는
변수들과 구분할 방법이 없다.
프로퍼티가 변수처럼 보일 수 있다는 말이다.
자바스크립트는 변수를 스코프 내에서 찾을 때 가장 안쪽에서부터 시작해 바깥쪽으로 넓혀가면서 찾는다.
즉, with 블록 내부에서는 주어진 변수 이름을 가진 프로퍼티부터 찾기 시작하며 없으면 외부 scope로 이어서 탐색하게 된다.
with 대신에 다음 코드를 아래와 같이 작업하자
function status(info){
var w = new Widget();
w.setBackground("blue");
w.setForeground("white");
w.addText("Status :" + info);
w.show();
}
Widget.prototype.info = "[[widget info]]";
status("connected"); // Status : connected
어떠한 코드가 Widget의 prototype을 수정하더라도 status 함수는 계속해서 기대한 대로 동작한다.
다른 경우에는 지역 변수를 명시적으로 연관된 프로퍼티와 바인딩하는 방법이 있다.
function f(x,y){
var min = Math.min , round = Math.round , sqrt = Math.sqrt;
return min(round(x), sqrt(y));
}
With 선언문은 되도록 쓰지 않는 것이 좋으며 , 객체로의 반복되는 접근을 위해 짧은 변수 이름을 사용하는 것이 좋다.
또한 With 선언문으로 암묵적으로 바인딩하는 대신에 명시적으로 지역 변수를 객체 프로퍼티에 바인딩하는 것이 좋다.
3. 클로저 개념에 익숙해지자 !
: 클로저란 간단히 설명하자면 함수 단위의 스코프로 계산된다는 점이다. 그와 관련되어서 조금 더 deep 하게 들어가보자
1. 자바스크립트는 현재 함수 외부에서 선언된 변수를 참조할 수 있다.
function makeSandwich() {
var magicIngredient = "peanut butter";
function make(filling) {
return magicIngredient + " and " + filling ;
}
return make("jelly");
}
makeSandwich(); // "peanet butter and jelly";
다음 코드를 보면 magicIngredient는 makeSandwich() 함수 내에서 선언된 변수입니다.
따지고 보면 make(filling) 이라는 함수 바깥에서 선언된 변수이지요.
이러한 변수를 make 함수 기준으로 보았을 떄 외부에 선언된 변수라고 할 수 있는데, 이를 make함수 내부에서 참조하여 사용하였습니다.
클로저의 첫 번쨰 개념은 다음과 같이 함수 기준으로 하였을 때 외부에서 선언된 변수를 내부에 정의된 함수에서 참조하여 활용할 수 있습니다.
2. 함수는 외부 함수가 무언가를 리턴한 이후에도 이 외부 함수에 선언된 변수를 참조할 수 있다.
자바스크립트 함수가 일종 객체라는 사실을 확인하면 이 말을 이해하기 쉬울 것이다.
function makeSandwich() {
var magicIngredient = "peanut butter";
function make(filling) {
return magicIngredient + " and " + filling ;
}
return make;
}
var f = makeSandwich();
makeSandwich 함수에서 리턴 값으로 내부 함수인 make를 반환하고 있다.
따라서 makeSandwich 함수를 f로 정의하고 f("jelly") 와 같은 선언을 진행하게 된다면 make 함수를 불러와서
"peanut butter and jelly" 와 같은 결과가 나오게 될 것 입니다.
또한 앞서 내용과 마찬가지로 make 내부 함수는 외부 변수를 참조하여 magicIngredient 변수를 기억 하기 때문에 그대로
기존 결과와 동일하게 나오는 일이 발생하게 되는 것 입니다.
이러한 일이 가능한 이유는 자바스크립트 함수는 해당 스코프에서 선언되어 참조할 수 있는 어떤 변수더라도 내부적으로 보관하게 됩니다.
함수 자신이 포함하고 있는 스코프의 변수들을 추적하는 함수를 "클로저" 라고 합니다.
즉, make 함수는 magicIngredient 외부 변수와 filling 이라는 내부 변수(인자)를 참조하는 클로저입니다.
함수는 파라미터와 외부 함수의 변수 뿐 아니라 해당 스코프 내에 포함된 어떠한 변수더라도 참조를 할 수 있습니다.
magicIngredient 변수도 makeSandwich 함수의 인자로 들어가서 표현되어도 참조하여 사용할 수 있습니다.
3. 클로저는 외부 변수의 값을 변경할 수 있다.
클로저는 실제로 외부 변수의 값을 복사하지 않고 참조를 저장한다. (포인터 느낌)
따라서 그들에게 접근하는 어떤 클로저도 변경사항으로 볼 수 있다.
function box(){
var val = undefined;
return {
set : function(newVal) { return val = newVal; } ,
get : function() { return val; } ,
type : function() { return typeof val; }
};
}
box라는 함수의 내부 변수로 val를 선언하고 반환 값으로 set , get , type 이 세 가지의 함수를 반환한다 .
이 세 함수 각각 box 함수를 참조하고 있으며 외부 변수 val를 참조하고 있다.
포인터 개념으로 생각 했을 때 set 함수 같은 경우 val를 참조만 하고 있으므로 인자(내부 변수)로 참조하게 되면
newVal를 통해 val 값을 수정할 수 있다.
var f = box();
f.set("abc"); // abc 만들어 짐 (val = "abc");
f.get(); // abc 출력
f.type(); // "string" 출력
다음과 같이 클로저 개념에서 내부 함수가 참조한 외부 변수의 val 값을 내부 함수 자신이 갖는 범위 내에서의 변수를 참조하여 변경하고 이를 출력 및 타입 출력을 통해 표현한 것이다.
총 정리를 하자면 함수는 외부 스코프에 선언된 변수를 참조할 수 있으며 클로저는 자신을 생성한 함수보다 더 오래 지속된다는 점이다.
(외부 변수 , 외부 함수 등도 참조할 수 있기 때문)
그리고 클로저는 내부적으로 외부 변수에 대한 참조를 저장하고 , 저장된 변수를 읽고 갱신할 수 있다.
이상 변수에 대해 알아보았습니다. 감사합니다.
'Node.js & Javascript' 카테고리의 다른 글
| S3 사용법 (2) | 2018.04.06 |
|---|---|
| module 관리 (0) | 2018.03.15 |
| 자바스크립트 함수(1) (0) | 2018.03.08 |
| 자바스크립트 변수(2) (2) | 2018.03.07 |
| FCM 푸시 [서버편] (0) | 2018.03.01 |