이제 scope를 복습해볼 시간이다. 어렴풋히 var, let과 const를 쓰면서 scope에 대해 알고는 있었지만 확실하게 개념을 정리하기 위한 포스트이다.

먼저 scope란 자바스크립트에서 어떤 변수에 접근할 수 있는지를 정의한다. 쉽게 말하면 유효범위라는 말이다. 스코프에는 두가지 종류가 있는데, 바로

전역 스코프 (Global Scope) 그리고 지역 스코프 (local scope)이다. local scope에서 바깥 변수/함수를 접근하는 것은
가능하지만, global scope에서 local scope안의 변수/함수를 접근하는 것은 불가능하다. 전역 scope는 최상단의 scope이다. 그리고 scope는 중첩이 가능하다. 그말은 scope안의 scope가 있을 수 있다는 것이다.

검색결과 자바스크립트는 옛날 부터 function scope를 지원해왔고 block scope는 지원하지 않았다.
하지만 ES6부터 block scope를 지원하기 시작했다.

자바스크립트는 기본적으로 함수단위의 scope를 가지고 있었다. var로 변수를 지정하거나 함수선언식으로 선언된 함수는
function scope을 가진다. 하지만 ES6가 도입되며 let 과 const가 더 자주 사용되고 block 단위로 scope을 구분하는게 가능해지면서 var, let 그리고 const의 차이와 또 다양하게 사용하는 방법을 알아야 한다.

let 키워드는 block scope이고 값을 재정의할수는 있지만 재선언을 할수는 없다.

const 키워드도 block scope이고 값을 재정의 할수도, 변수를 재선언도 할 수 없다. 값이 변하지 않는 변수를 정의할 때 사용하는 키워드이다.

var 키워드는 function scope이고 값을 재정의하고 변수도 재선언할 수 있다. 하지만 ES6 이후 자주 사용하지 않는 키워드이다. 함수레벨의 스코프를 가져 혼란을 야기시킬수 있어서이다.

*window는 전역 범위를 커버하는 객체이다. 그러므로 global scope에서 선언된 함수와 var 키워드로 선언된 변수는 window와 연결된다.

함수의 상위 스코프를 결정할 때, 두가지 방법이 있다. 하나는 함수가 어디서 호출되었는지에 따라 상위 스코프를 결정하는 것이고 다른 하나는 함수가 어디서 선언되었는지에 따라 상위스코프를 결정하는 것이다. 첫번 째 방법이 동적 스코프
(dynamic scope)이고 두번 째가 렉시컬 스코프 (lexical scope) 혹은 정적 스코프 (static scope)라고도 한다.
자바스크립트는 lexical scope를 따른다. 그러므로 함수가 어디서 호출되었는지가 아닌 어디서 선언되었는지에 따라 상위
스코프가 결정된다.

스코프를 공부하는 와중에 자바스크립트의 특징 중 하나인 호이스팅을 접하게 되었다.

Hoisting(호이스팅) 이란 단어 뜻으로 봤을 때 끌어 올리다, 들어 올린다라는 뜻인데, 흔히 변수나 함수 선언한 것을 코드문의
가장 위로 올린다는 의미로 이해한다.

MDN에 따르면 개념적으로는 변수나 함수 선언은 컴파일 단계에서 메모리에 저장되지만 위치는 코드에 쓰여있는 곳에
위치한다고 한다.

자바스크립트는 코드를 읽기전에 먼저 코드를 컴파일하는데 우리의 눈에는 하나일 수 있는 구문을 두개로 나눠서 본다.
var a = 3; 이라는 구문이 있으면 자바스크립트는 var a 와 a = 3으로, 선언과 할당 두가지로 나누는데 여기서 이 선언단계를
가장 상위 스코프로 호이스팅 (끌어올리기)한다. var의 경우 function scope이기 때문에 window까지의 호이스팅이 아닌 그
function scope까지만 유효하다.

Example)

function whatisheight() {

console.log("My height is "+height)
var height = 176;
console.log("My height is "+height)

}

//결과:

//My height is undefined

//My height is 176

처음 콘솔 로그는 호이스팅으로 인해 선언한 var height 부분만을 가져왔기에 var height = 176이 아래있더라도 에러가 뜨지 않았다. 하지만 값을 할당해주는 부분은 호이스팅 되지 않았기 때문에 첫번째는 undefined이 뜬것이고 두번째 콘솔 로그에서 값이 할당된 후이기 때문에 176이 나온것이다.

결국 풀어서 코드로 설명하자면 의미이다.

function whatisheight() {

var height;

console.log("My height is "+height)
height = 176;
console.log("My height is "+height)

}

//결과:

//My height is undefined

//My height is 176

또 특이한 점은 자바스크립트가 선언과 할당을 구분해서 보기 때문에 함수 선언문만 호이스팅이 유효하다.
함수 표현식 및 function을 생성하여 함수를 만들면 선언한게 호이스팅 되더라도 함수가 아닌 변수로 인지된다.

호이스팅이 됬을 때 함수선언은 변수선언을 덮어쓰지만

var food; //string

function food() {
console.log("chicken");
}

console.log(typeof food); //function

변수에 값이 할당됬을 경우 변수가 함수선언을 덮는다.

var food = "pizza"; //string

function food() {
console.log("chicken");
}

console.log(typeof food); //string

변수 선언 + 할당 > 함수 선언 > 변수 선언;

이렇게 호이스팅까지 공부했다. 오늘은 여기까지!