스코프(Scope)

- 변수에 접근할 수 있는 범위

스코프 종류

전역 스코프(Global scope)

- 코드 어디에서든 참조 가능

지역 스코프(Local scope)

- 함수 코드 블록 안에서 만든 스코프로 함수 자신과 자식 함수에서만 참조 가능

    var global = '전역 스코프';
    function test() {
        var local = "지역 스코프";
        console.log(`${local} 호출`)
    }
    
    console.log(`${global} 호출`); // (1) 전역 스코프 호출
    console.log(`${local} 호출`) // (2) local is not defined
    test() // (3) 지역 스코프 호출
             // 지역 스코프는 함수 내부에서 접근 가능하다
            // (2)과 같이 지역 스코프는 함수 외부에서 접근 불가능하다.

자바스크립트 스코프 특징

블록 레벨 스코프(block-level scope)

- 코드 블록( {...} )내에서 접근 가능한 스코프(조건문, 반복문, while, try/catch 등)

- 자바스크립트를 제외한 타 언어(C언어, Java언어)들은 블록 레벨 스코프를 따른다.

- 단 ES6에서 도입된 let keyword는 블록 레벨 스코프를 따른다.

    // 블록 레벨 스코프 예제
    
    // (1) 블록 코드 안에서 변수 선언
    {
        var a = 100;
    }
    // (2) 반복문 코드 안에서 변수 선언
    for(var i=0; i<10; i++) {
        
    }
    
    console.log(a); // 100
    console.log(i); // 10

(1), (2) 과 같이 변수를 블록 내부에서 선언하여 타 언어에 경우에는 블록 레벨 스코프에서만 접근이 가능하지만

자바스크립트는 함수 레벨 스코프를 따르기 때문에 블록 외부에서 접근이 가능하다.

함수 레벨 스코프(function-level-scope)

- 함수 코드 블록 내에서 선언된 변수는 함수 내부에서만 접근 가능하고 외부에서는 접근 불가능하다.

- 자바스크립트는 함수 레벨 스코프를 따른다.

1. 기본 예제)

    var a = 10;
    function test() {
        var b = 20;
    }
    
    console.log(a) // 10
    console.log(b) // b is not defined

2. 참조 순위 예제)

    // a변수 스코프 범위
    // 전역 > 부모 함수 > 지역 함수
    // 이 중에서 중복 a변수를 호출하면 가까운 곳에서 참조한다 (단 함수 외부에서 호출할 경우 전역변수를 참조)
    
    // (1) 부모 함수에서 a변수를 호출하면 전역 변수가 아닌 부모함수에서 선언한 a를 참조
    // (2) 자식 함수에서 a변수를 호출하면 가장 가까운 스코프를 참조 하기 때문에 부모함수에서 선언한 a를 참조
    // (3) 함수 레벨 스코프 특성으로 부모함수에서 선언한 변수를 참조하지 못하고 전역변수를 참조
    
    var a = 'global';
    
    function outer() {
        var a = 'local';
        console.log(a); // (1) local
        
        function inner() {
            console.log(a); // (2) local
        }
        
        inner();
    }
    
    outer();
    console.log(a); // (3) global

3. 변수값 변경 예제)

    // 함수 영역에서 전역변수를 참조 할 수있어서 값 변경이 가능하다
    // 또한 자식 함수에서도 부모 함수 or 전역 변수를 참조하여 변경이 가능하다
    
    var a = '전역';
    
    function outer() {
        console.log(a) // (1) 전역
        a = '부모 함수';
        console.log(a); // (2) 부모 함수
        
        function inner() {
            a = '자식 함수';
            console.log(a); // (3) 자식 함수
        }
        
        inner();
    }
    
    outer();
    console.log(a); // (4) 자식 함수

let vs var 스코프 차이점

- let : 블록 레벨 스코프를 따른다.

- var : 함수 레벨 스코프를 따른다.

    // var는 함수 레벨 스코프를 따르기 때문에 {} 안에 변수를 선언했지만 {} 외부에서 접근 가능
    // let은 블록 레벨 스코프를 따르기 때문에 {} 안에 변수를 선언하면 {} 외부에서 접근 불가능
    
    var a = 1;
    {
        var a = 2;
        console.log(a); // 2
    }
    
    let b = 10;
    {
        let b = 20;
        let c = 30;
        console.log(b); // 20
        console.log(c); // 30
    }
    
    console.log(a); // 2
    console.log(b); // 10
    console.log(c); // c is not defined

렉시컬 스코프

- 함수를 어디서 호출하였는지가 아니라 어디에 선언하였는지에 따라 상위 스코프가 결정된다.

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

    // 1번의 경우 aaa함수가 부모함수 인것처럼 보이지만 bbb의 상위 스코프는 전역 스코프이므로 전역변수 1을 출력한다.
    // 2번의 경우 상위 스코프인 전역 변수 1을 출력한다.
    
    var a = 1;
    
    function aaa() {
        var a = 10;
        bbb();
    }
    
    function bbb() {
        console.log(a);
    }
    
    aaa(); // (1) 1
    bbb(); // (2) 1

'Javascript' 카테고리의 다른 글

[Javascript] 실행 컨텍스트  (0) 2021.07.20
[Javascript] this  (0) 2021.07.09
[Javascript] 프로토타입(Prototype)  (0) 2021.07.07
[Javascript] 호이스팅  (0) 2021.07.03
[Javascript] 함수(function)  (0) 2021.06.30

+ Recent posts