javascript - core - 스코프

yj k·2023년 4월 15일

javascript

목록 보기
8/18

scope

01. scope

01_global-and-local-scope(전역과 지역 스코프)

전역과 지역 스코프

전역 : 코드의 가장 바깥 영역을 말하며 전역은 '전역 스코프'를 만든다.
전역에 변수를 선언하면 전역 스코프를 갖는 전역 변수가 되며 전역 변수는 어디서든 참조 가능하다.

지역 : 함수 내부 몸체를 말하며 지역은 '지역 스코프'를 만든다.
지역에 변수를 선언하면 지역 스코프를 갖는 지역 변수가 되며, 자신의 지역 스코프와 하위 지역 스코프에서 유효하다.


var 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(y);     // global y
console.log(z);     // ReferenceError: z is not defined
// 하위 스코프에서 유효한 변수는 상위 스코프에서 참조 불가능



스코프 체인
전역 스코프 (x, y, outer) <- outer 지역 스코프 (z, inner) <- inner 지역 스코프 (x)
자바스크립트 엔진은 변수를 참조할 때 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여
상위 스코프 방향으로 이동하며 선언된 변수를 검색한다.
=> 상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조 가능, 하위 스코프에서 유효한 변수는 상위 스코프에서 참조 불가능




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

함수 레벨 스코프
C, Java 등 대부분의 프로그래밍 언어는 함수 몸체만이 아니라 모든 코드 블록(if, for, while, try/catch 등)이 지역 스코프를 만드는 "블록 레벨 스코프"를 가진다.
var키워드로 선언 된 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정하는 "함수 레벨 스코프"를 가진다.


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

// 전역 변수로 이미 선언 된 i가 중복 선언 된다.
for(var i = 0; i < 10; i++) {}

// for 코드 블럭 내부의 값 변화가 반영된다. 
console.log(i);




01. let-and-const

01_var

var의 문제점
ES5까지 변수를 선언할 수 있는 유일한 방법은 var 키워드를 사용하는 것이었는데 이는 몇가지 문제를 유발한다.

// 1. 변수 중복 선언
var msg = "안녕하세요";
console.log(msg);		//출력 : 안녕하세요
// var 키워드로 선언 된 변수는 같은 스코프 내에서 중복 선언이 허용 된다.
// 초기화 문이 있는 변수 선언문은 자바스크립트 엔진에 의해 var 키워드가 없는 것처럼 동작한다.
var msg = "안녕히가세요";		//출력 : 안녕히가세요
console.log(msg);
// 초기화 문이 없는 변수 선언문은 무시 된다.
var msg;
console.log(msg);	//출력 : 안녕히가세요

// 2. 함수 레벨 스코프
// 함수 외부에서 var 키워드로 선언한 변수는 코드 블록 내에서 선언해도 모두 전역 변수가 된다.
var i = 0;
for(var i = 0; i < 10; i++) {}
console.log(i);

// 3. 변수 호이스팅
// 변수 선언문이 스코프의 선두로 끌어올려진 것 처럼 동작한다.
// 변수 선언문 이전에 참조 할 수 있다.
console.log(test);	// 출력 : undefined
test = "반갑습니다";
console.log(test);	// 출력 : 반갑습니다.
var test;




02_let

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

let : 선언, 초기화 분리되어 동작
var : 선언, 초기화 동시

// 1. 변수 중복 선언 금지
let msg = "안녕하세요";
// 같은 스코프 내에서 중복 선언을 허용하지 않는다.
// let msg = "안녕히가세요";

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

// 3. 변수 호이스팅
// 변수 호이스팅이 발생하지 않은 것처럼 동작한다.
// var : 선언, 초기화 동시
// let : 선언, 초기화 분리되어 동작, 초기화되기 전에 사용이 불가능

console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x;

03_const

let 키워드에서 알아본 특징은 모두 동일하며
상수(const) 선언에서 사용 된다는 점이 특징이다.

const : 선언과 동시에 초기화 해야한다.
let : 선언, 초기화 분리되어 동작
var : 선언, 초기화 동시

  1. const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화 해야 한다.
  2. const 키워드로 선언한 변수는 재할당 금지
  3. 일반적으로 상수의 이름은 대문자로 선언해 상수임을 나타내며, 여러 단어로 이루어진 경우 _(언더스코어)로 구분해서 스네이크 케이스로 표현하는 것이 일반적이다.
  4. const 키워드로 선언 된 변수에 객체를 할당한 경우 프로퍼티 값을 변경할 수 있다.
  5. 객체 재할당은 불가능하다.
//const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화 해야 한다
// const x;
const x = 1;

// const 키워드로 선언한 변수는 재할당 금지
// x = 2; TypeError: Assignment to constant variable.

// 일반적으로 상수의 이름은 대문자로 선언해 상수임을 나타내며, 여러 단어로 이루어진 경우
// _(언더스코어)로 구분해서 스네이크 케이스로 표현하는 것이 일반적이다.
const DISCOUNT_RATE = 0.15;

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

student.name = '유관순';
console.log(student);

// 객체 재할당은 불가능하다.
// student = {}; TypeError: Assignment to constant variable.

0개의 댓글