스코프, 호이스팅

Wook·2024년 8월 25일

💫JavaScript

목록 보기
8/11
post-thumbnail

스코프

전역 스코프, 지역 스코프

let x = 0;

const scopeTest = function(){
	let y = 1;
  console.log(x);
}

console.log(x);
console.log(y);

// x : 전역 변수, 스코프 전체에서 참조할 수 있으며, 지역 스코프 내에서도 참조 가능
// y : 지역 변수, 지역 스코프, 함수 밖에서는 참조 불가능

전역 스코프에 선언된 변수는 스코프 전체에서 참조될 수 있다
전역 스코프에 존재하는 변수를 전역 변수라고 함

지역 스코프 내에 선언된 변수는 해당 지역에서만 존재할 수 있다.
특정 지역 스코프 내에 존재하는 변수를 지역 변수라고 함

함수 스코프

자바스크립트는 최초에 var라는 키워드만 존재했고, var는 함수 레벨 스코프만 따르는 키워드이므로 함수 스코프로 동작하는 프로그래밍 언어였음. 하지만 이후 let, const 키워드를 통해 블록 스코프를 도입

함수를 실행할 때 생겨나는 지역 스코프
함수의 코드 블럭만을 지역 스코프로 인식함
-> if, for문과 같은 코드 블럭은 전역 스코프로 인식되어 과도한 메모리를 소모하는 문제

블록 스코프

모든 코드 블럭 내에서 선언된 변수를 지역 변수로 인식
-> 함수뿐만 아니라 if문, for문, while문 등
해당 변수는 해당 코드 블럭 내부에서만 유효함
각각의 스코프에서 선언되는 변수는 서로 영향을 주지 않음.

스코프 체이닝

변수를 참조하는 코드가 실행될 경우,

  • 먼저 해당하는 블록 스코프 내에서 변수 참조를 시도
  • 해당 스코프에 변수가 존재하지 않을 경우, 상위 스코프로 올라가 다시 탐색
for(let i = 0; i < 6; i++){
  let a = "123"
  if (i > 3){
  	console.log(a)
  }
  let b = "123"
}

// if문의 블록 스코프에 a가 없지만 정상적으로 동작함
// for문의 블록 스코프에서 a 변수를 참조

함수, 변수의 호이스팅

JavaScript는 코드를 실행하기 전에 선언된 변수, 함수 등을 전역 환경에 담아둠
(-> 이떄 변수는 선언 단계를 거침)
이후 정리된 코드를 실행

console.log(a)
let a = "abc"

// 결과: 에러 발생 'a is not defined'

console.log(b)
var b = "bcd"

// 결과: undefined 출력
// var로 선언된 변수는 자바스크립트를 해석하는 과정에서
// 마치 선언 단계가 위로 끌어 올려진 것처럼 동작

// var 처럼 에러가 발생하지 않으면 문제를 미연에 방지하기 어려워짐

호이스팅

함수, 변수의 선언이 마치 위로 끌어올려진 것처럼 동작하는 것
자바스크립트가 코드 해석&실행 과정과, 내부적인 변수의 선언&할당 과정 때문

변수의 선언 단계

  1. 선언 단계
    선언한 변수를 변수명이 담기는 객체에 할당하는 단계
  2. 초기화 단계
    변수에 할당할 메모리 공간을 부여하는 단계
    초기화까지 끝나면 undefined
  3. 할당 단계
    정의된 변수에 데이터가 할당되는 단계
  • let, const

    let과 const는 선언 단계와 초기화 단계가 분리되어 그 사이에 TDZ(Temporal Dead Zone)이 존재
    따라서 실제로는 호이스팅이 발생하지만 TDZ에 의해 초기화 단계 이전에 변수를 참조하려 시도하면 참조 에러(Reference Error) 발생

📌 함수 표현식도 TDZ의 영향을 받으므로 호이스팅이 발생하지 않는 것처럼 동작

const fn = function(){
	console.log("TDZ의 영향을 받음")
}

  • var

    선언 단계와 초기화 단계가 동시에 진행되어 TDZ가 존재하지 않음.
    JavaScript가 변수, 함수를 정리하는 과정에서 이미 임시 메모리를 할당 받음
    -> 따라서 변수를 참조하려고 시도하면 undefined가 찍힘

📌 선언 키워드가 없는 함수 선언식은 TDZ의 영향을 받지 않고 호이스팅이 발생하며, 아예 함수 자체가 끌어올려진 것처럼 동작

function fn(){
	console.log("TDZ의 영향을 받지 않음")
}
profile
Keep going

0개의 댓글