Ep11. 스코프와 호이스팅

hyobin·2022년 6월 17일
17

자바스크립트 기초

목록 보기
11/16
post-thumbnail

안녕하세요😄

이번시간에는 자바스크립트의 스코프와 호이스팅에 대해 다뤄보도록 하겠습니다.

스코프

스코프(Scope)란 범위 라는 뜻으로, 자바스크립트에서는 우리가 변수 또는 함수를 생성할 때, 해당 변수 또는 함수가 갖게 되는 유효범위 를 뜻합니다.

자바스크립트의 스코프에는 여러 종류가 있습니다.
범위별로 하나씩 살펴보겠습니다.

전역 스코프와 지역 스코프

전역 스코프(Global Scope)는 전역(Global)에 선언되어있어, 어느 곳이든지 해당 변수에 접근 할 수 있습니다.

반면, 지역 스코프(Local Scope)는 말 그대로 해당 지역에서만 접근할 수 있는, 지역을 벗어난 곳에서는 접근할 수 없는 범위를 나타냅니다.

저번 시간에 배웠던 전역변수는 전역 스코프를 갖고, 내부변수는 지역 스코프를 갖습니다.

아래의 코드를 통해 전역, 지역 스코프에 대해 알아보겠습니다.

const num = 10; //전역 스코프

function print() {
    const num = 100; //지역 스코프
    console.log(`지역 스코프 ${num}`);
}

print();
console.log(`전역 스코프 ${num}`);

위의 코드를 실행하면 다음과 같은 결과값이 출력됩니다.

지역 스코프 100
전역 스코프 10

print 함수 내부에 선언된 num 변수는 함수 내부에서만 접근 가능한 지역 스코프 이기 때문에 먼저 "지역 스코프 100" 이 출력되고,
함수 밖에 있는 num 변수는 전역에서 접근 가능한 전역 스코프 이기 때문에 가장 마지막 줄에 있는 console.log() 를 통해 "전역 스코프 10" 이 출력되는 것을 확인 할 수 있습니다.

같은 지역에서만 접근 가능한 지역 스코프에는 함수 스코프, 블록 스코프 이렇게 2가지 종류의 스코프가 있습니다.

이 2가지 스코프에 대해 자세하게 알아보겠습니다.

함수 스코프

함수 스코프는 함수가 선언되면 그 함수 안에서만 접근 가능한 것을 의미합니다.

function print() {
    let num = 10;
}
console.log(num); //ERROR

위의 코드를 실행하면, print 함수 내부에 선언된 num 변수는 지역 스코프 중 함수 스코프 이기 때문에, 외부에 있는 console 은 num변수에 접근하지 못해 ERROR 가 발생하게 됩니다.

블록 스코프

블록 스코프는 블록{} 내부에서 선언된 변수는 해당 블록에서만 접근 가능한 것을 의미합니다.

function print() {
    for (let i = 0; i < 10; i++) {}
    console.log(i); //ERROR
}

print();

위의 코드를 실행시켜보면, "i is not defined" 라는 오류가 발생합니다.

우리가 배웠던 letconst블록 스코프로, for문 안에 let 으로 선언된 변수 i 는 for문 블록("{}" 기준)에서만 접근 가능하기 때문에 위의 코드와 같이 오류가 발생하게 되는 것을 확인할 수 있습니다.

let과 var

우리는 강의를 시작할 때, 자바스크립트에서 letconst 라는 키워드로 변수를 생성한다고 배웠었는데요, 자바스크립트에서는 var 라는 키워드로 변수를 생성할 수 도 있습니다.

let num1 = 10;
var num2 = 20;

num1 = 100;
num2 = 200;

console.log(num1); // 100
console.log(num2); // 200

위의 코드와 같이 var 로 선언한 변수는 let 으로 선언한 변수와 유사하게 동작합니다.

하지만 var는 오래된 변수 선언 키워드 라고도 불리며, 잘 사용하지 않는 키워드 입니다.

그렇다면 var 와 let 은 어떤 차이점이 있는지, 그리고 왜 많은 사람들이 var 대신 let을 이용하여 변수를 선언하는지 하나씩 살펴보겠습니다.

1. 변수 선언 방식

let 과 var 를 사용해 변수를 선언 후, 재선언을 해보겠습니다.

먼저 let 으로 변수를 생성해보았습니다.

let num1 = 10;
let num1 = 100;

console.log(num1); //ERROR

코드 실행 결과 "이미 num1 이 선언되어있다" 라는 오류가 발생하는 것을 볼 수 있습니다.

그렇다면 var로 선언된 변수는 어떨지 확인해보겠습니다.

var num2 = 20;
var num2 = 200;

console.log(num2); //200

위의 코드를 실행시키면 200 이라는 값이 출력되는 것을 볼 수 있습니다.

이렇게 var 키워드를 이용하면 변수를 여러번 다시 선언할 수 있고, 기존에 선언되었던 동일한 변수는 무시되는 것을 확인할 수 있습니다.

