스코프란 현재 실행되고있는 컨택스트를 말합니다.
쉽게 말해 현재 실행되고 있는 함수가 가지고 있는 범위를 뜻합니다.
(사실 이게 사이트마다 사람마다 하는 말이 다 달라서 뭐라고 말을 해야할지 참 애매합니다. 그래서 전 이렇게 설명했습니다.😅)
그리고 자바스크립트에서 스코프를 구분하면 크게 2가지로 나룰 수 있습니다.
전역 스코프 (Global scope)
코드 어디에서든지 참조할 수 있다.
지역 스코프 (Local scope or Function-level scope)
함수 코드 블록이 만든 스코프로 함수 자신과 하위 함수에서만 참조할 수 있다.
var x = 'global';
function foo() {
var x = 'function';
console.log(x);
}
function foo2() {
console.log(x);
}
foo();//'function'
foo2()//'global'
console.log(x);//'global'
변수 x가 총 2개가 있지만 foo는 자신의 블록 스코프에 있는 'function'을
foo2는 전역 스코프에 있는 'global'을
console.log(x)는 전역 스코프에 있는 'global'을 호출 하였습니다.
전역에 선언된 변수 x는 어디에든 참조할 수 있습니다. 하지만 함수 foo 내에서 선언된 변수 x는 함수 foo 내부에서만 참조할 수 있고 함수 외부에서는 참조할 수 없습니다.
하지만 foo2에서는 자신의 스코프에 x가 없기때문에 부모 영역으로 나아가서 참조값을 찾았습니다.
즉 변수를 참조하는 '식별자'는 자신이 어디에서 선언됐는지에 의해 자신에게 유효한 범위를
찾습니다. 자바스크립트가 이러한 복잡한 범위를 지정하는 이유는 식별자 이름의 충돌을 막고 구별을 하기 위함입니다.
타 언어들은 블록 레벨 스코프(block-level scope)를 따릅니다. 블록 레벨 스코프란 코드 블록({})내에서 유효한 스코프를 의미한다.
하지만 자바스크립트는 함수 레벨 스코프(function-level scope)를 따릅니다. 함수 레벨 스코프란 함수 코드 블록 내에서 선언된 변수는 함수 코드 블록 내에서만 유효하고 함수 외부에서는 참조할 수 없다는 뜻입니다. if, for, while등 다른 블록에서 선언된 변수는 자동으로 전역 변수로 참조됩니다.
ECMAScript 6추가된 let, const를 사용하면 블록 레벨 스코프를 사용할 수 있습니다!
ECMAScript는 var의 사용을 자제하고 let, const를 사용하길 권장하고 있습니다.
var x = 1;
var y = 15;
function foo() {
var y = 10;
function foo2(){
console.log(y);
}
foo2();
console.log(x);
}
if(true){
var z = 3;
}
foo();//10, 1
console.log(z);//3
console.log(y);//error
위에서 말했듯이 자바스크립트는 함수 레벨 스코프를 따르지만 ECMAScript 6에 추가된 let, const를 사용하면 블록 스코프를 사용할 수 있습니다.
const x = 1;
let y = 15;
function foo() {
let y = 10;
function foo2(){
console.log(y);
}
foo2();
console.log(x);
}
if(true){
let z = 3;
}
foo();//10, 1
console.log(z);//error
console.log(y);//15
위와 똑같은 예제이지만 let과 const는 블록 스코프 규칙을 따르기 때문에 if 블록에 선언된 z는 var과 다르게 전역변수로 선언되지않고 지역변수로만 선언되었습니다.
let name = 'kim';
function func01() {
console.log(name);
}
function func02() {
let name = 'lee';
func01();
}
func02();//name
처음에는 'func02에서 name을 lee로 재할당했으니 console.log(name)은 lee겠군'이라는 생각을 하셨을겁니다. 하지만
이것을 렉시컬 스코핑(lexical scoping)이라고 합니다.
함수를 처음 선언하는 순간, 함수 내부의 변수는 자기 스코프로부터 가장 가까운 곳에 있는 변수를 계속 참조하게 됩니다. func01이 선언되었을때 가장 가까운 변수 name의 값은 글로벌 스코프에있는 kim이 됩니다. 그래서 func02에서 lee로 재할당하여도 func01에서 참조하는 값은 변하지 않았습니다.