변수이름, 함수이름, 클래스 이름과 같은 식별자가 본인이 선언된 위치에 따라 다른 코드에서 자신이 참조될 수 있을지 없을지 결정되는 것 변수가 동작하는, 유효한 영역
const outer = () => {
var a = 1;
console.log(a)
}
outer // a가 출력된다
이때 a에 무슨값이 들어있는지를 찾는 곳이 바로 스코프다 // 표같이
이때 이 스코프는 outer에 속해있다
자바스크립트는 함수단위로 스코프가 생성된다
const outer = () => {
var a = 1;
fuction inner() {
var a = 2;
console.log(a)
}
inner()
}
outer // 2가 출력된다
여기서 바깥의 a(1)인지 inner 안쪽의 a(2)
찾아 볼 수 있는 곳이 스코프다!
var d = 'X' 어느 곳에서
const outer = () => {
var a = 1;
var b = 'B'
fuction inner() {
var a = 2;
console.log(a)
console.log(b)// 'B'가 출력됨
}
inner()
}
outer // 2가 출력된다
위의 코드를 보면 outer에서 b를 선언하고
inner에서 b를 출력해준다
여기서 스코프의 동작순서를보면
inner의 스코프에서 b를 찾고 없으니까 다음으로 outer의 스코프를 찾은 것이다!
만약 outer에도 없으면 함수 밖에 선언 해놓은 글로벌 스코프에서 찾게된다!
이렇게 스코프들 끼리 연결되어 찾는 것을
스코프체인이라고 한다!
자바스크립트 엔진은 변수를 참조할때 스코프 체인을 참조한다
var d = 'X' 어느 곳에서
const outer = () => {
var a = 1;
var b = 'B'
fuction inner() {
var a = 2;
console.log(a)
console.log(b)// 'B'가 출력됨
}
return inner
}
var someFun = outer()
someFun()
outer가 실행될때 안에서 선언한 변수는
outer가 return하고 함수가 끝날때 b라는 변수는 사라진다고 생각한다
그러나 b는 잘 출력된다 이것이 바로 클로저다 함수가 생성된 시점에 스코프체인을 계속 들고 있는다!
클로저 때문에 outer가 실행된 다음에도 someFun에 의해 호출이된다
const x = 1;
fuction outer () {
const x = 10;
const inner = function(){
console.log(x);
}
return inner
}
const ella = outer()
ella(); //10이 출력됨
자바스크립트 함수 실행순서
함수호출 => 실행 컨텍스트 생성 => 실행컨택스트 스택에 쌓인다 => 렉시컬 환경 생성(어떠한 코드가 어디서 생성되며 그 코드의 주변환경정보를 담고 있는 환경)
코드 실행이 끝나면 실행컨택스트 스택에서 pop되어 사라진다
ella(); 가 1이 아닌 10을 출력할 수 있었던 이유는
outer()가 ella라는 값에 할당이 된 후에도 살아 있었다!
fuction outer () {
const x = 10;
const inner = function(){
// 외부함수의 변수인 x값을 참조할 수 있다면? 이때 inner를 클로저라고 한다
console.log(x);
}
return inner
}
이는 코드 실행이 끝나면 실행컨택스트 스택에서 pop이 일어나면서 컨텍스트가 사라지지만 렉시컬 환경에선 아직 남아있기 때문이다!
그래서 가비지 컬렉션에 저장이 되어있지 않다!
중첩함수에서 클로저
- 상위 스코프의 식별자를 참조하고 있다
- 본인의 외부 함수보다 더 오래 살아있다
클로저는 하나의 state가 의도치 않게 변경되지 않도록 state를 안전하게 은닉하거나 특정함수에게 state변경을 허용하기 위해 사용한다고 한다
설명이 잘되어있는 링크 https://www.youtube.com/watch?v=PVYjfrgZhtU