자바스크립트는 변수나 함수를 선언하면 Hoisting이라는 현상이 일어난다.
자바스크립트는 변수나 함수의 선언부분을 변수의 범위 맨 위로 강제로 끌고가서 가장 먼저 해석한다.
그게 Hoisting이다.
예를 들어보자면
function 함수(){
console.log('hello');
var 이름 = 'Kim';
}
이렇게 함수 내에서 변수를 만들었다고 가정해보자
근데 자바스크립트가 이 코드를 해석하는 순서는 이렇게 된다.
function 함수() {
var 이름;
console.log('hello');
이름 = 'Kim';
}
변수의 선언 부분을 강제로 변수의 범위 맨 위로 끌고가서 해석하고 지나간다.
우리 눈에는 보이진 않지만 자바스크립트는 코드 동작 순서가 이렇다.
이게 Hoisting 현상이다.
함수를 만들어도 똑같고, 변수를 let, const로 만들어도 똑같다.
그럼 이 코드는 실행결과가 어떻게될까?
<script>
console.log(이름);
var 이름 = 'Kim';
console.log(이름);
</script>
콘솔창에 첫째로는 Undefined가 출력되고
둘째로는 Kim이 출력된다. 왜냐하면 Hoisting 때문이다.var 이름; console.log(이름); 이름 = 'Kim'; console.log(이름);
이런 순서로 코드가 실행되기때문
undefined라는건 변수가 선언은 되었는데 값을 아무것도 할당하지 않았을 때 undefined가 출력된다.
일종의 자료형 같은 것인데 정해지지 않은 값이라고 생각하면 된다.
하지만 let, const 변수의 경우 Hoisting이 일어나긴 하는데 약간 이상한 방식으로 일어난다.
변수를 콤마로 구분하면 여러개를 동시에 만들 수 있다.
var 이름, 나이, 성별;
이렇게 하면 변수가 3개 생성된다.var 키워드 3번 쓰지 않아도 되니 코드가 약간 줄어드는 효과를 볼 수 있다.
var 이름 = 'Kim', 나이, 성별;
선언과 동시에 할당도 하고 싶으면 이렇게 작성하면 된다.
그냥 var let const 키워드를 여러번 안써도 된다는 장점이 있다.
변수는 바깥에 있는 변수는 안쪽에서 자유롭게 사용가능하다는 특징이 있다.
이걸 참조 가능하다라고 부른다 자바스크립트에서는 이 현상을 부르는 다른 말이 있다.
closure라고 한다.
안쪽 바깥쪽이 뭔지 예를 들자면
var 나이 = 20;
function 함수(){
console.log(나이)
}
함수();
지금 함수(){} 안쪽에서 바깥쪽에 있는 나이라는 변수를 가져다 쓸 수 있다는 것이다.
함수(){} 안쪽에 나이라는 변수 정의가 있으면 그걸 쓰겠지만
없으면 자연스럽게 바깥에 있는 변수를 가져다 쓴다.(참조한다)
프로그래밍에선 전역변수라는게 있다.
모든 하뭇나 if나 for 내부에서 공통적으로 사용할 수 있는 (참조할 수 있는) 유용한 변수를 뜻한다.
전역변수를 만들어 쓰고싶으면 그냥 script태그 열고 변수하나 만들어주면된다.
<script>
var 나이 = 20;
function 함수(){
console.log(나이)
}
</script>
그럼 밑에 나오는 모든 함수, for, if등에서 전부 나이라는 변수를 사용 가능하다.
근데 전역변수는 이상한 특징이 있다.
전역변수를 만들면 window에도 보관이 된다.(let 말고 var 키워드만 해당)
<script>
var 나이 = 20;
console.log(나이);
console.log(window.나이);
</script>
나이라는 전역변수를 만들면
자동으로 window 오브젝트에 보관이 되었으니까
신기하게 window.나이를 써도 출력이 된다.
(전역함수도 마찬가지로 window에 자동으로 보관된다)
그래서 전역변수를 조금 더 엄격하게 관리하거나 구분짓고 싶으면
전역변수를 만들 때와 사용할 때 window를 활용해보자.
<script>
window.나이 = 20; //전역변수만들기
console.log(window.나이); //전역변수사용하기
window.나이 = 30; //전역변수변경하기
</script>
이런 식으로도 사용할 수 있다.
(node.js 환경에선 window 대체품인 global 이라는 오브젝트가 있다)