varFunction-Level Scope를 가지고, letconstBlock-Level Scope를 가진다.

Function Scope부터 하나씩 살펴보자.

Function Scope

function scope 란 함수에서 선언된 변수는 내부에서만 유효하고, 외부에서는 참조할 수 없다는 의미이다.

function test() {
    var a = 1;
    if(true) {
        var b = 2;
        if(true) {
            var c = 3;
        }
    }

		b = 2;

    console.log(a, b, c);
}

test();
console.log(a, b, c);

위와 같이, test() 함수를 호출한 결과는 무엇일까? 정답은 1 2 3 과 마지막 console.log() 함수는 a, b, c 변수를 참조하지 못한다.

그 이유는 a, b, ctest() 함수 내부에서 유효한 동일한 scope를 가지고 있기 때문이다. 그리고 함수 밖인 전역 스코프에서는 a, b, c 변수가 없으므로 접근할 수 없는 것이다.

여기서 한가지 더 짚고 넘어갈게 있다. 렉시컬 스코프이다.

렉시컬 스코프

렉시컬 스코프는 함수의 실행 환경이 아닌 함수를 정의한 환경으로 참조하는 특징을 가지고 있다. 말이 어려우므로 예제를 통해서 살펴보자.

var a = 0;

function first() {
    var a = 1;
		second();
}

function second() {
	 console.log(a); // 1
}

first();

예상을 해보면, 우선 second() 함수가 호출될 시점에 상위 스코프인 first() 함수 스코프를 참조해 '1'을 출력할 것이라고 생각할 수 있다. 하지만, 자바스크립트는 렉시컬 스코프의 정의에 따라 함수 호출 시점이 아닌 함수를 선언한 위치에 따라 상위 스코프가 결정된다. 따라서 second() 함수는 전역 스코프에서 선언이 되었고 상위 스코프는 전역 스코프가 되어 '0'이 출력된다.

그럼 아래 코드는 어떻게 출력이 될 지 짐작이 될 것이다.

var a = 0;

function first() {
    var a = 1;
		var second = function() {
	    console.log(a);
		}
    second();
}

first();

second 함수는 first() 함수 내부에 선언되어 상위 스코프는 first() 함수 스코프이고 '1'을 출력할 것이다.

var 키워드 생략된 경우

뜬금없지만, 만약 var 를 선언하지 않는다면 어떻게 될까?

해당 변수는 전역 스코프에 선언이 된다.

function first() {
    var second = function () {
        a = 1;

    }
    second();
}

first();
console.log(a);