[JS] 스코프와 변수(let, const, var)

jellyjw·2022년 11월 7일
0
post-thumbnail
post-custom-banner

스코프(scope)

스코프는 변수 접근 규칙에 따른 유효 범위 를 의미한다.
안쪽 스코프에서 바깥쪽 스코프로는 접근이 가능하지만, 반대의 경우는 불가능하다.

let username = 'jangjiwoo';
if(username) {
  let message = `hello, ${username}!`;
  console.log(message); // hello, jangjiwoo!
}

console.log(message) // reference error

이 예제에서, if문 안에 있는 console.log(message) 는 정상적으로 출력되지만 if문 밖에 있는 console.log(message)는 변수 자체가 중괄호(블록) 안쪽에 선언 되어 있으므로 바깥쪽에서 접근할 수 없다.

이처럼, 변수에 접근할 수 있는 범위가 존재하는데 중괄호 {} 안쪽에 변수가 선언되었는가, 바깥쪽에 변수가 선언되었는가가 중요하다. 이 범위를 스코프라고 부른다.

  • 안쪽 스코프에서 바깥쪽 스코프로는 접근이 가능하지만, 그 반대의 경우는 불가능하다.
  • 스코프는 중첩이 가능하다.
  • 지역변수는 전역변수보다 더 높은 우선순위를 가진다.


[출처] 코드스테이츠

가장 바깥쪽의 스코프는 전역 스코프(Global Scope) 라고 부르고, 전역이 아닌 다른 스코프는 전부 지역 스코프(local scope)이다.

let name = 'jangjiwoo'; // 전역 변수

function showName() {
  let name = '장지우'; // 지역 변수
  console.log(name); // 장지우
}

console.log(name) // jangjiwoo
showName();
console.log(name) // jangjiwoo

위 예제와 같이 함수 밖에서 console.log(name) 을 출력했을 때 스코프 규칙에 의해 함수 내부의 지역변수에는 접근할 수 없기 때문에 "장지우"를 출력한다.
함수 내부에서 console.log(name) 을 했을 때에는, 지역 변수가 전역 변수보다 우선순위가 높으므로 지역변수 name 이 출력된다.

동일한 변수명으로 인해 바깥쪽 변수가 안쪽 변수에 의해 가려지는 현상을 쉐도잉(variable shadowing)이라고 부른다.

스코프 종류(블록 스코프, 함수 스코프)


블록 스코프(block scope)

블록스코프는 중괄호를 기준으로 범위가 구분된다.

if(true) {
  console.log('i am jangjiwoo');
}

함수 스코프(function scope)

function 키워드가 등장하는 함수선언식 및 함수표현식은 함수스코프를 만든다.

여기서 중요한 사실은, 화살표 함수가 블록 스코프로 취급된다는 점이다.


var와 let, const

스코프는 변수 접근 규칙에 따른 유효 범위 라고 했는데, 변수를 정의하는 키워드에 따라 범위가 달라질 수 있다!

var

유효범위 : 함수 스코프

  • var 키워드는 블록 스코프를 무시하고 함수 스코프만 따른다.
  • 화살표 함수의 블록 스코프는 무시하지 않는다 (모든 블록 스코프 무시 x)
  • 블록 단위로 스코프를 구분했을 때 훨씬 예측 가능한 코드 작성이 가능하기에, let키워드 사용이 권장된다.
  • 재선언, 재할당이 모두 가능하다.

let

유효범위 : 블록 스코프 및 함수 스코프

  • 재선언이 금지된다. var는 재선언을 해도 오류가 나지 않지만, let 사용하여 재선언할 시에 SyntaxError 가 난다.
  • 재할당 가능

const

유효범위 : 블록 스코프 및 함수 스코프

  • 변하지 않는 값, 상수(constant)를 정의한다.
  • 값의 재선언 및 재할당이 모두 불가하다. 값을 재할당할 경우 TypeError 가 뜨며 의도하지 않은 값의 변경을 막을 수 있다.

전역변수가 많은것은 결코 좋은것이 아니다.
애플리케이션이나 웹 사이트를 만들 때, 내가 작성한 코드만 들어가는 경우는 거의 없을 것이다. 수많은 다른 함수와 로직이 포함되는데 전역변수가 많다면 문제가 발생할 확률이 매우 높아진다.

똑같은 이름으로 전역 변수를 선언하거나 값을 재할당하는 경우를 side effect라고 하는데, 전역변수를 최소화하는 것은 side effect를 줄이는 좋은 방법이다!

profile
남는건 기록뿐👩🏻‍💻
post-custom-banner

0개의 댓글