이 글에서, 우리는 자바스크립트 변수의 범위(scope)와 호이스팅(hoisting), 그리고 이 두가지의 특징에 관해 배워보겠습니다.
자바스크립트의 변수범위와 호이스팅이 작동하는 원리를 이해하는것은 필수적입니다. 이 두가지 컨셉은 직관적이면서도 이해하기가 쉽지 않습니다. 거기에는 미묘한 차이가 있으며, 자바스크립트 프로젝트에서 성공하기 위해서는 반드시 이해해야 합니다.
변수 범위 (Variable Scope)
변수 범위는 변수가 존재하는 컨텍스트입니다. 이것은 어디에서 변수에 접근할 수 있는지, 그 컨텍스트에서 변수에 접근할 수 있는지를 명시적으로 나타납니다.
변수는 지역 범위(local scope)와 전역 범위(global scope) 둘 중 하나를 가집니다.
지역 변수 (함수 수준 범위)
대부분의 프로그래밍 언어와 달리, 자바스크립트는 블럭-수준(block-level)의 범위를 가지고 있지 않습니다. 대신, 자바스크립트는 함수-수준(function-level)의 범위를 가집니다. 함수내에 정의된 변수는 지역 범위를 가지며, 해당 함수와 내부 함수에서만 접근이 가능합니다. 내부 함수에서 외부 함수의 변수 접근에 관한 더 자세한 내용은 클로저(Closure)를 설명한 글을 참조하시기 바랍니다.
함수-수준 범위의 예제
|
|
잘못된 예제. (블럭-수준 범위로 오해할 경우)
|
|
지역변수를 선언하지 않는다면 문제를 일으킬 가능성이 높아집니다.
항상 지역변수를 사용하기 이전에 선언하도록 하십시오. JSHint를 사용하면 코드의 문법 오류나 스타일을 체크할 수 있습니다. 다음은 지역변수를 선언하지 않음으로 인해 문제가 발생한 경우입니다.
|
|
지역번수는 함수내에서 전역번수보다 높은 우선순위를 가집니다.
만약, 같은 이름의 전역변수와 지역변수가 존재할 경우 이 변수를 함수내에서 사용한다면, 지역변수가 우선권을 갖게 됩니다.
|
|
전역 변수
함수의 외부에서 선언된 모든 변수는 전역 범위(global scope)를 가집니다. 브라우저에서, 전역 컨텍스트(또는 scope)는 window 객체를 가리킵니다.
그러므로, 전역변수는 전체 어플리케이션에서 사용이 가능합니다.
|
|
모든, 전역 변수는 window객체와 연결됩니다. 그러므로, 아래와 같이 window객체를 통해 모든 전역 변수에 접근이 가능합니다.
|
|
만약, 변수가 최초 선언 없이(var 키워드를 사용하여) 초기화 되었다면, 이 변수는 자동으로 전역 컨텍스트에 추가됩니다:
|
|
아래의 firtName은 둘다 전역 범위입니다. 두번째, firstName은 {} 블럭으로 쌓여있지만, 자바 스크립트는 블럭단위 범위를 지원하지 않는다는 것을 기억하기 바랍니다.
|
|
다른 예제:
|
|
setTimeout 변수는 전역 범위에서 실행됩니다.
setTimeout 안에서 선언된 모든 함수는 전역 범위에서 실행됩니다. 다음 예제를 주의해서 보십시오.
|
|
전역 범위를 오염시키지 마십시오
자바스크립트 전문가가 되려면, 가급적 전역 범위에 변수를 생성하는것을 피하도록 해야 합니다.
|
|
다음은, 개선된 코드로서 전역범위를 덜 오염시킵니다.
|
|
위의, 예제에서 fullName() 함수 역시 전역 범위에 있습니다.
변수 호이스팅(Variable Hoisting)
모든 변수선언은 호이스트 됩니다. 호이스트란, 변수의 정의가 그 범위에 따라 선언과 할당으로 분리되는 것을 의미합니다. 즉, 변수가 함수내에서 정의되었을 경우 선언이 함수의 최상위로, 함수 바깥에서 정의되었을 경우는 전역 컨텍스트의 최상위로 변경됩니다.
변수의 선언이 초기화나 할당시에 발생하는것이 아니라, 최상위로 호이스트 된다는 것을 명심해야 합니다. 다음 코드를 주목하십시오.
|
|
이 코드는 자바스크립트 엔진에 의해 다음과 같이 해석됩니다.
|
|
호이스트 되었을때, 함수 선언은 변수선언을 덮어 씁니다.
|
|
하지만, 변수에 값이 할당될 경우에는 반대로 변수가 함수선언을 덮어 씁니다.
|
|
“strict mode”에서 최초의 선언없이 변수에 값을 할당하려 한다면 오류가 발생합니다. 변수에 값을 할당 하려 할때는 항상 미리 선언하는 습관을 들이는것이 좋습니다.
이 글은 javascriptissexy.com의 허락을 받아 번역 하였습니다. 상업적인 목적이 아니라면 얼마든지 퍼가셔도 좋습니다. 단, 원문과 번역의 차이가 다소 있을 수 있으므로 번역글과 함께 아래 원문 사이트 주소도 항상 첨부해 주시기 바랍니다. 그외 오역이나 개선될 문장이 있다면 트위터 멘션이나 댓글, 이메일등 어떤 경로로든 알려주시면 바로 잡도록 하겠습니다.
'WEB > Javascript' 카테고리의 다른 글
레이어 팝업 중앙 띄우기 (0) | 2017.02.17 |
---|---|
Callback Function 콜백함수 (0) | 2017.01.06 |
변수의 Scope (0) | 2017.01.04 |
Closure 클로저 (0) | 2017.01.03 |
모바일/웹 분기 처리 script (0) | 2016.12.13 |