JS - 스코프

Lee Ju-Hyeon(David)·2021년 9월 18일
0

Java Script

목록 보기
5/8
post-thumbnail

변수와 매개변수, 함수 등의 생존기간을 정하여 유효범위를 결정하는 것을 의미한다. 예를 들어 특정 변수는 유효범위를 넘어서면 참조될 수 없다.

1. JS의 Scope

Global scope

var global = 'global';

function foo() {
  var local = 'local';
  console.log(global); // global
  console.log(local); // local
}
foo();

console.log(global); // global
console.log(local); // local is not defined

JS에서는 코드가 나타나는 즉시 해석되어 특정 스코프 내에서 선언되지 않으면 모두 전역 스코프의 특징을 가지게 된다.

Block-level / Non block-level scope

JS는 기본적으로 Non block-level scope를 가지고 있다.

var x = 0;
{
  var x = 1;
  console.log(x); // 1
}
console.log(x);   // 1

let y = 0;
{
  let y = 1;
  console.log(y); // 1
}
console.log(y);   // 0

블록 레벨 스코프를 갖는다면 변수 x는 블록 외부와 내부의 값이 다를 것이다. 하지만 JS에서는 블록 레벨 스코프를 갖지 않기 때문에 위 코드와 같은 결과가 나타난다. 따라서 ECMAScript 6에서 도입된 let을 사용하여 변수를 블록 레벨 스코프로 지정해주는 것이 좋다.

Function-level scope

함수도 {}로 감싸져 있지만, 조건문/ 반복문과는 구분해야 한다. JS에서 조건문/ 반복문는 Non block-level scope를 가지지만, 함수는 Function-level scope를 가진다. 즉, 함수는 Non Block-level scope가 아니다

var x = 'global';

function foo() {
  var x = 'local';
  console.log(x);
}

foo();          // local
console.log(x); // global

만약에 JS의 함수가 조건문이나 반복문과 같이 동작한다면 변수 코드의 출력은

local
local

이 됐을 것이다. 하지만 JS에서 함수는 Function-level scope를 가지기 때문에 함수 안에서의 변수 x와 밖에서의 변수 x는 다른 변수이다.

함수 안에 함수가 중첩되어 존재할 수도 있다. 이 때도, Function-level scope를 철저하게 따른다.

var x = 10;

function foo(){
  var x = 100;
  console.log(x);

  function bar(){   // 내부함수
    x = 1000;
    console.log(x); // 1000
  }

  bar();
}
foo();
console.log(x); // 10
  1. foo함수를 실행하면 먼저 100이 저장된 x를 출력한다.
  2. foo함수 내부의 boo함수를 정의하고 실행한다. boo함수 내부에 x에는 1000이 저장되어 있어 이 함수 내부에서의 x값은 1000이다.
  3. 함수 실행이 종료 되면 x에는 처음에 선언했던 대로 10이 저장되어 있다.

2. 상위 스코프 결정 방식

함수가 중첩되어 있으면 내부 함수는 상위 스코프에 따라 변수 사용이 달라진다. 상위 스코프를 결정하는 방식은 두 가지가 있다.

  1. 함수가 호출된 위치에 따라 결정(동적 스코프)
  2. 함수가 선언된 위치에 따라 결정(렉시컬/정적 스코프)

JS를 비롯한 많은 언어들이 두번째 방법인 렉시컬 스코프를 따른다.

var x = 1;

function foo() {
  var x = 10;
  bar();
}

function bar() {
  console.log(x);
}

foo(); // 1
bar(); // 1

bar함수는 전역에서 선언되었기 때문에 foo함수 내부에서 호출되더라도 x값은 1이다.





참조

0개의 댓글