모든 변수는 스코프(유효범위)를 지니는데, 이들이 어디에 선언되었느냐에 따라 그 스코프가 어떤 것인지 알 수 있다. 선언된 범위가 어딘지에 따라 이 변수들이 어디까지 참조될 수 있는지 파악할 수 있는데 2가지로 크게 나눠볼 수 있다.
위의 그림에서 전역변수는 무엇이고, 지역변수는 무엇일까?
코드를 실제로 실행하게 되면
var와 let 선언에서의 차이는?
변수와 타입 참조
let
: lexical scope(렉시컬, 어휘적 스코프)var
: Block 범위에 한정되지 않고 자신만의 scope를 가짐.(old way)let | const | var | |
---|---|---|---|
유효범위 | Block Scope | Block Scope | Function Scope |
값의 재정의 | 가능 | 불가능 | 가능 |
재선언 | 불가능 | 불가능 | 가능 |
- 함수를 어디서 선언했는지에 따라 상위 스코프를 결정하는 것으로 함수의 '호출' 기준이 아닌 '선언'에 따라 결정된다.
let num = 'global' // 전역변수 num
function a(){
let num = 'local'; // 지역변수 num
b();
}
function b(){
console.log(num); // 여기서 num은 어느 변수의 값을 출력할까?
}
① b() 함수 안에는 num을 지역변수로 설정한 게 없다. 고로 밖으로 나가서 찾아와야하는 상황.
② a 안의 num은 a 지역에서만 쓸 수 있는 변수로 b() 함수가 들어가서 꺼내올 수 없다.
③ 그럼 b() 함수는 최종적으로 바깥에 있는 전역변수인 num의 값을 갖고 들어온다.
④ 결과적으로 a()를 실행했을 때, b()는 갖고 있던 전역변수 num을 출력한다.
함수와 정적 스코프 환경의 조합으로 함수가 생성될 당시 외부 변수를 기억해서 생성 이후에도 계속 그 환경에 접근할 수 있는 함수다.참조
function counter() {
let num = 0;
return function (){
return num++
}
}
let counterTest = counter();
console.log(counter()); // 0
console.log(counter()); // 1
console.log(counter()); // 2
사용 하는 이유 :
1) 현재 상태를 기억하고 변경된 최신 상태를 유지하기 위해
2) 전역 변수의 사용을 억제 하기위해
3) 정보를 은닉하기 위해
외부 함수의 변수에 접근할 수 있는 내부 함수
대표적인 예시
private variable
scope chain
참조사이트
스코프
Lexical Scope(Static Scope) and Dynamic Scope
자바스크립트 클로저 이해하기