JS/Javascript

[JS] 자바스크립트 스코프 ? : 변수의 유효 범위

emayom 2021. 7. 29. 23:07

자바스크립트는 다른 프로그래밍 언어와는 다르게 

전통적으로 함수 레벨 스코프를 지원하였고, 블록 스코프는 지원하지 않았다.

ES6 이후부터 let, const가 등장하면서 블록 레벨의 스코프를 지원하기 시작했다.

 

유효 범위 (Scope ) ?

 

프로그램이 커질 수록,

선언된 변수가 많아질수록 여러가지 이유로 충돌이 발생할 수 있다.

 

이때 변수 사이의 충돌을 방지할 수 있도록 암시적으로 구분해놓은 것을 유효 범위라고 한다.

즉, 해당 변수를 사용할 수 있는 범위를 유효범위라고 한다!

 

변수는 선언 위치에 따라 변수를 참조할 수 있는 범위가 달라진다.

전역 변수 (global variable)
통상적으로 프로그램의 내부 (함수 내부, 외부) 어디서든 사용할 수 있는 변수를 의미한다.

지역 변수 (local variable)
통상적으로 코드 블록 내부에서만 사용할 수 있는 변수를 의미한다.

 

변수의 우선 순위

 

var의 경우 같은 이름의 중복된 전역 변수 선언이 가능하다.

 

이때 변수를 호출할 경우,

마지막에 선언된 변수가 우선 순위가 높다.

var x = "first var";
var x = "second var";

console.log(x); //"second var"

 

만약 함수 내부와 외부에 선언된 변수의 이름이 같고,

함수 내부에서 호출할 경우 자기 자신과 가까운 지역 변수의 우선 순위가 높다.

let x = "global";

function func() {
    let x = "local";
    console.log(x);
}

func(); // "local"

 

 

var

 let, const 이전부터 존재하던 var는 함수 레벨 스코프이다.

즉, 함수 내부에서 var를 이용하여 선언한 변수는 함수 내부 전체에서 유효한 식별자가 된다.

 

함수 레벨 스코프(Function-level Scope)
함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없다.
즉, 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수이다.

 

아래에 스코프를 체크할 수 있는 함수를 정의하였다.

함수 내부의 조건문에서 var를 선언하고 조건문의 외부에서 호출했다.

 

var가 함수 레벨 스코프라면 function-level scope가 출력이 될 것이고,

블록 레벨 스코프라면 레퍼런스 에러가 발생할 것이다!

function scopeCheck() {
    if(true){
    	var var_check = "function-level scope";
    }
    console.log(var_check);
}

 

결과는 function-level scope라고 잘 출력되는 것을 확인할 수 있다.

결론적으로 var_check는 함수 레벨 스코프로 함수 내부에서 선언된 지역변수이다.

 

+)

함수 외부에서 선언된 전역 변수 var는 함수 내부 / 외부 어디서든 호출이 가능하다.

 

하지만 아래와 같이 함수 내부에서 선언된 지역변수 var를 

함수 외부에서 호출하게되면 레퍼런스 에러를 내는 것을 확인할 수 있다.

 

var global = "global";

function checkScope() {
    if(true) {
        var local = "local";
    } 
    console.log(global);
}

checkScope();
console.log(local);

 

 

let

let은 블록 레벨 스코프이다.

즉, {} 블록 내부에서만 유효한 식별자가 된다.

 

블록 레벨 스코프(Block-level Scope)
모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등) 내에서 선언된 변수는
코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없다.
즉, 코드 블록 내부에서 선언한 변수는 지역 변수이다.

 

같은 코드를 let으로 변경하여 실행해보자!

조건문 코드 블록 내부에 선언된 let_check를 

조건문 외부에서 호출했다.

 

아까와 마찬가지로

let_check가 블록 레벨 스코프라면 레퍼런스 에러가 날 것이고,

함수 레벨 스코프라면 정상적으로 출력될 것이다.

function scopeCheck() {
    if(true){
    	let let_check = "block-level scope";
    }
    console.log(let_check);
}

 

결과는 Reference Error가 출력되는 것을 확인해 볼 수 있다.

결론적으로 let_check는 블록 레벨 스코프의 지역변수로 선언된 코드 블록 외부에서는 참조할 수 없다.

 


⚠️ 아래 내용은 모두 개인적인 참고 / 기록을 위한 용도입니다. 참고해주시고 편안하게 봐주세요 :)  ⚠️

***    혹시라도 잘못된 정보가 있다면  언제든지 알려주시면 감사하겠습니다  !    ***