Scope(유효 범위) : 해당 변수가 사용될 수 있는 범위

  • Global Scope(전역 스코프) : 어디에서든 참조 가능
  • Local Scope / Function-level scope(지역 스코프) : 함수 코드 블록이 만든 스코프로 함수 자신과 하위 함수에서만 참조 가능

모든 변수는 스코프를 갖는다.

  • Global variable(전역 변수) : 전역에서 선언된 변수이며 어디에서든 참조 가능
  • Local variable(지역 변수) : 지역(함수)내에서 선언된 변수이며 그 지역과 지역의 하위 지역에서만 참조 가능

Function Scope(function-level scope)

함수 코드 블록 내에서 선언된 변수는 함수 코드 블록 내에서만 유효하고 함수 외부에서는 유효하지 않다.

1
2
3
4
5
6
7
8
9
10
11
var a = 1;

function foo () {
var b = 2;

console.log(a); // 1
console.log(b); // 2
}

foo();
console.log(b); // ReferenceError: b is not defined

스코프는 내부에서 외부를 접근할수 있지만 외부에서 내부의 접근이 불가능하다

1
2
3
4
5
6
7
8
9
var a = 1;

function foo () {
var a = 2;
console.log(a); // 2
}

foo(); // 2
console.log(a); // 1
1
2
3
4
5
6
7
8
9
10
11
function foo () {
var a = 10;

for (var i = 0; i < a; i++) {
console.log(i); // 0 ~ 9까지
}

console.log(i); // 10
}

foo();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var x = 'global';

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

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

bar();
}

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

내부함수는 자신을 포함하고 있는 외부함수의 변수에 접근할 수 있다. closure: 함수가 접근할수 있는 범위의 정보들을 기억하고 접근 및 사용할수 있는 현상

Block Scope

ES6에서 도입된 let, const 키워드를 사용하면 Block-level scope를 사용할 수 있다. 함수 뿐만 아니라 모든 블록은 범위가 된다.

1
2
3
4
5
6
7
8
function myFunc() {  
let name = 'Luke'
console.log(name); // 'Luke'
}

myFunc();

console.log(name); // name is not defined
1
2
3
4
5
if(true) {  
let name = 'Luke'
}

console.log(name); // name is not defined

Lexical Scope

함수를 어디서 호출하는지가 아니라 어디에 선언 하였는지에 따라 결정

  • 프로그래밍 언어의 함수 상위 스코프 결정 방식

    • Dynamic Scope (동적 스코프) : 함수를 어디서 호출하였는지에 따라

    • Lexical Scope (= Static Scope: 정적 스코프) : 함수를 어디에 선언하였는지에 따라

      => 자바스크립트를 비롯한 대부분의 프로그래밍 언어는 렉시컬 스코프를 따른다.

1
2
3
4
5
6
7
8
9
10
11
12
13
var x = 1;

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

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

foo(); // ?
bar(); // ?

함수를 선언한 시점에 상위 스코프가 결정되므로 전역에 선언된 bar함수의 상위 스코프는 전역 스코프이고 위 예제는 전역 변수 x의 값인 1을 두 번 출력한다.

Hoisting

var를 이용해 만들어진 변수의 선언문을 유효한 함수 범위의 최상단으로 끌어올리는 행위

  • function declaration (함수 선언식) : hoisting 가능
  • function expression (함수 표현식) : hoisting 불가능
1
2
3
4
5
6
7
8
9
10
11
12
13
console.log(a); // undefined

var a = 1;
// var a : 변수를 만들고 선언
// = 1 : 변수에 할당

console.log(a); // 1

foo();

function foo () {
console.log(a); // 1
}
  • 함수 선언식

    1
    2
    3
    4
    5
    6
    7
    j(); // 'j'

    function j () {
    console.log('j');
    }

    j();
  • 함수 표현식

    1
    2
    3
    4
    5
    6
    7
    d(); // Uncaught TypeError: d is not a function

    var d = function () {
    console.log('I am inside function d');
    }

    d();