1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
---
title: var
slug: Web/JavaScript/Reference/Statements/var
tags:
- JavaScript
- Reference
- Statement
translation_of: Web/JavaScript/Reference/Statements/var
---
<div>{{jsSidebar("Statements")}}</div>
<p><code><strong>var</strong></code>문은 변수를 선언하고, 선택적으로 초기화할 수 있습니다.</p>
<div>{{EmbedInteractiveExample("pages/js/statement-var.html")}}</div>
<h2 id="구문">구문</h2>
<pre class="syntaxbox">var <em>varname1 [</em>= <em>value1 [</em>, <em>varname2 [</em>, <em>varname3 ... [</em>, <em>varnameN]]]]</em>;</pre>
<dl>
<dt><code>varnameN</code></dt>
<dd>변수 이름. 어떤 유효한 식별자도 될 수 있습니다.</dd>
</dl>
<dl>
<dt><code>valueN</code></dt>
<dd>변수의 초기값. 어떤 유효한 표현도 될 수 있습니다.</dd>
</dl>
<h2 id="설명">설명</h2>
<p>어디에 선언이 되어있든 간에 변수들은 어떠한 코드가 실행되기 전에 처리가 됩니다. var로 선언된 변수의 범위는 현재 실행 문맥인데, 그 문맥은 둘러싼 함수, 혹은 함수의 외부에 전역으로 선언된 변수도 될 수 있습니다.</p>
<p>선언된 변수들의 값 할당은 할당이 실행될 때 전역변수(이것은 전역 오브젝트의 프로퍼티가 됩니다)처럼 생성이 됩니다. 선언된 변수들과 선언되지 않은 변수들의 차이점은 다음과 같습니다:</p>
<p>1. 선언된 변수들은 변수가 선언된 실행 콘텍스트(execution context) 안에서 만들어집니다. 선언되지 않은 변수들은 항상 전역변수 입니다.</p>
<pre class="brush: js">function x() {
y = 1; // strict 모드에서는 ReferenceError를 출력합니다.
var z = 2;
}
x();
console.log(y); // 로그에 "1" 출력합니다.
console.log(z); // ReferenceError: z is not defined outside x를 출력합니다.
</pre>
<p>2. 선언된 변수들은 어떠한 코드가 실행되기 전에 만들어집니다. 선언되지 않은 변수들은 변수들을 할당하는 코드가 실행되기 전까지는 존재하지 않습니다.</p>
<pre class="brush: js">console.log(a); // ReferenceError를 출력합니다.
console.log('still going...'); // 결코 실행되지 않습니다.</pre>
<pre class="brush: js">var a;
console.log(a); // 브라우저에 따라 로그에 "undefined" 또는 "" 출력합니다.
console.log('still going...'); // 로그에 "still going..." 출력합니다.</pre>
<p>3. 선언된 변수들은 변수들의 실행 콘텍스트(execution context)의 프로퍼티를 변경되지 않습니다. 선언되지 않은 변수들은 변경 가능합니다. (e.g 삭제 될 수도 있습니다.)</p>
<pre class="brush: js">var a = 1;
b = 2;
delete this.a; // strict 모드에서는 TypeError를 출력합니다. 그렇지 않으면 자동적으로 실패합니다.
delete this.b;
console.log(a, b); // ReferenceError를 출력합니다.
// 'b' 프로퍼티는 삭제되었고, 어디에도 존재하지 않습니다.</pre>
<p>이러한 세가지 다른점 때문에, 변수 선언 오류는 예기치않은 결과로 이어질 가능성이 높습니다. 그러므로 <strong>함수 또는 전역 범위인지 여부와 상관없이, 항상 변수를 선언 하는 것을 추천합니다.</strong> 그리고 ECMAScript 5 안에 <a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">strict mode</a>, 선언되지 않은 변수에 할당하면 오류를 출력합니다.</p>
<h3 id="var_호이스팅(hoisting)">var 호이스팅(hoisting)</h3>
<p>변수 선언들 (그리고 일반적인 선언)은 어느 코드가 실행 되기 전에 처리하기 때문에, 코드 안에서 어디서든 변수 선언은 최상위에 선언한 것과 동등합니다. 이것은 변수가 선언되기 전에 사용 될 수 있다는 것을 의미합니다. 변수 선언이 함수 또는 전역 코드의 상단에 이동하는 것과 같은 행동을 "호이스팅(hoisting)"이라고 불립니다.</p>
<pre class="brush: js">bla = 2
var bla;
// ...
// 위 선언을 다음과 같이 암묵적으로 이해하면 됩니다:
var bla;
bla = 2;
</pre>
<p>이러한 이유로, 그들의 범위(전역 코드의 상단 그리고 함수 코드의 상단) 상단에 변수를 항상 선언하기를 권장합니다. 그러면 변수는 함수 범위 (지역)이 되며, 스코프 체인으로 해결될 것이 분명합니다.</p>
<h2 id="예제">예제</h2>
<h3 id="두_변수들의_선언_및_초기화">두 변수들의 선언 및 초기화</h3>
<pre class="brush: js">var a = 0, b = 0;
</pre>
<h3 id="단일_문자열_값으로_두_변수들_할당">단일 문자열 값으로 두 변수들 할당</h3>
<pre class="brush: js">var a = "A";
var b = a;
// 다음과 같음:
var a, b = a = "A";
</pre>
<p>순서에 유의:</p>
<pre class="brush: js">var x = y, y = 'A';
console.log(x + y); // undefinedA
</pre>
<p>여기, x와 y는 어떠한 코드 실행하기 전에 선언되었다, 할당은 후에 발생하였다. "<code>x = y</code>"가 실행될 때, <code>y<font face="Open Sans, Arial, sans-serif">는 존재하여 </font></code><code>ReferenceError를 출력하진 않고</code> 값은 '<code>undefined</code>' 입니다. 그래서, <code>x는</code> undefined 값이 할당 됩니다. 그리고나서, <code>y는 </code>'A' 값이 할당 됩니다. 결과적으로, 첫번째 줄 이후에, <code>x === undefined && y === 'A'</code>, 이와 같은 결과가 됩니다.</p>
<h3 id="다수의_변수들의_초기화">다수의 변수들의 초기화</h3>
<pre class="brush: js">var x = 0;
function f(){
var x = y = 1; // x는 지역변수로 선언됩니다. y는 아닙니다!
}
f();
console.log(x, y); // 0, 1
// x는 예상대로 전역이다
// y leaked outside of the function, though! </pre>
<h3 id="암묵적인_전역변수와_외부_함수_범위">암묵적인 전역변수와 외부 함수 범위</h3>
<p>암묵적인 전역변수가 될 것으로 보이는 변수는 함수 범위 밖에서 변수들을 참조할 수 있다.</p>
<pre class="brush: js">var x = 0; // x는 전역으로 선언되었고, 0으로 할당됩니다.
console.log(typeof z); // undefined, z는 아직 존재하지 않습니다.
function a() { // a 함수를 호출했을 때,
var y = 2; // y는 함수 a에서 지역변수로 선언되었으며, 2로 할당됩니다.
console.log(x, y); // 0 2
function b() { // b 함수를 호출하였을때,
x = 3; // 존재하는 전역 x값에 3을 할당, 새로운 전역 var 변수를 만들지 않습니다.
y = 4; // 존재하는 외부 y값에 4를 할당, 새로운 전역 var 변수를 만들지 않습니다.
z = 5; // 새로운 전역 z 변수를 생성하고 5를 할당 합니다.
} // (strict mode에서는 ReferenceError를 출력합니다.)
b(); // 호출되는 b는 전역 변수로 z를 생성합니다.
console.log(x, y, z); // 3 4 5
}
a(); // 호출되는 a는 또한 b를 호출합니다.
console.log(x, z); // 3 5
console.log(typeof y); // undefined y는 function a에서 지역 변수입니다.</pre>
<h2 id="명세">명세</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">명세</th>
<th scope="col">상태</th>
<th scope="col">비고</th>
</tr>
<tr>
<td>{{SpecName('ES1')}}</td>
<td>{{Spec2('ES1')}}</td>
<td>Initial definition. Implemented in JavaScript 1.0</td>
</tr>
<tr>
<td>{{SpecName('ES5.1', '#sec-12.2', 'var statement')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td> </td>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-variable-statement', 'variable statement')}}</td>
<td>{{Spec2('ES6')}}</td>
<td> </td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-variable-statement', 'variable statement')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="브라우저_호환성">브라우저 호환성</h2>
<p>{{Compat("javascript.statements.var")}}</p>
<h2 id="같이_보기">같이 보기</h2>
<ul>
<li>{{jsxref("Statements/let", "let")}}</li>
<li>{{jsxref("Statements/const", "const")}}</li>
</ul>
|