변수의 유효 범위란 프로그램에서 그 변수가 정의되어 있는 영역을 말한다.
전역 변수의 유효 범위는 전역적이다. 즉, 그 변수는 자바스크립트 코드 전체에 걸쳐 정의되어 있다.
반면, 어떤 함수 안에서 선언된 변수는 오직 그 함수 몸체 안에서만 정의된다. 이런 변수는 지역 변수라
불리며, 유효 범위도 지역적이다. 함수의 매개변수 역이 지역 변수이며 오직 해당 함수 내부에서만 정의된다.
함수 내부에서는 지역 변수가 같은 이름의 전역 변수 보다 우선적으로 사용된다. 만일 어떤 전역 변수와 같은 이름으로 지역 변수(또는 함수의 매개변수)를 선언할 경우, 원래의 전역 변수를 감추는 셈이 된다.
예를 들어, 다음 코드의 결과로 "local"이 출력된다.
var scope = "global"; // 전역 변수 선언
function checkscope() {
var scope = "local"; // 같은 이름의 지역 변수 선언
document.write(scope); // 전역 변수가 아닌 지역 변수가 사용된다.
}
checkscope(); // "local"을 출력
전역 유효 범위에서 코드를 작성한다면 var 문을 생략해도 문제가 되지 않지만,
지역 변수를 전언하려면 언제나 반드시 var 문을 써야 한다.
그러지 않을 경우 다음과 같은 일이 벌어질 수 있다.
scope = "global" // var가 없어도 문제없이 전역 변수로 선언된다.
function checkscope() {
scope = "local"; // 앗, 전역 변수의 값을 바꿔버렸다.
document.write(scope); // 전역 변수가 쓰인다.
myscope = "local"; // 새로운 전역 변수가 암묵적으로 선언된다.
document.write(myscope); // 새로 선언된 전역 변수가 쓰인다.
}
checkscope(); // "locallocal"을 출력
document.write(scope); // "local"을 출력
document.write(myscope); // "local"을 출력
일반적으로 함수에서 변수를 사용할 때 그것이 전역 변수인지 아니면 해당 함수에서만 정의된 변수인지
확인하지는 않는다. 따라서 어떤 함수에서 지역 변수 대신 전역 변수가 사용될 경우 그 함수 외의 프로그램
어딘가에서 사용될지도 모르는 값을 변경하는 위험을 감수해야 한다. 이러한 위험을 피하는 방법은 의외로
간단하다. 모든 변수를 var를 사용해서 지역 변수로 선언하는 것이다.
함수의 정의는 중첩될 수 있다. 각 함수에는 자신만의 유효 범위가 있다.
따라서 유효 범위가 여러 단계로 중첩될 수도 있다. 다음의 코드를 살펴보자.
var scope = "global scope" // 전역 변수
function checkscope() {
var scope = "local scope" // 지역 변수
function nested() {
var scope = "nested scope"; // 함수 안에 포함된 유효 범위의 지역 변수
document.write(scope); // "nested scope"를 출력
}
nested();
}
checkscope();
1. 블록 단위의 유효 범위는 없다.
C, C++, 자바와는 달리 자바스크립트에서는 블록 단위의 유효 범위라는 것이 존재하지 않는다.
함수 안에서 정의된 변수는 그것이 정의된 위치에 관계없이 항상 함수전체에 걸쳐 유효하다.
다음의 예에서 변수 i, j, k의 유효 범위는 모두 같다(함수 전체).
아래의 코드가 만일 C, C++, Java 등으로 작성되었다면 이와 다른 유효 범위를 가질 것이다.
if (typeof o == "object") {
for(var k = 0; k < 10; k++) { // k는 루프뿐만 아니라 함수 전체에서 정의된다.
document.write(k); // k는 여전히 정의되어 있다. 10이 출력된다.
document.write(j); // j는 정의되어 있지만, 초기화되지 않았을 가능성이 있다.
함수 안에서 선언된 변수는 모두 해당 함수 전체에 걸쳐 정의되어 있다 보니,
때로는 다음과 같은 놀라운 결과를 초래하기도 한다.
function f() {
var scope = "local"; // 변수는 이곳에서 초기화되었지만 함수 전체에 걸쳐 정의되어 있다.
alert(scope); // 여기서는 제대로 된 값이 출력된다.
f();
위의 예를 통해,
어떤 함수에서건 모든 변수의 선언을 함수의 시작부에 두는 것이 좋은 프로그래밍 습관임을 할 수 있다.
2. 정의되지 않은 변수 vs. 할당되지 않은 변수
우리는 앞 절에서 자바스크립트 프로그래밍에서의 미묘한 점, 즉 정의되지 않은 (undefined) 변수의 서로
다른 두 가지 종류를 살펴보았다. 정의되지 않은 변수의 첫 번째 종류는 아직 선언된 적이 없는 변수이다.
이러한 '선언되지 않은 변수'를 읽으려 하면 런타임 에러가 발생한다. 선언되지 않은 변수는 존재하지도
않기 때문에 당연히 정의되지 않은 상태다. 그러나 앞에서 설명한 바와 같이 정의되지 않은 변수에 값을
할당할 때는 에러가 발생하지 않는다. 이 경우에는 암묵적으로 해당 변수가 전역의 유효 범위로 선언된다.
정의되지 않은 변수의 두 번째 종류는 선언은 되었으나 아직 값이 할당되지 않은 경우다.
이러한 변수를 읽으려 하면 그 변수의 초기값, 즉 'undefined'를 얻게 된다. 앞서 설명했던 종류의 정의되지 않은 변수, 즉 선언되지 않았기에 존재하지도 않는 경우와 구별하기 위해서, 두 번째 종류의 정의되지 않은
변수를 좀 더 편리하게 '할당되지 않은(unassigned) 변수'로 부르기도 한다.
다음의 코드에서 아예 정의되지 않은 변수와 단지 할당만 되지 않은 변수의 차이점을 볼 수 있다.
var x; // 할당되지 않은 변수를 선언한다. 현재 값은 undefined이다.
alert(u); // 선언되지 않은 변수를 사용했기에 에러가 일어난다.
u = 3; // 선언되지 않은 변수에 값을 할당하려 하는 순간 이 변수가 생성된다.
'IT_Programming > JavaScript' 카테고리의 다른 글
자바스크립트 완벽가이드 - 4.5 가비지 컬렉션 (0) | 2010.07.04 |
---|---|
자바스크립트 완벽가이드 - 4.4 기본 타입과 참조 타입 (0) | 2010.07.04 |
자바스크립트 완벽가이드 - 4.1 변수 타입, 4.2 변수 선언 (0) | 2010.07.04 |
자바스크립트 완벽가이드 - 3.15 값에 의한 vs. 참조에 의한 (0) | 2010.07.04 |
자바스크립트 완벽가이드 - 3.14 객체에서 기본 타입으로 변환 (0) | 2010.07.04 |