자바스크립트에서 변수, 함수를 선언할 때, 해당 변수 또는 함수가 아무데서나 유효한 것이 아니다. 어떻게, 어디에 선언되었는지에 따라 유효한 범위가 있는데 이를 Scope 라고 한다.
자바스크립트에서는 var, let, const 이렇게 세가지의 키워드가 있다. 각각 다른 특징을 가지고 있다.
변수를 어떤 키워드로 선언하느냐에 따라서 다른 유효범위를 가진다.
전역에 선언된 전역변수는 전역 스코프를 가지기 때문에 하위의 모든 곳에서 참조가 가능하다.
지역(블록,함수)에 선언된 지역변수는 지역스코프를 가져 해당 지역과 하위의 지역에서 참조가 가능하다.
let foo = 123; // 전역 변수
let foo2 = 1 //전역 변수
function a() {
let variable = 1; //지역변수
}
cosole.log(variable) // ReferenceError: variable is not defined
{
let foo = 456; // 지역 변수
let bar = 456; // 지역 변수
foo2 = foo + 1 //전역변수 참조, foo2는 457이 됨.
}
console.log(foo); // 123(젼역변수 foo)
console.log(bar); // ReferenceError: bar is not defined
console.log(foo2) // 457
블록 스코프이기 때문에 중괄호(코드블록) 밖에서는 사용이 불가능하다.
함수안, 블록 안에 선언된 변수 모두 지역변수가 된다.
또한 foo2는 블록 안에서 정의되지 않았으므로 전역 스코프에서 해당 변수를 검색하여 사용해 1+456 즉 457이 된다.
해당 스코프에서 정보를 찾지 못하고 이렇게 바깥 스코프에서 변수를 검색하는 것이 스코프 체인이다.
function a() {
var variable = 1; // 지역변수
}
console.log(variable) // ReferenceError: variable is not defined
if (true) {
var variable = 1; // 전역변수
}
console.log(variable) // 1
함수 내에서 선언된 변수 variable
는 function a
의 지역변수 이기 때문에, 해당 함수 밖에서 사용할 수 없다.
하지만 블록스코프는 무시하기 때문에 블록에서 선언되었더라도 블록 밖에서 사용이 가능하다.
var value = 'hello!';
function myFunction() {
var value = 'bye!';
if (true) {
var value = 'world';
console.log('block scope: ');
console.log(value);
}
console.log('function scope: ');
console.log(value);
}
myFunction();
console.log('global scope: ');
console.log(value);
var는 function scope이기 때문에, if문 블록 스코프를 무시하고 블록 밖의 valuer값에도 영향을 준다. 그러므로
다음과 같은 결과가 나온다. 그리고 마지막 value는 전역변수 value인 hello가 나온다.
만약 var가 아닌 let,const 였다면 블록 스코프이기 때문에 world, bye, hello가 나왔을 것이다.
만약 if 문이 아닌 아래와 같이 함수일 경우
var value = 'hello!';
function myFunction() {
var value = 'bye!';
function a() {
var value = 'world';
console.log('block scope: ');
console.log(value);
}
a()
console.log('function scope: ');
console.log(value);
}
myFunction();
console.log('global scope: ');
console.log(value);
위와같이 함수 내에서 밖의 value에 영향을 미치지 않아 bye가 출력된다.
아까도 특징과 예시에서 봤듯이 스코프는 안쪽(하위) 스코프에서 바깥쪽 (상위)스코프로만 접근할 수 있다. 이때 상위 스코프를 결정하는 방법으로 두가지가 있다.
이 중에서 자바스크립트는 렉시컬 스코프를 따른다. 즉 함수를 선언한 시점에 상위 스코프가 결정된다는 말이다.
그러므로 가지는 두가지의 특징이 있다.
var x = 1;
function foo() {
var x = 10;
bar();
}
function bar() {
console.log(x);
}
foo(); // 1
bar(); // 1
위와같이 하수 bar는 전역에 선언되었다. 그러므로 함수 bar의 상위 스코프는 전역 스코프 이며 모두 1이 출력된다.