변수의 유효 범위

Doum Kim·2020년 6월 25일
0

Javascript

목록 보기
16/23
post-thumbnail

변수의 유효 범위

🥊🥊 전역 유효 범위 vs 지역 유효 범위

변수에 접근할 수 있는 범위를 그 변수의 유효 범위 또는 스코프라고 한다.
자바스크립트는 프로그램의 구문만으로 유효 범위를 정하는 어휘적 범위 또는 렉시컬 스코프이다.
자바스크립트 변수는 유효 범위에 따라 두 가지로 나눠진다.

  1. 전역 변수
    함수 바깥에서 선언된 변수로 유효 범위가 전체 프로그램이다.

  2. 지역 변수
    함수 안에서 선언된 변수와 함수 인자로 유효 범위는 변수가 선언된 함수 내부이다.

ex(1)

var a = 'global'
function foo = () {
  var b = "local"
  console.log(a);  // -> 'global'
  return b;
}
foo();
console.log(b); // -> ReferenceError:b is not defined

ex(2)

var a = 'global'
function foo = () {
  var a = "local"
  console.log(a);  // -> 'local'
  return b;
}
foo();
console.log(a); // -> 'global'

ex(3)

var a = 'global'
function foo = () {
  a = "local"
  console.log(a);  // -> 'local'
  return a;
}
foo();
console.log(a); // -> 'local'

변수 호이스팅

중간 부분에서 변수를 선언하더라도 변수는 함수 첫머리에서 선언된 것처럼 함수 안의 다른 문장보다 먼저 생성된다.
즉, 자바스크립트 엔진은 함수 안의 변수 선언부를 함수의 제일 위로 끌어올린다.

function foo = () {
  console.log(a); // -> undefined
  var a = "local"
  console.log(a);  // -> 'local'
  return a;
}
foo();

🥊🥊 var vs let

var는 잊어버려!!

대부분의 자바스크립트 개발자들은 'var 키워드를 사용해서 변수를 만들지 마세요' 라고 한다.
그럼 그 var와 let을 한번 비교해보자.

  • let/const는 재 선언이 불가능하다. 같은 스코프에서 똑같은 식별자로 선언을 하면 에러가 발생한다.
    스코프가 block({})을 기준으로 잡힌다.

  • var은 일단 재 선언이 가능하다. 같은 스코프에서 똑같은 식별자로 선언을 해도 문제가 되지 않는다.
    이러한 특성으로 variable shadowing이 가능하며 함수형 프로그래밍에서는 side effect를 제거하는데 좋다.
    스코프가 function을 기준으로 잡힌다.

이렇게만 비교를 했을 때 딱히 var이 나쁜점이 없어보이는데? 라고 생각할 수도 있다.
그렇다면 아래의 예를 한번 보자.

ex(1)

var a = 10;
if(true) {
  var a = 30;
}
console.log(a); // -> 30

var b = 10;
function foo() {
  var b =20;
}
foo();
console.log(b); // ->  10

function 기준으로 스코프가 잡히는 var 키워드는 if문 같은 block을 기준으로 스코프를 갖지 못한다.
따라서 전역 변수 a의 값이 변경되는 문제가 발생한다.

ex(2)

let a = 10;
if(true) {
  let a = 20;
}
console.log(a) // -> 10

let b = 10;
function foo() {
  let b = 20;
}
foo();
console.log(b) // -> 10

반대로 block 스코프를 가지는 let 키워드는 if문 같은 block을 기준으로 스코프를 가진다.
따라서 전역 범위와는 상관이 없는 a 변수를 지역 범위에 또 선언을 할 수 있다.

결론은 var을 써서 문제가 될 수 있는 부분이 더 많기 때문에 var을 사용하지 말자.....

0개의 댓글