FrontEnd/JavaScript
Modern JavaScript 스코프
is..cy
2023. 1. 22. 12:50
1. 스코프
- 스코프 : 참조 대상 식별자(identifier) 를 찾아내기 위한 유효범위
- 어디에 선언 되었는지 정해진 범위에 대한 규칙
- 식별자 이름의 충돌을 방지한다.
2. 스코프의 구분
- 전역 스코프 (Global scope) : 코드 어디에서든 참조
- 지역 스코프 (Local scope/ function-level scope) : 함수 코드 블록이 만든 스코프로 자신과 하위함수에만 참조
- 전역 변수 (Global variable) : 어디서든 참조 가능한 변수 (전역에서 선언)
- 지역 변수 (Local variable) : 해당 함수와 하위 지역에서만 참조 (함수 내에서 선언된 변수)
3. 스코프 특징
- 블록 레벨 스코프 (block-level scope) : ({...}) 코드블록 내에서 유효한 스코프 (코드플록 내에서 접근 가능)
- C-family Language
- Javascript : Non block-level scope, 함수 밖에 선언된 변수는 블록 내에 선언되어도 전역스코프임
int main(void) {
// block-level scope
if (1) {
int x = 5;
printf("x = %d\n", x);
}
printf("x = %d\n", x); // use of undeclared identifier 'x'
return 0;
}
- 함수 레벨 스코프 (function-level scope) : 함수 코드내에서만 유효 (함수 외부에서는 유효 x)
- javascript : 시작점이 따로 없어 전역변수를 남용할 가능성이 있다. 할당상태 변화시 예측이 어려우므로 제어가 필요
- 함수 내에서 선언된 매개변수와 변수는 함수 외부에서는 유효하지 않음
var x = 'global';
function foo() {
var x = 'local';
console.log(x);
}
foo(); // local
console.log(x); // global
- 전역변수와 지역변수 변수명이 중복선언 될시, 지역변수를 우선하여 참조
var foo = function ( ) {
var a = 3, b = 5;
var bar = function ( ) {
var b = 7, c = 11;
// 이 시점에서 a는 3, b는 7, c는 11
a += b + c;
// 이 시점에서 a는 21, b는 7, c는 11
};
// 이 시점에서 a는 3, b는 5, c는 not defined
bar( );
// 이 시점에서 a는 21, b는 5
};
- 중첩 스코프는 가장 인접한 지역을 우선하여 참조 : 실행 컨텍스트의 스코프 체인에 의해 참조순위가 변경된다.
- 렉시컬 스코프 (Lexical scope) : 함수를 어디에 선언하였는지에 따라 결정 (javascript)
- 동적 스코프 (Dynamic scope) : 함수를 어디서 선언하였는지에 따라 결정
4. 암묵적 전역 (implicit global)
var x = 10; // 전역 변수
function foo () {
// 선언하지 않은 식별자
y = 20;
console.log(x + y);
}
foo(); // 30
- y가 선언되지 않았지만 마치 선언된것처럼 동작 (선언하지 않은 식별자에 값 할당시 객체의 프로퍼티로 바뀜)
- 전역변수는 delete 연산자로 삭제할 수 없다. (프로퍼티만 가능, delete y)
5. 변수 통제
- 최소한의 전역변수 사용 : 전역 변수 객체를 하나 만들어 사용
var MYAPP = {};
MYAPP.student = {
name: 'Lee',
gender: 'male'
};
console.log(MYAPP.student.name);
- 즉시실행함수(Immediately-Invoked Function)를 이용하여 전역변수 사용 억제 : 즉시실행후 전역에서 사라진다.
- 라이브러리에 자주 사용
(function () {
var MYAPP = {};
MYAPP.student = {
name: 'Lee',
gender: 'male'
};
console.log(MYAPP.student.name);
}());
console.log(MYAPP.student.name);