스코프(Scope)는 '범위'를 의미합니다. 자바스크립트에서는 변수 접근 규칙에 따른 변수의 유효범위로 사용됩니다. 또는 식별자(변수)를 찾기 위한 규칙이라고도 합니다.
변수에는 접근할 수 있는 범위가 존재합니다. 중괄호({ }
)에 의해 범위가 나누어지고 이 범위를 스코프라고 부릅니다. function을 제외하고 { }
로 묶이는 부분을 블록 스코프라고 합니다.
바깥 쪽 스코프에서 선언한 변수는 안 쪽 스코프에서 사용할 수 있지만 반대로 안 쪽에서 선언한 변수는 바깥 쪽 스코프에서는 사용할 수 없습니다.
🎀 vs. 내부함수는 자신을 포함한 외부함수, 전역변수에 접근할 수 있습니다. 따라서 함수 내부에서 전역변수의 값도 변경할 수 있습니다.(화살표 방향이 바뀌었을 뿐 사실상 같은 내용 입니다.)
function 키워드가 등장하는 함수선언식(혹은 함수표현식)은 함수 스코프를 만듭니다.
var
을 이용한 변수선언은 블록스코프를 무시하고 함수스코프만 따릅니다. (다만 화살표 함수의 블록 스코프는 무시하지 않습니다) 즉 var
이 함수 내에서 선언된 경우에만 함수를 빠져나오지 못하고, 다른 곳에서 선언이 되었다면 어디에서든 쓰일 수 있습니다.
var
선언은 함수스코프 최상단에 선언됩니다. 선언 키워드 없는 선언은 최고 스코프에 선언됩니다. 함수 내에서 선언 키워드 없는 선언은 함수 실행 전까지 선언 되지 않은 것으로 취급합니다.
중괄호({ }
) 기준으로 범위가 구분됩니다. 자바스크립트에서 변수를 선언하는 기호 중 let
은 블록스코프 입니다.
블록 스코프 안에서 정의된 변수는 블록 범위를 벗어나는 즉시 접근할 수 없습니다. 범위 밖에서 호출시 ReferenceError
가 납니다.
블록은 시각적으로 들여쓰기가 적용되면서 분명하게 구분됩니다.
var
선언은 시각적으로 들여쓰기되는 규칙을 무시하므로 시각적으로 명확하지 않습니다. 따라서 예측가능한 코드작성을 위해 let
키워드로 선언하는 것을 권장합니다. 또한 let
키워드는 재선언을 방지합니다.
const
키워드는 변하지 않는 값, 즉 상수(constant)를 정의할 때 이용합니다. 재할당이 불가능하고, 재할당할 경우 TypeError
를 내므로, 의도하지 않은 값의 변경을 막을 수 있습니다.
🎀 렉시컬 스코프(Lexical scope)
어휘적인 범위 지정을 의미합니다. 함수의 상위 스코프를 결정하는 방식으로, 어디서 선언하였는 지에 따라 상위 스코프를 결정하는 것입니다. 대부분의 프로그래밍 언어는 렉시컬 스코프를 따릅니다.🎀 vs. 동적 스코프(Dynamic scope)
함수를 어디서 호출하였는 지에 따라 상위 스코프를 결정하는 방식입니다.
브라우저에는 window라는 객체가 존재합니다.브라우저 창을 의미하는 객체이지만, 별개로 전역 영역을 담고 있습니다. 함수선언식으로 함수를 선언하거나, var로 전역변수를 만들면 window객체에서도 찾을 수 있습니다.
🎀 전역객체
전역 범위(global scope)에 항상 존재하는 객체를 의미합니다. 언어 자체나 호스트 환경에 내장되어 있는 경우가 많습니다. 브라우저에선 window 객체가 있습니다. 전역 객체를 사용하면 어디서든 접근 가능한 변수를 만들 수 있습니다.window.함수()
로 전역함수로 호출하면 내부적으로 window 객체를 사용해 호출됩니다.
전역변수는 어디서든 접근이 가능합니다. 전역변수를 많이 만들면 내가 작성하지 않은 다른 함수와 로직이 포함될 때 같은 이름으로 선언된 전역변수에서 문제가 발생하게 됩니다(이름이 중복될 수 있기 때문입니다). 의도치 않은 재할당에 의한 상태 변화로 코드를 예측하기 어렵게 만듭니다. 이를 side effect라고 하고, 최소화 하는 것이 바람직합니다.
🎀 스코프 오염(Scope Pollution)
전역 네임스페이스에 너무 많은 전역변수가 존재하거나, 다른 범위에서 변수를 재사용하는 상황을 말합니다. 즉, 선언된 변수가 너무 다양해서 기억하고 추적하기 어려워 다른 로컬 변수와 충돌하는 등의 다양한 오류를 만들어 냅니다.
전역변수를 var
로 선언하는 것은 브라우저의 내장 기능을 사용하지 못하게 만들 수도 있습니다. 또한 선언 없이 변수를 할당하면, 해당 변수는 var
로 선언한 전역변수처럼 취급됩니다. 두 경우 모두 바람직 하지 않습니다.
strict Mode는 브라우저가 엄격하게 작동하도록 만들어 위의 위험을 방지해줍니다. 선언 없는 변수를 할당할 경우 Strict Mode는 에러로 판단합니다.js파일 상단에 'use strict'라고 입력하면 Strict Mode가 작동합니다.
블록 스코프를 잘 사용해, 변수의 사용범위를 엄격하게 제한하여 스코프 오염을 방지해야 합니다. 이 경우 다양한 이점이 있습니다.