스코프란?
- 식별자가 유효한 범위
- 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효 범위가 결정됨.
스코프 내에서 식별자는 유일해야 하지만 다른 스코프에는 동명의 식별자를 쓸 수 있다.
- 단, var는 스코프 내의 동일한 식별자를 허용하는데, 이는 의도치 않은 재할당의 부작용이 있다. let, const는 같은 스코프 내의 중복선언을 허용하지 않는다.
1 | var x = "global"; |
var는 스코프 내에서 중복선언을 허용하기 때문에 foo라는 함수의 스코프 내에서 var x를 중복선언한 경우 x = ‘local2’로 재할당된 것과 같은 효과가 발생한다. 따라서 의도치 않게 var x의 값이 변경된다. 또한 var는 함수 레벨 스코프를 가지기 때문에 foo 함수 내에서 선언된 변수는 함수 내에서만 유효하다. 따라서 함수 외부에서 console.log(x)를 하면 전역에 선언된 var x의 값인 global이 출력된다.
하지만 let은 같은 스코프 내에 중복 선언을 허용하지 않기 때문에 console.log(y)를 하면 에러가 발생한다. 또한 let은 블록 스코프 레벨을 가지기 때문에 전역에 선언된 변수를 참조할 수 없다.
전역스코프 vs 지역스코프
전역스코프: 코드 가장 바깥 영역. 어디에서나(함수 내부 포함) 참조가능
지역스코프: 함수 몸체 내부. 자신이 선언된 지역과 하위지역에서만 참조가능. 지역변수를 전역에서 참조하면 에러가 발생한다.
전역 스코프 <- outer 함수 <-inner 함수
1 | var x = "global x"; |
블록 레벨 스코프 vs 함수 레벨 스코프
- 블록 레벨 스코프: 모든 코드 블록(함수, if문, for문 등)을 지역 스코프로 인정한다.
- 함수 레벨 스코프: 함수의 코드 블록만 지역 스코프로 인정한다. 함수에 의해서만 지역스코프가 생성된다.
단, var로 선언된 변수는 코드 블록 내에 선언되었더라도 지역변수가 아닌 전역변수이다.
1 | var x = "global x"; |
1 | var x = "global x"; |
렉시컬 스코프
함수는 어디서 호출
했는지 혹은 어디서 정의
되었는지에 따라 상위 스코프를 결정하는데 전자를 동적스코프, 후자를 정적 스코프라고 말한다. 자바스크립트는 정적 스코프를 따르고 이를 렉시컬 스코프라 부르기도 한다.
1 | var x = 1; |