본문 바로가기

javascript

변수의 유효범위

변수의 유효범위란?


프로그램에서 어떤 변수가 정의되어 있는 영역.


전역변수(global variable)


이름 그대로 유효범위가 전역적

자바스크립트 코드 전체에 걸쳐 정의되어 있다.


지역변수(local variable)


어떤 함수 안에서 선언된 변수

오직 해당 함수 몸체 안에서만 정의되어 있다.


지역변수가 전역변수와 같은 이름을 갖는 경우에는 함수 내부에서 지역변수가 우선!

전역 유효범위에서 var를 사용하지 않고 전역 변수를 선언할 수 있지만, 지역변수는 반드시 var를 사용해야한다. 

전역변수로 선언하지 않은 변수를 var 없이 함수안에서 선언하면 전역변수로 자동 선언된다!


1
2
3
4
5
6
7
8
9
10
11
12
scope = 'global';
 
function checkScope2() {
    scope = 'local'// 전역 변수를 변경
    myScope = 'local'//  변수를 선언
    return [scope, myScope];
 }
 
checkScope2(); // ['local', 'local']
scope // 'local'
myScope // 'local' ---> 함수 내에 선언되었지만 접근이 가능하다.(전역변수로 선언됨)
 
cs



함수의 정의는 중첩될 수도 있다.


함수가 중첩되었을 경우


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var scope = 'global'// 전역 변수
 
function checkScope() {
    var scope = 'local scope'// 지역 변수
 
    function nested() {
        var scope = 'nested scope';
        return scope;
    }
 
    return nested();
}
 
checkScope(); // 'nested scope'
 
cs






함수 유효범위와 끌어올림(hoisting)


자바스크립트에는 블록 유효범위의 개념이 아니라 함수 유효범위를 사용한다.

변수는 해당 변수가 정의된 함수 안에서 보일 뿐 아니라, 그 함수 안에 중첩된 함수 안에서도 보인다.


아래 예제는 i, j, k 는 다른 위치에 선언되지만 모두 같은 유효범위를 갖는다.


1
2
3
4
5
6
7
8
9
10
11
12
function test(o) {
    var i = o; // i는 함수 전체에 걸쳐 정의 된다.
    if(typeof o === "object") {
        var j = 0// j는 블록 뿐만아니라 함수 전체에 걸쳐 정의 된다.
        
        for(var k=0; k < 10; k++) {
            console.log(k); // k는 반복문 외에도 함수 전체에 걸쳐 정의된다. (숫자 0~9 출력)
        }
        console.log(k); // k는 여전히 정의되어 있다 (10 출력)
    }
    console.log(j); // j는 정의되어 있다
}    
cs



함수 유효범위란?

어떤 함수 안에서 선언된 모든 변수는 그 함수 전체에 걸쳐 유효하다.

변수가 미처 선언되기 전에도 유효하다는 뜻이기도 하다.



1
2
3
4
5
6
7
8
9
var scope = 'global';
 
function scopeTest() {
    console.log(scope); // undefined
 
    var scope = 'local';
    console.log(scope); // local
}
 
cs



scope를 초기화 하기 전에 콘솔 결과 값이 'global'로 출력될 것 같지만 undefined를 출력한다.

지역 변수는 함수 전체에 걸쳐서 정의된다. 즉, 지역변수와 같은 이름의 전역변수는 함수 내의 지역 변수에 의해 감춰진다.

바로 위의 코드에서의 scopeTest함수는 아래의 코드와 같다.

변수 선언이 함수 맨 꼭대기로 끌어올려진(hoisted) 것이다.


1
2
3
4
5
6
7
8
function scopeTest() {
    var scope; // 지역 변수는 함수 맨 꼭대기에서 선언한다.
    console.log(scope); // scope 변수는 존재하지만 아직 "undefined" 값이다.
 
    var scope = 'local'; // 이제 scope 변수가 초기화된고 제대로 된 값이 있다.
    console.log(scope); // local <--여기서는 우리가 기대한 값이 들어 있다.
}
 
cs




프로퍼티로서의 변수


자바스크립트 전역 변수  ==  전역 객체의 프로퍼티


var를 사용하면 생성된 프로퍼티는 수정 가능하지 않고 delete연산자로  소멸시킬 수 없다.


자바스크립트는 선언하지 않은 변수에 값을 대입하면 자동으로 전역 변수를 생성하는데 이런 식으로 생성된 변수는 전역객체의 평범하고 수정 가능한 프로퍼티이며 삭제할 수도 있다.


1
2
3
4
5
6
7
var trueVar = 1;
fakeVar = 2;
this.fakeVar2 = 3;
 
delete trueVar; // false
delete fakeVar; // true
delete this.faceVar2; // true
cs


자바스크립트의 전역 변수는 전역 객체의 프로퍼티이다. (ECMAScript 명세에 규정되어 있음.)

지역변수에는 전역 변수와 같은 규정은 없지만 지역변수는 변수를 각 함수 호출과 연관된 객체의 프로퍼티로 생각해도 된다.


자바스크립트는 this 키워드로 전역 객체를 참조할 수 있도록 한다.

하지만 지역변수가 저장된 객체를 참조할 방법은 제공하지 않는다.

지역변수를 각 함수 호출과 연관된 객체의 프로퍼티로 생각해도 된다.




유효범위 체인


자바스크립트는 언어적으로 유효범위를 가지고 있는(lexically scoped) 언어다.

변수의 유효범위란 정의된 변수를 사용 가능한 소스 코드의 집합으로 생각할 수 있다.

전역 변수는 프로그램 전체에 걸쳐 유효하다. 지역 변수는 변수가 선언된 함수 전체에 걸쳐 유효하고, 그 안에 중첩된 함수 내에서도 유효하다.


유효범위 체인은 해당 코드 무더기의 범위 안에 있는 변수를 정의하는 객체의 체인, 다시 말해 리스트이다.


1
2
3
4
5
6
7
8
9
10
11
12
var global = 1;
 
function outter() {
    var outterChain = 2;
    function inner() {
        var innerChain = 3;
        console.log("global: " + global);
        console.log("outterChain: " + outterChain);
        console.log("innerChain: " + innerChain);
    }
    inner();
}
cs



inner함수에서 변수를 찾을 수 없다면 outter함수를  outter함수에서 변수를 찾을 수 없다면 전역 변수를 탐색!


최상위 자바스크립트 코드의 경우(어떤 함수에도 속하지 않는 코드), 유효범위 체인은 단 하나의 '전역객체'만으로 이루어 진다.


함수가 정의될 때, 함수는 유효범위 체인을 저장한다.

함수가 호출될 때, 해당 함수의 지역 변수를 저장하기 위해서 새로운 객체를 하나 생성하고, 해당 객체를 기존에 저장된 유효범위 체인에 추가한다.



 inner

 innerChain = 3

[[scope chain]]


  outter

 outterChain = 2

[[scope chain]] 


 global

 global = 1





'javascript' 카테고리의 다른 글

변수 선언  (0) 2017.02.21
기본 표현식  (0) 2016.12.22
숫자  (0) 2016.12.13
타입, 값, 변수  (0) 2016.12.13
for... in  (0) 2016.12.05