본문 바로가기
Programming/JavaScript

[ JavaScript ] 자바스크립트 전역변수와 지역변수 | 변수의 유효범위

by 코뮤(commu) 2021. 2. 3.
728x90
반응형

이미지 출처 :   https://commons.wikimedia.org/wiki/File:JavaScript-logo.png

 

 

 

 

 

해당 포스팅은 생활코딩의 이고잉 님의 강의를 기반으로 개인 공부용으로 정리한 포스팅임을 미리 알립니다.

 

 

 


 

 

전역변수

 

 

 

유효범위(Scope)는 변수의 수명을 의미합니다. 

 

 

 

 

var vscope = 'global';
function fscope(){
    console.log(vscope);
}
fscope();

 

 

 

 

 

 

 

함수 밖에서 변수를 선언하면 그 변수는 전역변수가 됩니다.

전역변수는 애플리케이션 전역에서 접근이 가능한 변수입니다.

 

다시 말해서 어떤 함수 안에서도 그 변수에 접근 할 수 있는 것입니다.

때문에 함수 fscope 내에서 vscope를 호출 했을 때 함수 밖에서 선언된 vscope의 값 global이 반환된 것입니다. 

 

 

 

 

 

지역변수

 

 

 

 

var vscope = 'global';
function fscope(){
    var vscope = 'local';
    console.log('함수안 '+vscope);
}
fscope();
console.log('함수밖 '+vscope);

 

 

 

 

 

위의 예시에서 변수 vscope을 조회(4행) 했을 때

함수 내에서 선언한 지역변수 vscope(3행)의 값인 local이 사용되었습니다.

 

 

하지만 함수 밖에서 vscope를 호출(7행) 했을 때는

전역변수 vscope(1행)의 값인 global이 사용된 것입니다.

 

즉 지역변수의 유효범위는 함수 안이고,

전역변수의 유효범위는 에플리케이션 전역인데,

 

같은 이름의 지역변수와 전역변수가 동시에 정의되어 있다면 지역변수가 우선한다는 것을 알 수 있습니다. 

 

 

 

 

 

아래 예제의 출력값은 어떻게 될까요?

 

 

 

var vscope = 'global';
function fscope(){
    vscope = 'local';
    console.log('함수안'+vscope);
}
fscope();
console.log('함수밖'+vscope);

 

 

 

 

충분히 예상을 하고 결과값을 확인해보시길 바랍니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

둘 다 local 을 출력합니다. 예측하셨나요?

 

함수밖에서도 vscope의 값이 local인 이유는 무엇일까요?

 

 

그것은 함수 fscope의 지역변수를 선언할 때 var를 사용하지 않았기 때문입니다.

 

var를 사용하지 않은 지역변수는 전역변수가 됩니다.

 

따라서 3행은 전역변수의 값을 local로 변경하게 된 것입니다.

var을 쓰는 것과 쓰지 않는 것의 차이를 알아가시면 좋을 것 같습니다.

 

 

 

다른 예제들도 봅시다.

 

 

 

function a (){
    var i = 0;
}
for(var i = 0; i < 5; i++){
    a();
    console.log(i);
}

 

 

 

 

 

 

위의 예제에서 함수 a 안의 변수 i 는 지역변수이기 때문에, for 문에서 쓰이는 전역변수 i 에게

영향을 미치지 않습니다.

 

만약 함수 a 의 변수 i 를 사용할 때, var 로 변수선언을 하지 않으면 어떻게 될까요?

 

 

 

function a (){
    i = 0;
}
for(i = 0; i < 5; i++){
    a();
    console.log(i);
}

 

 

위의 예제는 무한반복을 발생시킵니다.

함수 a 에서 사용하는 변수 i 가 for 문의 변수 i 이기 때문에, 무한루프가 생기는 것입니다.

 

 

 

 

참고로, 전역변수는 사용하지 않는 것이 좋습니다.

 