var로 선언된 변수가 더 유연하다고 생각하실 수 있지만,
코드량이 많은 js 프로그램에서 var 로 변수를 선언한다면, 특정 변수가 이미 선언이 되어있는지 판단하기 어려울 뿐만 아니라, 어디서 어떻게 사용되고 있는지 파악이 힘들어지고 프로그램상의 오류를 발생시킬 수 있게됩니다.

2. 함수 스코프

let 과 var 의 또다른 차이점은 var은 함수 스코프 이며, let은 블록 스코프 라는 것입니다.

아래 코드를 통해 자세하게 알아보겠습니다.

function print() {
    for (var i = 0; i < 10; i++) {}
    console.log(i); //10
}

print();

이 코드는 위에서 우리가 블록 스코프를 알아보기 위해 실행해보았던 코드입니다.

이렇게 동일한 코드에서 for문 내부에 변수 i 를 let이 아닌 var로 선언해보았습니다.

이번에는 에러가 발생하지 않고 10이 출력되는 것을 확인할 수 있습니다.

동일한 코드이지만 함수 내부에서 let 으로 변수를 선언했을 땐 에러가 나고 var로 변수를 선언했을 때는 에러가 발생하지 않게 되는 이유는,

var 키워드는 함수 스코프 이기 때문에 var 가 선언된 함수 내부에서 해당 변수에 접근을 하는 것은 가능하기 때문입니다.

이러한 차이점과 단점 때문에 많은 사람들이 let을 이용해 변수를 선언하고 있고, 이번 강의에서도 var 가 아닌, let을 이용해 변수 선언을 하도록 하겠습니다.

호이스팅

호이스팅이란, 아직 선언되지 않은 함수나 변수들을 해당 스코프의 맨 위로 끌어올려서 사용하는 자바스크립트의 작동 방식을 의미합니다.

함수 호이스팅

아래의 코드를 통해 살펴보도록 하겠습니다.

print();

function print() {
    console.log("hello world");
}

위의 코드에서 print 함수를 선언하기 전에 print 함수를 호출해주었습니다.
함수가 아직 선언되지 않았지만, 코드는 정상적으로 작동하는 것을 확인할 수 있습니다.

위의 코드가 정상적으로 작동하는 이유는, 자바스크립트 엔진이 위 코드를 해석하는 과정에서 아래의 코드와 같이 받아들이기 때문입니다.

function print() {
    console.log("hello world");
}

print();

이러한 방식을 호이스팅(Hoisting) 이라고 부르며, 코드 실행 시 함수 선언문을 스코프의 맨 위로 끌어올리는 방식을 함수 호이스팅 이라고 부릅니다.

변수 호이스팅

자바스크립트에서는 함수 뿐만 아니라 변수 또한 호이스팅이 됩니다.

아래의 코드를 실행시켜보겠습니다.

console.log(num); // undefined

var num = 10;

num 변수가 선언되기 전에 console.log 함수로 num의 값을 출력하려했지만, 실행 결과 ERROR 가 아닌 undefined 가 출력됩니다.

그 이유는 자바스크립트 엔진이, 위의 코드를 아래와 같이 해석하기 때문입니다.

var num;
console.log(num); // undefined
num = 10;

이러한 방식을 변수 호이스팅 이라고 하며, 변수 호이스팅은 var로 선언된 변수에서만 일어나고, let 또는 const 로 선언된 변수에서는 호이스팅이 발생하지 않습니다.

호이스팅은 자바스크립트의 기본 성질이지만, 호이스팅이 많이 발생하게 작성된 코드는 가독성도 좋지 않아 코드의 이해도가 떨어지고, 많은 오류를 발생시킬 수 있기 때문에 방지하는 것이 좋습니다.

호이스팅이 많이 발생하는 코드를 작성하지 않기 위해서는 되도록 변수는 let 과 const로 선언해야하며, 함수는 호출 전에 미리 선언을 할 수 있도록 해야합니다.


next

이번 시간에는 자바스크립트의 스코프와 호이스팅을 배우면서 var 이라는 변수 선언 키워드에 대해 다뤄보았습니다.

앞으로 다루게 될 강의의 코드에서는 var 를 사용하지 않고, 모두 let 또는 const를 이용해 변수를 선언하도록 하겠습니다.

다음 시간에는 자바스크립트의 함수표현식과 콜백함수, 화살표형 함수에 대해 배워보도록 하겠습니다.

감사합니다😀


🙏참고 & 출처

https://developer.mozilla.org/ko/docs/Glossary/Hoisting
https://poiemaweb.com/js-scope

3개의 댓글

comment-user-thumbnail
2022년 6월 18일

잘 보고 가용 ㅎㅎ

1개의 답글
comment-user-thumbnail
2022년 6월 29일

유익하네요 감사합니다 !!

답글 달기