- 제목자바스크립트 유효 범위와 var
- 작성일자4 years ago
- 태그자바스크립트
자바스크립트 변수의 유효 범위
자바스크립트에서 변수를 선언할 때 사용하는 키워드로 var
, let
, const
세 가지가 있다. var
는 뒤에 두 개의 키워드와 다른 점이 존재하는데 let
과 const
는 ES6에 이르러 만들어진 표준안이므로 ES6를 지원하는 환경에서만 사용할 수 있다. (IE 같은 환경만 아니면 사용이 가능하다) let
과 const
는 여타 다른 언어와 비슷한 블록 기준으로 범위가 생기는데 var
는 블록 기준으로 범위가 생성되지 않는다.
이제 사용하면 안되는 var
자바스크립트를 이제 배우는 시점에서 var
키워드를 사용해서 변수를 선언하세요. 라고 가르침을 받았다면 나중에 배울 let
과 const
를 사용할 때 혼란스러울 수 있다. 그리고 현재로써 var
를 사용해야할 이유가 전혀 없다.
하지만 오래된 자바스크립트 코드를 수정해야 할 일이 반드시 있을 것이고, 모든 자바스크립트 코드가 표준 스펙이 업데이트 됨에 따라 자동으로 수정이 되지 않기 때문에 반드시 직접 수정해야 할 일이 생길 것이다. 그럴 때 var
의 자세한 특성을 모른다면 코드 수정에 난항이 생길 수 있다.
범위
var
가 가지는 범위는 단 2가지다. 전역적으로 범위를 가지거나 함수에서 범위를 가진다.
var globalScope = 1 // 전역 범위
function helloWorld() {
var functionScope = 1 // 함수 범위
}
한 파일을 기준으로 globalScope
는 전역 범위이므로 어떤 함수 혹은 어떤 블록에서나 호출할 수 있다. 다만 functionScope
변수는 함수 범위에 선언됬으므로 함수 바깥에서 참조하는 것은 불가능하다.
if (true) {
var blockScope = 'block'
}
console.log(blockScope)
// block
var
는 오직 전역/함수 범위만 가지기 때문에 블록 안에 선언됬더라도 블록 외부에서 사용이 가능하다. var
를 let
으로 바꾸면 blockScope
는 정의되지 않았다는 오류가 뜬다.
호이스팅
function helloWorld() {
console.log(fScope)
var fScope = '123456'
}
helloWorld()
// undefined
위 코드는 정상적으로 실행된다. 출력 값은 undefined
이다. 바로 호이스팅이 일어나기 때문이다. var
키워드로 선언된 변수가 범위 내에 존재한다면 그 선언을 범위의 최상단으로 끌어 올린다. 따라서 위 코드와 아래 코드는 같다.
function helloWorld() {
var fScope
console.log(fScope)
fScope = '123456'
}
helloWorld()
// undefined
맨 위 코드를 var
에서 let
으로 바꾸면 호이스팅이 일어나지 않기 때문에 오류가 나게 된다.
부작용
위의 특성들이 괜찮다고 느껴질 수도 있다. 하지만 이러한 특성이 때로는 부작용을 일으킨다. 이러한 부작용들 때문에 let
과 const
가 등장했으므로 그 키워드들을 사용하면 된다.
클로저
함수형 프로그래밍 언어는 함수를 일급 객체로 취급한다. 이런 언어들의 특성 중 클로저라는 특성이 있다.
function WrapClosure() {
let counter = 0
return function () {
counter++
console.log(counter)
}
}
const addCounter = WrapClosure()
addCounter() // 1
addCounter() // 2
WrapClosure
함수는 함수를 반환하는 함수이다. 함수 내부 범위에 선언된 변수 counter
는 블록 범위이기 때문에(내부적으로는 자바스크립트 엔진이 여러 범위를 바인딩) 반환하는 함수 안에서 접근할 수 있다. 반환된 함수는 counter
를 1 증가 시키고 콘솔에 찍는 간단한 함수이다.
이러한 일이 가능하기 까지 매우 많은 내부 절차가 있지만 단순히 중요하게 봐야 될 부분은 반환된 함수를 감싸는 함수(외부 함수)는 호출이 완료되고 실행 컨텍스트에서 반환되고 소멸되지만 클로저(반환된 함수)에서 외부 변수를 참조한다면 그 변수는 유효하다는 부분이다. 즉 외부 함수의 변수 혹은 객체가 내부 함수에서 사용되고 있다면 그 변수와 객체들은 함수의 호출이 끝나도 존재한다는 뜻이다. 클로저가 이러한 환경을 기억하고 있기 때문이다.
클로저는 외부 함수의 환경을 기억하고 있기 때문에 메모리를 사용하는 입장에서는 부담이 될 수 있다.
클로저로 할 수 있는 것
상태를 유지해야 하거나, 정보 은닉이 필요하거나할 때 유용하게 사용할 수 있다.