글 작성자: bbangson
반응형

scope 이해하기

 

Scope란?

변수 혹은 함수를 선언하게 될 때, 해당 변수 혹은 함수가 어디까지 유효한 지 범위를 나타내는 개념입니다. 

 

scope의 범위에는 Global, function, block이 있습니다. 

 

Global은 모든 범위(전역)에서 사용 가능한 것을 의미합니다. 

Function은 특정 함수 내부에서만 사용 가능한 것을 의미합니다.

Block은 if문, switch문, for문을 작성하게 될 때, 중괄호로 코드를 작성하게 되는데 중괄호로 감싸진 블록 내부에서만 사용 가능한 것을 의미합니다. 

 

scope는 자바스크립트의 문법이라기 보단 작동 원리라고 이해하는 것이 좋습니다. 

 

Global, function scope의 예입니다.

const value = 'hello!'; // global scope변수이다. 

function myFunction() {
    console.log('myFunction: ');
    console.log(value); // 'hello!' 출력.
}

// 함수형 scope 변수이다.
function otherFunction() {
    console.log('otherFunction: ');
    const value = 'bye!'; // 특정 함수 내부에서만 사용 가능한 변수이다. 
    console.log(value); // 'bye!' 출력.
}

myFunction();
otherFunction();

console.log('global scope : ');
console.log(value); // 'hello!' 출력.

위의 코드에서 최상단에 위치한 value 변수는 global scope 변수입니다.

value 값이 바뀌지 않는 한, value를 출력하게 되면 'hello!'를 출력하게 됩니다. 

 

하지만 otherFunction() 함수 안에 있는 value는 특정 함수 내부에서만 사용 가능한 function scope 변수입니다. 

기존의 value 값을 무시하고 otherFunction() 내부에서만 사용 가능한 value 변수를 생성합니다. 

이 함수 안에서 value 값을 출력하면 'bye!'를 출력하게 됩니다. 

 

또한, function scope 변수는 같은 이름으로 된 변수라도 기존의 global scope 변수에 영향을 주지 않습니다. 

그래서 맨 밑 코드에 위치한 value 값을 출력하는 코드를 보면 영향을 받지 않고 'hello!'를 출력하는 것을 알 수 있습니다.

 

또 다른 예시를 보겠습니다. 

const value = 'hello!'; // global scope변수이다. 

function myFunction() {
	const value = 'bye!';
    const anotherValue = 'world';
    
    function functionInside() {
        console.log('functionInside : ');
        console.log(value); // 'bye!' 출력.
        console.log(anotherValue); // 'world' 출력.
    }
    functionInside();
}

myFunction();
console.log('global scope : ');
console.log(value); // 'hello' 출력.
console.log(anotherValue); // 에러 출력. (is not defined)

위 코드는 함수 안에 함수를 만들어서 내부 함수 바깥에서 선언된 변수가 내부 함수 안에서 출력했을 경우, 출력이 되는지 확인하는 코드입니다. 

 

또한, function scope 안에서 변수를 선언하고, function scope 밖에서 변수를 출력하였을 경우를 확인해 볼 수 있는 코드입니다. 

 

먼저 함수 안에 위치한 함수( functionInside() )는 바깥 함수( myfunction() ) 범위 안에 들어가기 때문에, 바깥 함수에서 선언된 변수라도 내부 함수에서 출력할 수 있습니다. 

 

맨 마지막 코드인 anotherValue 변수를 출력하는 코드는 에러를 발생시킵니다. 

 

그 이유는 anotherValue 변수는 function scope이기 때문에 함수 밖에서 사용하고자 하면 이 변수를 찾지 못하기 때문입니다. 그래서 'undefined error'를 발생시킵니다.  

 

 

block scope 예시를 보겠습니다. 

const value = 'hello!'; // global scope변수이다. 

function myFunction() {
	const value = 'bye!';
    
    if(true) {
        const value = 'world'; // 이 값은 block scope이다.
        console.log('block scope: ');
        console.log(value); // 'world' 출력.
    }
    console.log('function scope: ');
    console.log(value); // 'bye!' 출력.
}

myFunction();
console.log('global scope : ');
console.log(value); // 'hello' 출력.

if문 안에서 선언된 value는 block scope입니다. 그래서 if문을 만들기 위해 구성된 중괄호 안이 이 변수가 유효한 범위가 됩니다. 

 

만약 위에서 3번 선언된 value 변수들을 'const'가 아닌 'var'로 수정한다면 어떤 일이 발생할까요? 

 

function scope의 변수인 value가 block scope의 영향을 받아 'bye!'를 출력하지 않고 'world'가 출력됩니다. 

그 이유는 'var'는 function scope으로 설정되기 때문에 if문 안에서 value값이 다시 초기화되기 때문입니다.

 

그래서 if문 밑에서 value 변수를 출력하고자 한다면 value 변수는 기존의 function scope의 'bye!'가 아닌  'world'가 출력되는 것입니다. 즉, 기존의 값이 영향을 받는 것입니다. 

 

'var' 보단 'const'나 'let'을 사용하는 것이 좋습니다. 

 

 

 

hoisting

 

hoisting이란?

자바스크립트에서 아직 선언되지 않은 함수 혹은 변수를 끌어올려서 사용할 수 있는 자바스크립트의 작동 방식을 의미합니다.

 

빠르게 예시를 보여드리겠습니다. 

myFunction();

function myFunction() {
    console.log('hello world');
}

위의 코드는 정상 작동합니다. 

이렇게 함수가 선언되기도 전에 함수를 호출해도 자바스크립트에서는 잘 작동합니다. 

이런 식으로 함수 혹은 변수를 끌어올려서 사용하는 것을 hoisting이라고 합니다. 

 

하지만 hoisting은 웬만하면 피해야 합니다. hoisting은 방지해야 하는 것입니다. 

 

그 이유는 다른 사람이 봤을 때 코드를 이해하기 어려워질 수 있기 때문입니다. 

 

변수 또한 hoisting이 적용되는 경우가 있습니다. 

'var'로 변수를 선언할 경우에는 hoisting이 됩니다. 하지만 undefined가 뜹니다. 

하지만 'const''let'은 hoisting이 되지 않습니다. 'cannot access before initialization~ ' 오류가 뜰 것입니다. 

 

hoisting을 방지하는 방법입니다.

myFunction(); // error 발생

const myFunction = function myFunction() {
    console.log('hello world');
}

위의 코드로 hoisting을 방지할 수 있지만 굳이 이렇게 하지 않아도 그냥 코드를 작성할 때

함수를 선언 후, 함수를 호출하는 습관을 들이는 게 좋습니다.

 

어차피 사실 ESlint 사용하면 경고창으로 다 알려줍니다. 걱정 안 하셔도 됩니다. 

hoisting을 방지하는 코딩 습관만 들이면 될 것 같습니다.

 

 

 

참고 강의

프론트엔드 개발 올인원 패키지 with React Online. | 패스트캠퍼스 (fastcampus.co.kr)

 

프론트엔드 개발 올인원 패키지 with React Online. | 패스트캠퍼스

프론트엔드 개발 러닝패스, 이 강의 패키지 하나로 끝낼 수 있습니다. 총 90시간 분량의 평생 소장 온라인 강의로 프론트엔드 개발자가 되세요.

www.fastcampus.co.kr

 

반응형