관리 메뉴

FU11M00N

[ JavaScript ] JS 지역변수와 전역변수의 유효범위 , 정적 유효 범위 본문

SUA 정보보안/JavaScript

[ JavaScript ] JS 지역변수와 전역변수의 유효범위 , 정적 유효 범위

호IT 2021. 2. 4. 00:32

이미지 출처 :        https://www.inflearn.com/course/javascript-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B0%95%EC%A2%8C#

 

생활코딩의 이고잉 님의 강의를 기반으로 개인 공부용으로 정리한 포스팅입니다.

 

 

 

 


 

- 전역변수

 

 

 

유효범위(Scope)는 변수의 수명을 의미하고있습니다.

 

 

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

 

 

 

 

 

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

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

 

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

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

 

아래 예제를 보자. 결과는 '함수안 local'과 '함수밖 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이 출력됩니다.

 

함수 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 에게 영향을 미치지 않습니다.

 

 

 

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

 

 

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

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

 

 

또한 전역변수를 가급적 사용하지않는것이 좋습니다.

 

여러가지 이유로 그 값이 변경될 수 있습니다.

 

 

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

 

함수의 동작도 달라지게 되겠죠. 

 

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

 

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

 

 

 

 

- 전역변수의 사용

 

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

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

 

 

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 를 출력하기 때문입니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SUA 정보보안 멘토링에 참여하고 있습니다.

 

Comments