analogcoding

Scope [global , local] / Hoisting 본문

Study JS for me/Keyword

Scope [global , local] / Hoisting

be well 2019. 4. 23. 18:27


Scope 

변수와 그 값이 어디서부터 어디까지 유효한지 판단하는 범위.

scope는 변수 접근 규칙에 따른 유효범위를 의미한다.

javascript에서 함수가 선언되는 동시에 자신만의 scope를 가진다.

 

+ var 와 let, const는 변수가 적용되는 범위가 다르다.
  var의 경우 function scope(함수범위) 를 가지고

  let과 const의 경우에는 block scope(블록범위)를 가진다.

 

  재할당 재선언
var 가능 가능
let 가능 불가능
const 불가능 불가능

 


Global scope (전역 스코프)

함수 외부에서 선언된 모든 변수는 전역 스코프이다.

전역 스코프를 대표하는 객체는 최상위 객체 window.
모든 전역변수는 window 객체와 연결된다.

코드 어디에서든 참조할 수 있다.

var myAge = 25
window.myAge // 25

하지만 let 이나 const의 경우 window 객체와 연결되지 않는다.

let myAge = 25
window.myAge // undefined
const yourAge = 25
window.yourAge // undefined

 

전역변수를 코드 어디에서든 참조할 수 있는 지 살펴보자.

var myAge = 25

function howOldRU(){
return myAge;
}

howOldRU() // 25

 

***선언 없이 초기화된 변수는 전역 변수로 받아드리지만 버그 발생의 우려가 있음으로 쓰지 않는 것이 좋다.


Local scope (지역 스코프)

함수 레벨 스코프(Function-Level scope)를 따라서

함수 블록이 만든 스코프로 함수 자신과 자신의 하위 함수에서만 참조할 수 있다.

function name(){
var myName = "Hyunseo"
  return myName;
}

name() // "Hyunseo"

cosole.log(myName) // Uncaught ReferenceError: myName is not defined
    

유효범위

Lexical (static) scope : 유효범위는 코드를 작성될 때 결정된다.

var global = 1; // global 을 전역에 1로 선언.

function local() {
  var global = 10; // local() 안에서 global 에 10을 대입.
  what();          // what()을 실행.      
}

function what() {
  console.log(global); // what()은 전역의 gliobal을 바라보고 있음.
}

local(); // 1
what();  // 1

Hoisting (호이스팅)

변수는 범위에 따라 선언할당으로 분리된다.

javascript 내부적으로 변수 선언을 scope의 상단으로 끌어올리는 것을 Hoisting이라고 한다.

function hoisting(){
  cosole.log(hoist);
  var hoist = "Yes"
  cosole.log(hoist);
}
  
  hoisting() // undefined
             // "Yes"

이 코드는 Hoisting으로 인해 아래와 같은 방식으로 해석된다.

function hoisting(){
  var hoist;             // 선언은 되어있지만 할당값이 없음.
  console.log(hoist);    // hoist = undefined
  hoist = "Yes"          // 값이 할당됨 현재 상태 hoist = "Yes"
  console.log(hoist);
}

hoisting() // undefined
           // "Yes"

+

Hoisting은 함수 선언식의 경우 항상 상단으로 Hoisting 하고 
                 함수 표현식의 경우 할당된 변수만 상단으로 Hoisting 한다.

 

함수 선언식

hoisting(); // 함수 선언식!

function foo() {
 console.log('함수 선언식')
}

함수 표현식

hoisting();// typeError

var foo = function(){
 console.log('함수 표현식')
}

+  하지만 위 Hoisting 해석 코드의 var 를  let 이나 const로 바꾼다면

Uncaught ReferenceError: hoist is not defined

라는 결과가 나오게 된다.  그 이유는 스코프에 진입할 때 변수가 만들어지고 TDZ(Temporal Dead Zone)가 생성되지만,

코드 실행이 변수가 실제 있는 위치에 도달할 때까지 액세스할 수 없는 것이다.

 

 

TDZ : let/const선언은 기본적으로 실행중인 실행 컨텍스트의 어휘적 환경(Lexical Environment)으로 범위가 지정된 변수를 정의한다.

변수는 그들의 어휘적 환경에 포함될 때 생성되지만, 어휘적 바인딩이 실행되기 전까지는 액세스할 수 없다.

새로운 범위에 진입할 때마다 지정된 범위에 속한 모든 let/const바인딩이 지정된 범위 내부의 코드가 실행되기 전에 실행된다.

(즉, let/const선언이 호이스팅된다.)

어휘적 바인딩이 실행되기 전까지 액세스할 수 없는 현상을 TDZ라고 한다.


이제 막 javacript를 배우기 시작한 나에게 var 과 let , const라는 ES6 문법에 대한 이해가 많이 부족해서 더 공부해서
다시 글로 다뤄볼 예정이다. var만 생각하고 시작한 scope에 대해 정리하려고 찾아보다가 더 많은 궁금증이 생겨버렸다.

'Study JS for me > Keyword' 카테고리의 다른 글

Template literals  (0) 2019.05.11
ES6 : let , const  (0) 2019.05.10
call & apply & bind  (0) 2019.04.27
Execution context 와 This  (0) 2019.04.26
Closure  (0) 2019.04.23
Comments