자바스크립트에서 Scope 는 식별자를 찾아내기 위한 규칙
스코프의 키워드를 중심으로 예시와 함께 스코프를 이해한다.
모든 변수는 스코프를 갖는다.
모든 변수는 자신이 어디서 선언 되었는지에 따라 다른 특징을 갖는다.
선언 위치가 전역인 변수는 어디서든 참조할 수 있다.
자바스크립트는 함수 레벨 스코프를 따르는데, 함수 레벨(지역) 내부에 선언된 변수는
함수 내부 에서만 유효하다.
즉, 변수가 선언된 위치가 함수 내부인지 외부인지에 따라 그 변수의 유효범위를 알 수 있는 것이다.
var test = "out"
function scopeTest(){
var test = "in"
console.log(test) // "in"
}
scopeTest()
console.log(test) // "out"
위와 같은 예시에서 변수를 참조할때 스코프의 중요성을 확인할 수 있는데,
블록 레벨 스코프는 중괄호({})로 코드 블록의 내부에서 외부를 참조 할 수 없다는 것을 의미한다.
즉, 함수 내부에서 선언된 변수를 외부에서 참조할 수 없듯이 let, const 로 블록 내부에 변수를 선언하면 블록 외부에서 그 변수를 참조할 수 없다.
{
var v = "var"
}
console.log(v)
// "var"
{
let l = "let"
}
console.log(l)
// ReferenceError: l is not defined
함수를 호출하더라도 선언 되어있던 곳으로 돌아가 함수의 스코프를 따르는 것인데 다음 예제를 살펴보면,
이해하기 쉬울 것 이다.
let test = 'out'
function outFunc() {
let test = 'in'
inFunc()
}
function inFunc() {
console.log(test)
}
outFunc() // "out"
inFunc() // "out"
왜 이런결과가 나온 것일까?
outFunc()로 "out"이라는 로그가 찍힌 것은 outFunc를 통해 inFunc를 호출한다.
하지만, 문제는 inFunc가 호출되는 위치와 상관없이 inFunc이 선언되었을 때의 스코프를 확인해야 한다.
inFunc이 선언 되었을 때에는 test는 "out"이라는 전역 변수로 할당되어 있기 때문에
호출 지점이아닌 선언 지점의 스코프를 따르는 렉시컬 스코프의 영향을 받은 것이다.
let test = 'out'
function outFunc() {
test = 'in' // <- 변경 !
inFunc()
}
function inFunc() {
console.log(test)
}
inFunc() // "out"
outFunc() // "in"
inFunc() // "in"
바로 위의 예제와 비슷해 보이지만, outFunc 과 다음에 호출된 inFunc 에서는
"out"이 아닌 "in"이 찍히는 것을 확인할 수 있다.
이러한 이유는?
outFunc에 키워드 없이 선언한 test 는 전역 객체의 속성을 변경시키기 때문이다.
하지만 이렇다고 해서 렉시컬 스코프가 발생하지 않은 것은 아니다.
스코프 체인은 실행 컨텍스트에 대한 개념이 필요하기 때문에 실행 컨텍스트 포스팅에서 확인 한다.
👈 스코프체인