자바스크립트/Likelion_JS
2-6. Scope 와 Hoisting
김딸기*
2024. 10. 5. 02:03
함수와호이스팅
호이스팅(Hoisting)은 자바스크립트에서 나중에 선언된 변수나 함수를 코드 맨 위로 끌어올려 먼저 사용할 수 있게 해주는 기능입니다.
변수 호이스팅: 변수를 코드 아래에서 선언해도, 자바스크립트가 그 변수를 코드 맨 위로 끌어올려 오류 없이 사용할 수 있게 해주는 기능입니다. var로 선언한 변수만 호이스팅되며, 값이 할당되기 전까지는 undefined 상태입니다.
=> let, const 로 선언된 변수는 호이스팅이 지원되지않습니다
//var hoisting test......................
//아래에 선언된 변수의 선언부분만(값 할당은 빼고) 위로 올린다.
console.log(`step1, data1 = ${data1}`)//step1, data1 = undefined
data1 = 20
console.log(`step2, data1 = ${data1}`)//step2, data1 = 20
var data1 = 10
console.log(`step3, data1 = ${data1}`)//step3, data1 = 10
//test2................let, const hoisting............
console.log(data2)//Cannot access 'data2' before initialization
console.log(data3)//Cannot access 'data3' before initialization
let data2 = 10
const data3 = 30
//==>var 에 한해서만 hoisting 에 의해 선언위치 위에서 변수 이용 가능
함수 호이스팅: 함수도 코드 아래에 선언된 함수를 위에서 사용할 수 있게 해주는 기능입니다. 다만, 함수 선언식만 호이스팅되고, 함수 표현식은 호이스팅되지 않습니다.
//test3.........함수 호이스팅................
console.log(myFun1())//myFun1 call
function myFun1(){
return 'myFun1 call'
}
console.log(myFun2())//error... Cannot access 'myFun2' before initialization
const myFun2 = () => {
return 'myFun2 call'
}
이처럼, 코드 실행 전에 변수와 함수가 자동으로 위로 올라가는 것을 호이스팅이라고 합니다.
1. 함수 선언식 (Function Declaration)
- 정의: 함수 이름과 함께 정의하는 방법입니다.
- 호이스팅: 이 방식으로 정의된 함수는 코드 어디에서든 호출할 수 있습니다.
//함수선언식console.log(add(2, 3)); // 5 (호출하기 전에 정의해도 됨)
function add(a, b) {return a + b; // 두 수를 더해서 반환}
2. 함수 표현식 (Function Expression)
- 정의: 변수를 사용해 함수를 정의하는 방법입니다. 보통 이름이 없습니다(익명 함수).
- 호이스팅: 이 방식으로 정의한 함수는 정의하기 전에 호출할 수 없습니다.
console.log(multiply(2, 3)); // 에러 발생 (호출하기 전에 정의해야 함)
//함수표현식->변수로 표현const multiply = function(a, b) {return a * b; // 두 수를 곱해서 반환};
요약
- 함수 선언식: 쉽게 정의하고, 어디서든 호출 가능.=>호이스팅 가능
- 함수 표현식: 변수를 사용해 정의하고, 정의한 후에만 호출 가능.
스코프
코드는 {}로 묶여 같은 영역에서 실행되며, 이를 스코프라고 합니다.
- 스코프는 코드가 실행되는 범위를 의미합니다. {}로 묶인 함수, for문, if문 등이 스코프를 형성합니다. 그 안에서 선언된 변수는 그 스코프 안에서만 유효합니다.
- 중복 선언은 같은 이름의 변수를 다시 선언하는 것을 말합니다.
- 다른 스코프에서는 같은 이름의 변수를 선언해도 서로 영향을 주지 않으므로 문제가 되지 않습니다.
- 하지만 같은 스코프에서 중복 선언할 경우, var로 선언된 변수는 허용되지만, let과 const로 선언된 변수는 중복이 불가능합니다.
- var는 함수 스코프만 지원하며, for문이나 if문 같은 블록 스코프에서는 영향을 받지 않습니다.
var 변수는 함수 안에서만 사용되고, 블록 {}에서는 유효 범위가 아니라, 전체 함수에서 접근할 수 있어요.
다른 방법인 let이나 const는 블록 안에서만 사용 가능하답니다.
함수 스코프: 함수 내에서만 유효하며, 함수 밖에서는 접근 불가능. (var로 선언한 변수)
블록 스코프: 블록 {} 내에서만 유효하며, 블록 밖에서는 접근 불가능. (let이나 const로 선언한 변수)
결론적으로, 변수 선언 시 스코프를 잘 이해하고 var, let, const를 적절히 사용해야 합니다.
//함수 중복 선언................................
function myFun1(){ console.log('step1') } // 선언식 함수
function myFun1(){ console.log('step2') }
myFun1()//step2
var myFun2 = function(){console.log('step1')} // var 에 대입되는 표현식 함수
var myFun2 = function(){console.log('step2')}
myFun2()//step2
let myFun3 = function(){console.log('step1')}
let myFun3 = function(){console.log('step2')}//error
//==>함수 중복 선언 : 선언식 함수와 var 에 대입되는 표현식 함수만
var과 스코프
- var: var로 선언한 변수는 함수 안에서 선언하면 그 함수 스코프 내에서만 사용할 수 있습니다. 만약 함수 밖에서 var로 변수를 선언하면, 그 변수는 전역 변수(Global Variable)가 되어 전체 코드에서 사용할 수 있습니다.

function myFunction() {
var functionScoped = "나는 함수 스코프 안에 있어요!";
console.log(functionScoped); // "나는 함수 스코프 안에 있어요!" 출력
}
myFunction();
console.log(functionScoped); // 오류 발생! 함수 밖에서는 사용할 수 없습니다.
- 블록 스코프: let이나 const로 선언한 변수는 블록 {} 안에서만 사용할 수 있습니다. 블록 밖에서는 접근할 수 없습니다.

블록 스코프 예시
{
let blockScoped = "나는 블록 스코프 안에 있어요!";
console.log(blockScoped); // "나는 블록 스코프 안에 있어요!" 출력
}
console.log(blockScoped); // 오류 발생! 블록 밖에서는 사용할 수 없습니다.
요약
- var로 선언한 변수:
- 함수 안에서 선언하면 함수 스코프 안에서만 유효합니다.
- 함수 밖에서 선언하면 전체 코드에서 유효하게 됩니다 (전역 변수).
- let과 const로 선언한 변수:
- 블록 {} 안에서만 유효하고, 블록 밖에서는 사용할 수 없습니다.
let name1 = '홍길동'
const someFun = () => {
let name1 = '김길동'
console.log(`in someFun 1, name1 = ${name1}`)//김
for(let i=0; i<1; i++){
let name1 = '이길동'
console.log(`in someFun, in for, name1 = ${name1}`)//이
}
console.log(`in someFun 2, name1 = ${name1}`)//김
if(true){
let name1 = '박길동'
console.log(`in someFun, in if, name1 = ${name1}`)//박
}
console.log(`in someFun 3, name1 = ${name1}`)//김
}
someFun()
console.log(`out someFun, name1 = ${name1}`)//홍
// in someFun 1, name1 = 김길동
// in someFun, in for, name1 = 이길동
// in someFun 2, name1 = 김길동
// in someFun, in if, name1 = 박길동
// in someFun 3, name1 = 김길동
// out someFun, name1 = 홍길동
//==>let 은 함수, for, if 스코프 지원한다.