요약
1. 스코프는 변와 함수의 유효범위이다.
2. 코드 내에서 변수와 함수의 이름이 충돌하지 않도록 도와준다.
3. 스코프에는 프로그램 전체에서 접근 가능한 전역 스코프와 해당 코드블록이나 함수 내부에서만 접근가능한 지역스코프 두가지 유형이 있다.
설명
스코프란?
식별자의 유효 범위입니다. 모든 변수, 함수, 클래스 등의 이름을 의미하는 식별자는 자신이 선언된 위치에 의해 다른 코드가 자신을 참조할 수 있는지에 대한 범위가 결정됩니다.
왜 필요한가요?
식별자는 어떤 값을 식별할 수 있는 고유한 이름으로 하나의 값은 유일한 식별자와 연결되어야 합니다.
스코프가 없다면, 즉 유효범위가 없다면
매번 새로운 식별자를 만들어야하는 번거로움이 있고
까먹고 앞서 사용한 식별자를 사용시 충돌이 일어날 수 있습니다.
이러한 이유로 스코프는 꼭 필요합니다.
스코프에는 두가지 종류가 있습니다.
var globalVar = "I'm in the global scope";
function printGlobalVar() {
console.log(globalVar); // 전역 변수에 접근 가능
}
printGlobalVar();
console.log(globalVar); // 전역 변수에 접근 가능
1. 코드 어디서든 참조 가능한 전역스코프
function localScopeExample() {
var localVar = "I'm in a local scope";
console.log(localVar); // 지역 변수에 접근 가능
}
// console.log(localVar); // 에러! 지역 변수에 접근 불가능
localScopeExample();
2. 함수 내부에서만 참조가능한 지역스코프
자바스크립트의 스코프는 함수 레벨 스코프를 따릅니다.
보통 다른 언어들은 블록 레벨 스코프를 따르지만 자바스크립트는 함수 레벨 스코프를 따릅니다.
블록 레벨 스코프는 코드블록(try,catc문, if문, for문 등) 내에서의 변수는 지역스코프를 생성합니다.
반면에 함수레벨 스코프는 함수의 코드블록에서만 지역스코프가 생성됩니다.
var 키워드로 선언된 변수는 함수 레벨 스코프를 가지며
ES6 부터 도입된 let, const 키워드로 선언된 변수는 블록 레벨 스코프를 지원합니다.
블록 레벨 스코프 예시
if (true) {
var blockVar = "I'm in a block scope (ES5)";
}
console.log(blockVar);
// "I'm in a block scope (ES5)" 출력 (ES5의 var는 함수 스코프를 따름)
// 즉 코드 블록 외부에서도 변수 접근 가능
if (true) {
let blockLet = "I'm in a block scope (ES6+)";
const blockConst = "I'm also in a block scope (ES6+)";
}
// console.log(blockLet); // 에러! 블록 스코프 변수에 접근 불가능
// console.log(blockConst); // 에러! 블록 스코프 변수에 접근 불가능
// 블록 스코프 변수는 ES6에서 도입된 let이나 const를 사용해야만 정확한 블록 스코프를 갖게 됩니다.
함수 레벨 스코프 예시
function functionScopeExample() {
var functionVar = "I'm in a function scope";
}
functionScopeExample();
// console.log(functionVar); // 에러! 함수 스코프 변수에 접근 불가능
렉시컬 스코프란 무엇인가요?
정적 스코프라고도 하며 변수의 선언위치에 따라 스코프가 결정되는 방식을 의미합니다.
렉시컬 스코프의 원리는 함수의 중첩 구조에 기반합니다.
함수 내부에서 선언된 변수는 해당 함수 내부에서만 유효하며
외부 함수나 전역 스코프에서는 해당 변수에 직접 접근 할 수 없습니다.
그러나 내부 함수는 외부 함수의 변수에 접근 할 수 있습니다.
왜냐하면 inner 함수가 정의된 위치에서 주변환경인 outerVar의 값(렉시컬스코프)을 기억하기 때문입니다.
function outer() {
const outerVar = 'I am from outer';
function inner() { //inner 함수가 선언되었을 때 상위 스코프를 기억한다.
const innerVar = 'I am from inner';
console.log(innerVar); // 내부 함수에서 innerVar에 접근 가능
console.log(outerVar); // 내부 함수에서 outerVar에 접근 가능
}
inner();
console.log(innerVar);
// 오류: innerVar는 inner함수의 스코프 내에서만 유효하기 때문에 오류
console.log(outerVar);
// 외부 함수에서 outerVar에 접근 가능
}
outer();
어디서든 접근할 수 있는 전역 변수만 사용한다면 문제점은?
1. 스코프가 없는 것과 마찬가지로 유효범위가 크므로 코드 가독성이 나빠지고 의도치 않은 상태 변경 위험이 있습니다.
2. 긴 생명 주기를 가지므로 메모리 리소스 소비기간이 길어집니다.
3. 변수의 값을 찾기 위한 속도가 느립니다. 스코프는 자바스크립트 엔진이 변수의 값을 검색하기 위해 사용합니다. 그 중 전역 변수는 가장 마지막에 검색되어 전역 변수의 검색속도가 가장 느립니다.
'JavaScript' 카테고리의 다른 글
모듈(Module) (0) | 2023.09.01 |
---|---|
클로저 (Closure) (0) | 2023.08.30 |
[JS] 호이스팅 (0) | 2023.04.23 |
UI/UX (2) | 2023.04.13 |
CORS (0) | 2023.04.04 |