10. 스코프 (Scope)

Javascript 유효범위 (Scope)에 대해서 학습합니다.

Scope 란 ?

Scope란 말그대로 코드의 영역이라는 뜻입니다. 지역 (local), 전역 (Global)로 나눌 수 있습니다. JS 는 Function 단위로 scope 가 이루어집니다. Scope를 이해한다면 우리가 선언한 변수가 어디까지 참조가될 수 있고, 어디까지 살아있을 수 있는지를 파악할 수 있습니다.

전역변수와 지역변수

var global = "global"; // 전역

function func() {
  var local = "local"; // 지역
}
func();

global 같이 아무것도 감싸지지 않은 가장 바깥영역의 변수를 전역변수 (global)라고 부릅니다. func 함수 안에 감싸져 있는 변수를 지역변수 (local) 라고 부릅니다.

만약에 전역과 지역변수의 이름이 같으면 어떻게 될까요?

var value = "global";

function func() {
  var value = "local";
  console.log(value); // local
}

func();
console.log(value); // global

func 안에서 지역변수 value를 호출했죠? 이 때는 자신의 영역 (local scope) 안에서 해당 변수 (value)를 먼저 찾아봅니다. 자신의 영역 (local Scope) 안에 value가 있습니다. 그럴 경우 자신의 value 를 console 에 출력합니다. JS 에서는 기본적으로 외부 영역에서 내부영역에 접근할 수 없습니다. 하지만 내부에서는 외부로의 접근은 가능합니다. 그렇기 때문에 밖에서 console.log(value) 로 value 를 찾았을 때는 func 안에 value는 참조할 수 없기 때문에 자신의 영역 (global)의 value 를 찍은것 입니다.

Scope Chain

자신의 영역에서 값을 찾는다 -> (없다) -> 다음 스코프에서 찾는다 -> 전역 스코프까지 넓혀가면서 찾아갑니다. 이것을 스코프 체인이라고 부릅니다.

var value = "global";

function outFunc() {
  // 이때의 value는 local영역의 value가 없기 때문에 global 의 value 를 참조합니다.
  console.log(value);

  function innerFunc() {
    // 이때도 마찬가지로 local에 value가 없기 때문에 global 의 value 를 참조합니다.
    console.log(value);
    // innerValue 라는 지역 변수 선언합니다.
    var innerValue = "local";
  }
  innerFunc();
}
outFunc();
// error: innerValue is not defined
// 외부에서 내부 스코프의 값을 참조할 수 없습니다. global 에서는 innerValue가 선언된 줄도 모르고 있습니다.
console.log(innerValue);

그렇다면 이런 경우는 어떨까요?

var value = "global";

function func() {
  value = "local";
  console.log(value); // local
}

func();
console.log(value); // local

위의 경우 func 내부에서 선언된 value 를 보면 var value 로 새로운 변수를 만들 것이 아니라 기존의 value 의 값을 변경하고 있습니다. var가 생략된 경우 자바스크립트는 value를 전역 변수로 판단 및 생성 또는 수정을 합니다. func 내부에서 value 를 전역변수로 생성하려고보니 글로벌에 스코프에 이미 value 가 존재 하고있습니다. 그래서 value의 값을 바꿔버린 것이지요. 그래서 local 이 된 것 입니다. 전역변수를 사용을 조심하여야 될 이유중 하나입니다. 여러곳에서 같은 전역변수를 사용하게 되면 위와 같이 변수의 값을 맘대로 바꿔버릴 수 있습니다.

let, const

var 는 function scope 입니다. let 과 const 는 block scope 입니다.

let foo = 'a'; 

{
  let foo = 'b'; 
}

console.log(foo) // a

중복선언 금지

var foo = 'a';
var foo = 'a';  

let bar = 'a';
let bar = 'a'; // error  

const foo = 'a'
foo = 'b' // error

Last updated