Javascript - Scope

YoungWoo·2021년 3월 19일
0

JS

목록 보기
2/2

Scope

모든 식별자(변수 이름 , 함수 이름 , 클래스 이름 등)는 자신이 선언된 위치에 의해 다은 코드가 식별자 자신을 참조할 수 있는 유효범위가 결정된다. 이를 Scope라고 한다.
즉 Scope는 식별자가 유효한 범위를 말한다.

코드가 어디서 실행되며 주변에 어떤 코드가 있는지 를 우리는 랙시컬 환경이라고 한다. 즉, 코드의 문맥은 랙시컬 환경으로 이루어진다.

Global & Local

스코프는 global과 local로 구분된다.

  • Global : 코드의 가장 바깥영역을 의미한다.
  • Local : 함수 몸체 내부를 의미한다.

이때 변수는 자신이 선언된 위치에 따라 유효한 스코프가 결정된다.
즉 전역변수는 전역 스코프를 가지고 , 지역에서 선언된 변수는 지역 스코프를 가진다.
그리고 전역변수는 어디에서든지 참조가 가능하다.
하지만 지역 변수는 선언된 지역에서만 참조가 가능하다.

Scope Chain

모든 스코프는 하나의 계층적 구조로 연결되며, 모든 지역 스코프의 최상위 스코프는 전역 스코프이다. 이렇게 스코프가 계층적으로 연결된것을 Scope Chain 이라고 한다.
변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색한다.

Function level Scope

var 키워드로 선언된 변수는 오로지 코드 블록(함수 내부)만을 지역 스코프로 인정하는데 이를 함수 레벨 스코프라고 한다.

전역변수의 문제점

  • 암묵적 결합
    전역변수는 말그대로 전역에서 사용할 수 있는 변수이다. 그래서 모든 코드가 의도하지 않았지만 전역변수를 참조하고 변경할 수 있는 암묵적 결합이 발생할 가능성이 있다.

  • 생명 주기
    전역변수는 생명주기가 길다. 따라서 메모리 리소스를 오랜 기간 소비한다. 상태를 변경할 시간과 기회도 많다. 하지만 지역변수는 생명주기도 짧고 상태를 변경할 시간도 짧다.

  • Scope chain상 종점에 존재
    전역변수는 변수를 검색할때 가장 마지막에 검색된다. 즉 전역변수의 검색속도가 가장 느리다.

  • 네임스페이스 오염
    자바스크립트의 가장 큰 문제점은 파일이 분리되어 있어도 하나의 전역 스코프를 공유한다는 것이다. 그래서 다른 파일에서의 지역변수나 전역변수가 동일한 이름으로 존재할 경우 예상하지 못한 결과가 발생할 수 있다.

전역함수 사용 억제

전역함수를 반드시 사용해야 할 이유를 찾지 못한다면 지역변수를 사용해야 한다. 변수의 스코프는 좁을수록 좋다.

var 키워드로 선언한 변수의 문제점

중복선언

var 키워드로 선언한 변수는 중복 선언이 가능하다. 그래서 먼저 선언된지 모르고 중복하여 변수를 선언한다면 변수의 값이 변경되는 부작용이 발생한다.

var x = 1;
var y = 1;

var x =100;
var y; // 초기화 없는 변수 선언은 무시된다.

console.log(x); //100
console.log(y); //1

함수 레벨 스코프

var 키워드로 선언한 변수는 오직 함수 내부코드 블록만을 지역 스코프로 취급하고 외부의 코드블록은 지역 스코프로 취급하지 않아서 그 안에 있는 코드들도 전부 전역 스코프로 본다.

var i = 10;

for (var i = 0; i < 5; i++) {
  console.log(i); // 0 1 2 3 4
}

console.log(i); //5

위의 예제처럼 for문 속의 i 변수도 이전에 선언된 전역변수인 var i = 10과 같은 스코프에 있어
i의 값이 최종적으로는 5가 되어 버렸다.

let 키워드

그래서 ES6에서 생겨난 키워드가 바로 let 키워드이다. 이제 var과 let이 어떠한 차이가 있는지 알아보자.

변수 중복 금지

let은 똑같은 이름의 변수를 중복으로 선언하는것을 금지한다.

블록 레벨 스코프

var과는 다르게 if, while , for , try/catch 문 안을 지역스코프로 인정한다.

let foo = 1;

{
  let foo = 2;
  let bar = 3;
}

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

전역변수 var과 차이점

var 전역함수 및 변수는 전역 객체 windows의 프로퍼티가 된다. 그리고 let은 그렇지 않다.

let x = 1;

console.log(windwos.x); // undefined
consoel.log(x); //1

const 키워드

const 키워드는 상수를 선언하기 위한 키워드인데 let과 유사한 점이 많아서 다른점 위주로 살펴보겠다.

선언과 초기화

우선 const로 변수를 선언하기 위해서는 반드시 선언과 동시에 초기화를 해야한다.

const foo = 1;
const foo; // SyntaxError: Missing initializer in const declaration 

재할당 금지

목적이 상수를 선언하기 위함이라 값을 다시 설정하는것은 금지된다.

const foo = 1;
foo = 2; // TypeError: Assignment to consistant variable

객체에서의 const

const 키워드로 선언된 변수에 객체를 할당한 경우 값을 변경할 수 있다.

const person = {
  name : 'Lee'
};

person.name = 'Jang';

console.log(person.name); // 'Jang'

정리

  • ES6를 사용하면 var의 사용은 추천하지 않음
  • 재할당이 필요한 경우에 한정 let 키워드를 사용하라
  • 변경이 필요 않은 값은 const 키워드를 사용하라.
profile
too rare to die too weird to live

0개의 댓글