프로그래밍/JavaScript

08_자바스크립트 : scope ( 스코프체인, const, let, 함수 레벨 스코프)

pupu91 2022. 7. 28. 17:24
반응형

 

 

1. 전역과 지역 스코프

 

전역

:  코드의 가장 바깥 영역을 

- 전역은 전역 스코프를 만듦

- 전역에 변수를 선언하면 어디서든지 참조 가능

 

지역

: 함수 몸체 내부

- 지역은 지역 스코프를 만듦

- 지역에 변수를 선언하면 자심의 지역 스코프와 하위 지역 스코프에서 참조 가능

 

 

ar x = 'global x';
var y = 'global y';

function outer() {
    var z = "outer's local z";

    console.log(x);             
    => global x
    console.log(y);             
    => global y
    console.log(z);             
    => outer's local z

    function inner() {
        var x = "inner's local x";

        console.log(x);         
        => inner's local x 
        console.log(y);         
        => global y
        console.log(z);         
        => outer's local z
    }

    inner();
}

outer();

console.log(x);                
=> global x
console.log(z);             
=> ReferenceError: z is not defined

 

 

 

 

2. 스코프 체인

 

- 변수를 참조할 때 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여
상위 스코프 방향으로 이동하며 선언된 변수를 검색

=> 상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조할 수 있지만
   하위 스코프에서 유효한 변수를 상위 스코프에서 참조할 수 없음

 

 

 

3. 함수 레벨 스코프

- 함수 몸체만이 아니라 모든 코드 블록(if, for, while, try/catch 등)이 지역 스코프를 만드는 블록 레벨 스코프를 가짐

- var 키워드로 선언된 변수는 오로지 함수의 코드 블록(함수 몸체)만을 지역 스코프로 인정하는 함수 레벨 스코프를 가짐

 

var i = 0;
=> i는 전역 변수


for(var i = 0; i < 10; i++) {}
=> for 코드 블록 내부에서 i라는 변수를 선언
이는 전역 변수로 이미 선언 된 전역 변수 i가 있어 중복 선언임

때문에 의도와 달리 for 코드 블록 내부에서의 값 변화가 반영된다.
console.log(i);
=> 10

 

 

반응형

4. var

- var 키워드로 선언 된 변수는 같은 스코프 내에서 중복 선언이 허용

- 함수 외부에서 var 키워드로 선언한 변수는 코드 블록 내에서 선언해도 모두 전역 변수

- var 키워드로 변수를 선언하면 변수 호이스팅에 의해 변수 선언문이 스코프의 선두로 끌어올려진 것처럼 동작

 

 

 

5. let

- var의 문제점을 보완하기 위해 ES6에서는 새로운 변수 선언 키워드인 let, const를 도입

(1) 변수 중복 선언 금지
let msg = '안녕하세요';

(x) let msg = '안녕히가세요';
=> 같은 스코프 내에서 중복 선언 허용(x)

(2) 블록 레벨 스코프
모든 코드 블록을 지역 스코프로 인정
let i = 0;
for(let i = 0; i < 3; i++) {
    console.log(`지역 변수 i : ${i}`);
    => 지역 변수 i : 0
       지역 변수 i : 1
       지역 변수 i : 2
}
console.log(`전역 변수 i : ${i}`);
=> 전역 변수 i : 0

(3) 변수 호이스팅
변수 호이스팅이 발생하지 않은 것 처럼 동작
let은 선언과 초기화가 분리 되어 진행되므로 선언은 되었지만 초기화가 되지 않아 참조 시 오류가 발생
// console.log(x); //ReferenceError: Cannot access 'x' before initialization
let x;

 

 

 

6. const

- let 키워드와 마찬가지로 블록 레벨 스코프를 가지며 변수 호이스팅이 발생하지 않는 것처럼 동작

- 상수(constant) 선언에 사용

- const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화해야 함

- onst 키워드로 선언한 변수는 재할당이 금지

(1) 선언과 동시 초기화
const x = 1; 

(2) 재할당 금지
x = 2; 

(3) 대문자로 선언
const DISCOUNT_RATE = 0.15;

let price = 15000;
let discountPrice = price * (1 - DISCOUNT_RATE);
console.log(discountPrice);
=> 12750

(4) const 키워드로 선언 된 변수에 객체를 할당한 경우 프로퍼티 값을 변경가능
const student = {
    name : '홍길동',
    age : 20
};

student.name = '아무개';
console.log(student);
=> { name: '아무개', age: 20 }

 

정리

ES6를 사용한다면 var 키워드는 사용하지 않는다. 재할당이 필요한 경우에 한정해 let 키워드를 사용하며 변수의 스코프는 최대한 좁게 만든다. 변경이 발생하지 않고 읽기 전용으로 사용하는 원시 값과 객체에는 const 키워드를 사용한다. const 키워드는 재할당을 금지하므로 var, let 키워드보다 안전한다.

반응형