여러가지 이유로 그 값이 변경될 수 있기 때문입니다.

 

함수 안에서 전역변수를 사용하고 있는데, 누군가에 의해서 전역변수의 값이 달라졌다면 어떻게 될까요?

 

 

함수의 동작도 달라지게 되겠죠. 이것은 버그의 원인이 될 수 있습니다.

 

또한 함수를 다른 애플리케이션에 이식하는데도 어려움을 초래합니다.

 

함수의 핵심은 로직의 재활용이라는 점을 상기시켜야합니다.

 

 

변수를 선언할 때는 꼭 var을 붙이는 것을 습관화해야 합니다.
전역변수를 사용해야 하는 경우라면 그것을 사용하는 이유를 명확히 알고 있을 때 사용하도록 합시다.

 

 

 

 

전역변수의 사용

 

 

 

불가피하게 전역변수를 사용해야하는 경우,

하나의 객체를 전역변수로 만들고 객체의 속성으로 변수를 관리하는 방법을 사용하면 됩니다.

 

 

MYAPP = {}
MYAPP.calculator = {
    'left' : null,
    'right' : null
}
MYAPP.coordinate = {
    'left' : null,
    'right' : null
}
 
MYAPP.calculator.left = 10;
MYAPP.calculator.right = 20;
function sum(){
    return MYAPP.calculator.left + MYAPP.calculator.right;
}
console.log(sum());

 

위의 예시와 같이 코드를 작성하게 된다면 전역변수는 MYAPP 이라는 객체 하나만 생성이 됩니다.

 

 

만약 전역변수를 하나도 사용하고 싶지 않다면,

아래와 같이 익명함수를 호출함으로서 이러한 목적을 달성할 수 있습니다.

 

 

 

(function(){
    var MYAPP = {}
    MYAPP.calculator = {
        'left' : null,
        'right' : null
    }
    MYAPP.coordinate = {
        'left' : null,
        'right' : null
    }
    MYAPP.calculator.left = 10;
    MYAPP.calculator.right = 20;
    function sum(){
        return MYAPP.calculator.left + MYAPP.calculator.right;
    }
    console.log(sum());
}())

 

 

위와 같이하는 방법은 자바스크립트에서 로직을 모듈화하는 일반적인 방법입니다.

 

 

 

 

 

유효범위의 대상

 

 

자바스크립트는 함수에 대한 유효범위만을 제공합니다.

많은 언어들이 블록(대체로 {,})에 대한 유효범위를 제공하는 것과는 다릅니다.

 

저도 자바스크립트보다 자바가 더 익숙해서, 가끔 헷갈리곤 합니다,,,

 

 

 

for(var i = 0; i < 1; i++){
    var name = 'test';
}
console.log(name);

 

 

위의 예제를 실행시키면 test 가 출력됩니다.

 

 

 

아래는 자바 코드입니다.

 

 

 

for(int i = 0; i < 10; i++){
    String name = "철보빡";
}
System.out.println(name);

 

 

자바에서는 위 코드는 허용되지 않습니다.

name은 지역변수로 for 문 안에서 선언 되었는데 이를 for문 밖에서 호출하고 있기 때문입니다.

 

 

 

결론적으로, 자바스크립트의 지역변수는 함수에서만 유효합니다.

 

 

 

 

정적 유효범위

 

 

자바스크립트는 함수가 선언된 시점에서의 유효범위를 갖습니다.

이러한 유효범위의 방식을 정적 유효범위(static scoping), 혹은 렉시컬(lexical scoping)이라고 합니다. 

 

 

 

var i = 5;
 
function a(){
    var i = 10;
    b();
}
 
function b(){
    console.log(i);
}
 
a();

 

 

위의 예시의 결과값은 5가 출력됩니다.

 

b 가 사용되는 시점에서의 i 가 아닌, 정의될 때의 시점에서의 i 를 출력하기 때문입니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90
반응형