리액트(React) 학습에 필요한 사전지식
var, let, const 차이점 - #2 Hoisting, 적용범위
Hoisting
먼저 hoisting의 동사격이 되는 hoist의 사전적 의미는 이렇습니다.
to lift something heavy, sometimes using ropes or a machine
- Cambridge Dictionary
hoist는 "줄과 기계를 이용해 무거운 것을 들어 올린다."는 뜻을 가지고 있습니다. 구글에 hoist라고 검색하면 특정 장비 사진이 나옵니다. 그 장비로 hoist 단어의 이미지를 생각하시면 될 것 같습니다.
hoist는 이렇듯 "무언가를 들어 올리다."라는 뜻을 가지고 있습니다. 그렇다면 hoist는 우리가 코딩한 무언가를 올린다는 건데, 도대체 무엇을 들어올리는 걸까요? 예시를 통해 설명하겠습니다.
var의 hoisting
function getFoo(){...}로 함수 '선언'을 했고, getFoo()로 함수를 실행하도록 작성했습니다. 선언한 함수 function getFoo(){...}를 볼까요? 함수 첫줄에 foo라는 변수를 콘솔에 변수값이 나오도록 작성했습니다. 하지만 변수를 먼저 설정하지 않고 콘솔로그를 찍어서 "foo라는 변수를 정의하지 않았습니다." 라는 에러메세지가 나올 것 같지만, 에러는 발생하지 않았습니다. 보통 다른 언어는 에러메세지가 뜨는데... 이상하지 않나요?
자바스크립트에서 var는 변수에 값을 넣는 것, 즉 '할당'하는 것과 동시에 '선언'이 됩니다. 코딩에서 '할당'은 값을 넣어주는 것이고, '선언'은 생성 및 생성한 내용이라 할 수 있겠습니다.
자바스크립트는 엔진 구동시 '선언'문을 최우선적으로 해석합니다. 그리고 '할당' 구문은 런타임(Run Time, 실행) 과정에서 이루어집니다. 그렇단 얘기는 getFoo()함수 내에서 var foo = 100; 라고 선언과 할당을 동시에 했지만, 여기에서 '선언'만 함수 내 최우선적으로 해석한다는 겁니다. 이 내용을 다시 hoisting으로 적용하자면, var로 '선언+할당'구문을 동시에 작성해도 '선언'만 자바스크립트가 집어서 최상단으로 끌어 올려 먼저 해석(hoisting)한다는 겁니다. 작동 순서에 맞게 코드를 재구성하면 이렇습니다.
var의 hoisting 재구성
그렇다면 let과 const는 과연 어떨까요?
let의 hoisting 도전(?)
const의 hosting 도전(?)
결과는 대실패. let, const는 선언+할당이 동시에 되지 않아 hosting이 적용되지 않는다는 걸 확인했습니다. 그렇다면 let과 const는 선언+할당을 따로 하면 잘 될까요?
let의 선언문 분리
와 분리해도 안되네요. 레퍼런스에러, 즉 'foo'가 정의되지 않아 발생한 에러입니다. let은 선언문을 분리해도 최상단으로 hosting되지 않습니다. 변수를 (직접 작성하여) 먼저 선언하고, 그 이후에 변수를 사용해야 합니다. 그래야 에러가 발생하지 않고 작동합니다. const도 동일할까요? 미리 말씀드리자면 const는 선언+할당을 동시에 해야 합니다. 따로 해주게 되면 "Uncaught SyntaxError: Missing initializer in const declaration." 라고 에러메세지가 뜹니다.
const 정의
let을 결국 최상단으로
변수를 생성할 때 var만 hoisting이 적용되는 걸 확인했습니다. 그렇다면 함수의 경우는 어떨까요? 함수도 '선언'을 하는데 말이죠.
함수선언 hoisting
함수 선언부를 함수 실행구문 이후에 배치했는데도 잘 실행이 됩니다. 즉, 함수 선언부는 위치에 상관없이 해당 전체 코딩의 최상단부로 hoisting 됩니다. 그렇다면 함수 선언부를 변수에 할당하는 건 hoisting이 될까요?
var bar = function getFoo(){ 에서 var bar 선언부만 hosting되고 나머지는 작동하지 않는다는 걸 알 수 있습니다.
적용범위 - Scope
미리 얘기하자면 var는 함수범위(function-scoped)이고, let과 const는 블록범위(block-scoped)입니다.
var의 적용범위
var를 let과 const로 바꿔볼까요?
let과 const는 함수범위가 아니라 block범위이기 때문에 적용이 되지 않습니다. block은 '{' 과 '}'로 이루어진 중괄호 내부를 의미합니다. 위 예시에서 foobar를 정의한 block과 foobar를 불러오는 block이 다릅니다. let과 const는 이렇듯 블록범위이기 때문에 var와는 다르게 함수적용이 되지 않습니다. 다른 예시를 들어볼게요.
같은 블록 안에서 let과 const를 정의하고 불러오면 문제가 없이 잘 실행 됩니다. 하지만 해당 블록 밖에서 불러오면 "not defined"라고 에러가 발생합니다. 이것이 var, let, const의 범위입니다.
함수, 블록을 떠나서 전역으로 var, let, const를 설정할 수 있습니다. 위 예시를 보면 전역으로 var, let, const를 선언과 동시에 할당을 했습니다. 제가 위에서 "let은 hoisting이 적용되지 않는다."라고 적었습니다. 하지만 block범위에서는 선언+할당이 동시에 되어 hoisting이 적용됩니다. 위에서 let이 hoisting이 적용되지 않은 건 함수범위 내에서 시도하였기 때문입니다. 그럼 전역범위에서는 var, let const가 모두 hoisting이 되는지 확인해볼까요.
전역범위에서도 역시 const는 선언이 분리가 되지 않는다는 걸 확인했습니다.
정리
1. 자바스크립트 엔진은 '선언'을 최우선적으로 해석.
2. hoisting은 var, let, const 선언부를, 함수에서도 선언부를 먼저 해석하는 것. '선언+할당'이 적용되는 경우, '선언'부를 자동으로 hoisting함.
3. var는 전역범위, 함수범위에서는 선언+할당 가능. let은 전역범위, 블록범위 내에서 선언+할당 가능. 함수범위에서는 불가. const는 어떤 범위에서든 선언+할당만 해야 함.
'[ Programming ] Basic > React' 카테고리의 다른 글
리액트(React) JSX (0) | 2020.02.05 |
---|---|
리액트 함수형 컴포넌트 (React Functional Components) (0) | 2020.02.04 |
[리액트(React) 학습자를 위한 기초지식] 템플릿 리터럴, 구조분해 할당 (2) | 2020.02.03 |
[리액트(React) 학습자를 위한 기초지식] var, let, const 차이점 - #1 재선언, 재할당 (0) | 2020.02.01 |
리액트(React) 학습자를 위한 기초지식 - ECMAScript (0) | 2020.01.31 |
댓글