Skip to content

Commit 38bf1bf

Browse files
committed
✏️ 4회차 문서 수정 : 전역 변수의 문제점
1 parent 57647bf commit 38bf1bf

1 file changed

Lines changed: 138 additions & 0 deletions

File tree

Javascript/global_variables.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,144 @@
11
자바스크립트의 특징이자, 문제인 전역 변수에 대해 알아봅시다.
22

33
## 전역 변수의 문제점
4+
> 전역 변수를 남용하면 많은 문제점이 있다고 합니다. 무슨 이유일까요?
5+
6+
### 변수의 생명주기
7+
> 변수는 자신이 선언된 위치에 생성되고 소멸합니다. 이를 생명 주기(Life Cycle)라고 해요.
8+
9+
예를 들어볼까요? 아래 예제는 `let`, `const`가 아닌 `var`를 사용하여 설명합니다.
10+
11+
```js
12+
var x = '전역';
13+
14+
function foo() {
15+
var y = '지역';
16+
console.log(y); // 지역
17+
return y;
18+
}
19+
20+
foo();
21+
console.log(y); // undefined
22+
```
23+
24+
함수 내부에 선언된 지역 변수(`y`)는 함수 호출 시 생성되고 함수 종료와 함께 소멸(`undefined`)합니다. 하지만 전역 변수(`x`)는 대체 언제 소멸, 아니 생성될까요?
25+
26+
우리는 호이스팅(Hoisting)에 대해 이해하고 있으니 변수 선언은 선언문의 위치 상관 없이 `가장 먼저 실행`됨을 알 수 있습니다. 이를 풀어서 말하면 런타임에 실행되는 것이 아니라, 그 이전 단계에서 자바스크립트 엔진에 의해 먼저 실행되는 것이라 할 수 있죠. 단, 이 설명은 지역 변수에 해당하지 않고, `전역 변수`에 해당합니다. 지역 변수는 위에서 언급한 그대로 실행되거든요! 그림으로 보면 이렇게 되겠죠?
27+
28+
```js
29+
var x = '전역'; // 전역 변수 x 생성
30+
31+
function foo() {
32+
// 지역 변수 y 생성
33+
var y = '지역'; // 지역 변수 y 값 할당
34+
console.log(y);
35+
return y;
36+
// 지역 변수 y 소멸
37+
}
38+
39+
foo();
40+
console.log(y); // undefined
41+
// 전역 변수 x 유효
42+
```
43+
44+
<br>
45+
46+
### 전역 변수의 문제점?
47+
> 어디서든 접근하고 변경할 수 있다면, 그것은 과연 좋기만 할까요?
48+
49+
이제부터 전역 변수가 가지는 문제점과 그 이유를 하나씩 살펴봅니다.
50+
51+
1. 암묵적 결합(Implicit Coupling)
52+
- 전역 변수를 개발자가 `의도하여` 선언한 경우, 해당 코드를 **어디서든 참조하거나 할당하겠다**는 겁니다.
53+
- 변수의 유효 범위가 클수록 가독성은 나빠집니다.
54+
- 예측하지 못한 영역에서 변수의 상태가 변경될 위험성이 높아집니다.
55+
56+
2. 긴 생명 주기(Long Life Cycle)
57+
- 전역 변수는 `애플리케이션의 생명 주기`**동일**합니다.
58+
- 활성화 되어 있는 시간이 기므로, 메모리 자원도 오래 소비합니다.
59+
- 전역 변수의 상태를 변경하거나 변경할 수 있는 위험성이 높습니다.
60+
- `var` 키워드는 변수 중복 선언을 허용하므로 의도치 않은 재할당이 이뤄질 수 있습니다.
61+
62+
3. 스코프 체인의 종점(Endpoint to Scope Chain)
63+
- 전역 변수가 `가장 마지막에` 검색됩니다. 즉, **전역 변수의 검색 속도가 가장 느립니다**.
64+
65+
4. 전역 네임스페이스 오염(Global Namespace Pollution)
66+
- 자바스크립트는 `파일이 분리`되어 있어도 **하나의 전역 스코프를 공유**합니다.
67+
- 다른 파일에 동일한 이름의 전역 변수가 존재하면 문제가 발생할 위험성이 높아집니다.
68+
69+
<br>
70+
71+
### 개선하는 방법
72+
> 전역 변수의 무분별한 사용은 위험한데, 어떻게 이를 방지(억제)할까요?
73+
74+
전역 변수를 **반드시** 사용해야 할 이유가 있다면 사용하는 것이 맞습니다. 그러나 변수의 스코프는 하위, 즉 좁을수록 좋습니다. 필요한 상황에서 생성과 소멸을 반복하게 만들어야 `명시적인 결합`이 가능해지니까요. 그럼 어떤 방식을 통해 방지할 수 있는지 알아볼까요?
75+
76+
1. 즉시 실행 함수(Immediately Invoked Function Expression)
77+
- `단 한 번 호출`되는 특성을 통해 **모든 변수를 즉시 실행 함수의 지역 변수**로 만드는 방법입니다.
78+
- 전역 변수를 생성하지 않으므로 `라이브러리`에 자주 사용됩니다.
79+
```js
80+
(function(){
81+
var x = 10; // IIFE의 지역 변수
82+
}());
83+
84+
console.log(x); // ReferenceError: x is not defined
85+
```
86+
1. 전역 네임스페이스 객체(Global Namespace Object)
87+
- 전역에 네임스페이스 역할을 담당할 객체를 선언하고, 사용할 전역 변수를 프로퍼티에 추가하는 방법입니다.
88+
- 네임스페이스를 가지므로 식별자가 충돌할 가능성은 낮아지나, 해당 객체가 `전역 변수`에 할당되므로 유용하진 않습니다.
89+
```js
90+
var APP = {}; // 전역 네임스페이스 객체
91+
92+
// 원시 값 할당하기
93+
App.school = false;
94+
95+
// 참조 값 할당하기
96+
App.person = {
97+
name: 'amy',
98+
age: 16,
99+
};
100+
101+
console.log(App.school); // false
102+
console.log(App.person.name); // amy
103+
```
104+
105+
3. 모듈 패턴(Module Pattern)
106+
- 클래스(Class)를 모방합니다. 변수, 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈을 만드는 방법입니다.
107+
- 자바스크립트의 `클로저`를 기반으로 동작합니다. 나중에 더 자세히 알아봐요!
108+
- 접근 제어자가 존재하지 않는 자바스크립트에서 객체 지향 프로그래밍의 특징인 **캡슐화(Encapsulation)** 를 흉내 낼 수 있습니다.
109+
```js
110+
var App = (function(){
111+
// 외부에서 참조가 불가능한 private 변수
112+
var year = 2021;
113+
114+
return {
115+
older() {
116+
return ++year;
117+
},
118+
younger() {
119+
return --year;
120+
},
121+
getYear() {
122+
return year;
123+
}
124+
}
125+
}());
126+
127+
console.log(App.year); // undefined
128+
129+
console.log(App.older()); // 2022
130+
console.log(App.getYear()); // 2022
131+
console.log(App.older()); // 2023
132+
console.log(App.getYear()); // 2023
133+
console.log(App.younger()); // 2022
134+
console.log(App.getYear()); // 2022
135+
```
136+
- 위 즉시 실행 함수는 객체를 반환합니다. 이 객체에는 외부에 노출시키고 싶은 변수, 함수를 담죠. 즉, 객체의 프로퍼티는 퍼블릭 멤버(Public Member)로 외부에서 참조가 가능하며, 객체에 추가하지 않은 프로퍼티는 프라이빗 멤버(Private Member)로 외부에서 참조할 수 없게 됩니다.
137+
138+
4. ES6 모듈
139+
- ES6에 추가된 모듈은 **파일 자체의 모듈 스코프**를 제공합니다. 즉 모듈 내에서 선언한 전역 변수는 window 객체의 프]로퍼티가 아닙니다.
140+
- HTML`<script type='module' src='app.js'></script>` 형태로 추가하면 로드된 자바스크립트 파일 `app.js`는 모듈로서 동작합니다.
141+
- 일반적으로 모던 브라우저가 아니면 사용할 수 없기에, Webpack 등의 모듈 번들러를 반드시 사용해야 합니다.
4142

5143
<hr>
6144
<br>

0 commit comments

Comments
 (0)