JavaScript

[JavaScript] 스코프 (Scope)

oagree0123 2021. 9. 8. 11:19

스코프는 번역하면 '범위'라는 뜻을 가지고 있습니다. 이것이 자바스크립트에서 어떠한 것을 의미하는지 알아보겠습니다. : )

 

1. 스코프 (Scope)

스코프는 전역(Global) 스코프과 지역(Local) 스코프 두 가지로 나눌 수 있습니다. 전역 스코프는 어느 곳에서든지 참조할 수 있는 것을 말합니다. 지역 스코프는 정의된 지역(함수) 안에서만 참조될 수 있는 것을 말합니다. 

 

코드를 보고 조금 더 설명하겠습니다.

var a = 'global';

function test() {
    var a = 'local';
    console.log(a);
}

test();         // local
console.log(a); // global

위 코드에서 함수 밖에 선언된 변수 a는 전역 변수이고, 함수 내부에 선언된 변수 a는 지역 변수입니다. 함수 내에서 변수 a에 'local'이라는 값을 대입했어도 함수 밖에서 변수 a는 전역 변수를 참조하는 것을 볼 수 있습니다.

 

2. 함수 스코프

함수 스코프는 ES6이전에 자바스크립트에서 적용되는 스코프입니다. 함수 스코프는 함수 내부에 선언한 변수는 지역 변수이고, 함수 외부에 선언한 함수는 모두 전역 변수입니다.

var name = 'Kim'

{
    var name = 'park';
}

function userCheck() {
    var name = 'Lee';
    var age = '20';
    
    console.log(`name: ${name}, age: ${age}`);
}

userCheck();       // name: Lee, age: 20
console.log(name); // park

위 코드를 보면 함수 내부의 name은 설명한데로 지역 변수인 것을 확인할 수 있지만, {} 안에 있는 변수 name이 전역 변수로 적용되는 것을 볼 수 있습니다.

 

3. 블록 스코프

블록 스코프는 ES6이후 let과 const가 나타나면서 적용되는 스코프입니다. {}의 내부에 선언된 변수는 지역 변수로 취급하는 것을 말합니다. 위의 코드를 조금 바꿔서 한번 살펴보겠습니다.

let name = 'Kim'

{
    let name = 'park';
}

function userCheck() {
    let name = 'Lee';
    let age = '20';
    
    console.log(`name: ${name}, age: ${age}`);
}

userCheck();       // name: Lee, age: 20
console.log(name); // Kim

이전에 var을 사용한 코드에는 'park'으로 변수의 값이 변했지만, let을 사용하면 {}안의 변수는 지역 변수로 적용되어 전역 변수 name의 값이 변경되지 않는 것을 볼 수 있습니다. 

 

4. 렉시컬 스코프

스코프는 함수를 어디서 호출하는지가 중요한 것이 아니라 함수를 선언했을 때 생깁니다. 이번에도 코드를 보고 설명하겠습니다.

let a = 10;

function test() {
    let a = 20;
    print();
}

function print() {
    console.log(a);
}

test();
print();

먼저, 결과를 예상한번 해봅시다. 어떤 결과가 나올꺼라고 생각하셨나요?

정답은, 둘다 10이 나오게 됩니다. 위에서 설명했듯 함수가 선언될 때 스코프가 결정됩니다. print() 함수는 전역에 선언되었기 때문에 전역 변수 a를 참조하여 값을 보여줍니다. 

 

5. 스코프 체인

스코프 체인은 내부 함수에서 변수를 찾고, 변수가 없다면 상위 스코프에서 변수를 다시 찾는 것을 말합니다. 즉, 내부 함수는 외부 함수의 변수를 접근할 수 있지만, 외부 함수는 내부 함수의 변수에 접근할 수 없습니다.

let id = 01;

function ex() {
    console.log(id);
    function in() {
        var innerId = 02;
        console.log(id);
    }
    in();
}

ex();  // 01
console.log(innderId);  / undefined