scope 이해하기

csongin·2022년 9월 24일
0

developer

목록 보기
5/15

Scope

Scope란?

scope은 JavaScript의 문법이 아니다.

JavaScript에서 scope란, '변수가 어디까지 쓰일 수 있는지'의 범위를 의미합니다.

is not defined

변수가 아직 선언되지 않았다는 뜻입니다.

변수는 let, const, var 등으로 선언할 수 있으며, JavaScript가 변수를 선언한 영역(block)에 접근할 수가 없다면 is not defined와 같은 에러 메시지를 나타내게 됩니다.

변수가 선언된 위치에 따라 어디서든 활용 될수도, 특정한 영역 내에서만 사용될 수도 있습니다.

이러한 개념이 바로 scope입니다.


Block

scope을 더 파헤치기 전에 먼저 알아야할 개념은 block입니다.

우리는 functionif 문, for 문 등에서 이미 block을 많이 사용하고 있습니다.

block이란 중괄호({} , curly brace)로 감싸진 영역을 block이라고 합니다.

function 의 내부는 하나의 block입니다.

function hi() {
  return 'i am block';
}

for 문도 하나의 block입니다.

for (let i = 0; i < 10; i++) {
  count++;
}

if 문의 {} 도 역시 하나의 block입니다.

if (i === 1) {
  let j = 'one';
  console.log(j);
}

{} (block)내부에서 변수가 정의되면 변수는 오로지 {} (block)내부에서만 사용할 수 있습니다.

{} (block)내부에서 정의된 변수는 local(지역) 변수라고 부릅니다.

function getResult() {
  let result = 10;
  
  return result;
}

// 자바스크립트 에러! 
// getResult 내부의 scope에 접근할 수 없다.
console.log(result);

console.log(result) 에서 getResult 내부에 접근이 불가능하기 때문에 result 라는 변수의 존재를 알지 못합니다.

result 라는 변수는 getResult 함수의 {} (block)에서만 사용할 수 있습니다.


Global(전역) Scope

scope는 변수가 선언되고 사용할 수 있는 공간입니다.

scope 외부(block밖)에서는 특정 scope의 변수에 접근할 수가 없습니다.

block밖인 global scope에서 만든 변수를 global variable(전역변수)이라고 합니다.

코드 어디서든 접근 가능해서 변수값을 확인할 수 있습니다.

const color = 'red';
console.log(color);

function returnColor() {
  return color;
}

console.log(returnColor());

returnColor 함수 내에서, returnColor 함수 밖에 있는 color 라는 변수를 return 해주었습니다.

color 라는 변수는 global 변수이기 때문에 returnColor 함수의 block에서도 접근이 가능해서 'red' 를 반환한것입니다.


Scope의 오염

global 변수를 쓰면 여기 저기서 접근하기 쉬워서 좋다고 생각할 수 있지만, 너무 남용하면 프로그램에 문제를 일으킬 수 있습니다.

global 변수를 선언하면, 해당프로그램의 어디에서나 사용할 수 있는 global namespace를 갖습니다.

namespace라는 것은 변수 이름을 사용할 수 있는 범위라는 뜻입니다. scope 라고도 하고 특히 변수이름을 얘기할 때는 namespace라고도 합니다.

global 변수는 프로그램이 종료될때까지 계속 살아있습니다. 이 말은 local 변수는 {} - block이 끝나면 더 이상 변수가 살아있지 않고 쓸 수 없다는 말입니다.

global 변수가 계속 살아있어서 변수값이 계속 변한다면 해당 변수를 트래킹하기도 어렵고 이 변수는 어디에서 왜 필요한지 알려면 도대체 어디에서 let, const로 선언을 했는지 찾아 나서야 합니다.

아래는 scope이 오염된 대표적인 예입니다.

const satellite = 'The Moon';
const galaxy = 'The Milky Way';
let stars = 'North Star';

const callMyNightSky = () => {
  stars = 'Sirius';
  
  return 'Night Sky: ' + satellite + ', ' + stars + ', ' + galaxy;
};

console.log(callMyNightSky());
console.log(stars);
  • stars 이라는 global 변수가 있습니다.
  • callMyNightSky 함수에서 새로운 변수를 선언하고 싶었는데 깜빡하고 let 키워드를 작성하지 않았습니다.
  • callMyNightSky 을 호출하면 stars 변수에 "Sirius" 이 할당됩니다.
  • global 변수였던 stars 에 영향이 갔습니다!
  • 다른 함수에서 global 변수인 stars 을 사용하고 싶은데 값이 수정된 "Sirius" 으로 사용하게 됩니다.

좋은 Scoping 습관

global 변수가 여기저기서 수정되면 안되기 때문에 변수들은 block scope으로 최대한 나눠놔야 합니다.

  • 타이트한 scope(tightly scoping)의 변수는 코드 품질을 올려줍니다!
  • 코드가 block 으로 명확하게 구분되기 때문에 코드 가독성이 올라갑니다.
  • 코드가 한줄 한줄 쭉 나열된 것이 아니라 각각의 기능별로 block을 나누면 코드가 이해하기 쉬워집니다.
  • 나중에 코드를 수정할 일이 있을 때, 코드를 오랜만에 보더라도 잘 나뉘어 있어서 유지보수가 쉬워집니다.
  • 프로그램이 끝날때까지 변수가 살아있는 것이 아니라서(block이 끝나면 local 변수의 삶이 끝나서) 메모리 절약도 됩니다.

즉, 한마디로 요약하면 global 변수는 쓰지 않도록 노력해야 하고, 최대한 {} 내에서 let, const 을 사용하여 변수를 새로 만들어서 써야합니다.

출처


Wecode westudy JavaScript 24.Scope

profile
Backend Developer

0개의 댓글