목차
1. 클로저란?
2. 어휘적(Lexical) 환경
3. 스코프 (블록 스코프 / 함수 스코프 / 렉시컬 스코프)
클로저 - JavaScript | MDN
클로저는 주변 상태(어휘적 환경)에 대한 참조와 함께 묶인(포함된) 함수의 조합입니다. 즉, 클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공합니다. JavaScript에서 클로저는 함수 생
developer.mozilla.org
출처 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures
1. 클로저
클로저는 주변 상태(어휘적 환경)에 대한 참조와 함께 묶인(포함된) 함수의 조합이다.
즉, 클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공한다.
Javascript에서 클로저는 함수 생성 시 함수가 생성될 때마다 생성한다.
(쉽게 말하면 함수 안에 함수가 정의 될 때 감싸고 있는 함수에 접근할 수 있는 것을 의미한다.)
2. 어휘적(Lexical) 환경
function start(){
var name = "Jaka";
function viewName(){
// viewName() 은 내부 함수이며, 클로저.
console.log(name); // 부모 함수에서 선언된 변수를 사용
}
viewName();
}
start();
start() 는 지역 변수 name과 함수 viewName() 을 생성한다. viewName() 은 start() 안에 정의된 내부 함수이며 start() 함수 본문에서만 사용가능하다. viewName() 내부엔 자신만의 지역변수가 없다는 점이다. 내부함수는 외부함수의 변수에 접근할 수 있기 때문에 start()를 실행하면 viewName() 가 실행되어 "Jaka"가 출력되는 것을 확인할 수 있다.
- let / const 를 사용한 범위 지정
var 사용
JavaScript에는 함수 스코프와 전역 스코프 두 가지만 존재했다. var로 선언한 변수는 함수 내부 또는 외부에서 선언 되었는지에 따라 함수 스코프나 전역 스코프를 가지게 된다.
if (Math.random() > 0.5) {
var x = 1;
} else {
var x = 2;
}
console.log(x); // 1 or 2 가 출력되며 에러가 발생하지 않는다.
위에 코드에서는 에러가 발생하지 않은데 그 이유는 var로 선언한 변수에 대해 스코프를 생성하지 않기 때문이며, 여기서 var 는 전역변수를 생성한다.
let / const 사용
ES6에서, JavaScript는 블록 스코프 변수를 생성할 수 있도록 let과 const 로 변수를 선언했을 때만 유효한다.
if (Math.random() > 0.5){
let x = 1;
} else {
let x = 2;
}
console.log(x); // 에러 발생
ES6부터는 블록은 스코프로 취급되기 시작했다지만, let과 const 로 변수선언 했을 때만 유효하다.
클로저(Closure)
function testFunc() {
const name = "Jaka";
function displayName() {
console.log(name);
}
return displayName;
}
const myTest = testFunc();
myTest();
// Jaka 가 출력됨
이 함수는 displayName() 내부 함수가 실행되기 전에 외부 함수에서 반환된다. 이 코드가 정상적으로 동작할 수 있는 이유는 JavaScript의 함수가 클로저를 형성하기 때문이다 . 클로저는 앞서 말했듯이 함수와 함수가 선언된 어휘적 환경의 조합이다. 이 환경은 클로저가 생성된 시점의 유효범위 내에 있는 모든 지역 변수로 구성된다.
위의 코드 경우에는, myTest는 testFunc이 실행 될 때 생성된 displayName 함수의 인스턴스에 대한 참조다. displayName의 인스턴스 변수 name이 어휘적 환경에 대한 참조를 유지한다. 이런 이유로 myTest가 호출될 때 변수 name은 사용할 수 있는 상태로 남게 되고 "Jaka"가 console.log에 전달된다.
3. 스코프 (함수 스코프 / 블록 스코프 / 렉시컬 스코프)
- 스코프는 쉽게 말해서 변수에 접근할 수 있는 범위이다.
- 변수 또는 표현식이 "해당 스코프" 내에 있지 않다면, 사용할 수 없다.
- 스코프는 계층적인 구조를 기지기 때문에, 하위 스코프는 상위 스코프에 접근할 수 있지만 반대는 불가능하다.
함수 스코프
특정 함수 내에 어떠한 블록이 있다면, 해당 블록 내에 있는 변수는 해당 함수 내에서도 접근할 수 없고 오직 그 블록 내에서만 접근이 가능하다.
function f1() {
var x = 0;
{
var x = 1;
console.log(x); // 1
}
console.log(x); // 1
}
f1(); // var는 블록내에서만 유효하지 않아서 x가 1이 두번 찍히는 것을 확인할 수 있다.
블록 스코프
let과 const 로 변수를 선언하면 블록 스코프를 가진다. let 과 const 는 변수 선언된 블록 내에서만 유효하다.
function f1(){
let x = 0;
{
let x = 1;
console.log(x); // 1
}
console.log(x); // 0
}
f1();
렉시컬 스코프
함수의 위치에 따라 함수의 상위 스코프가 정해지는데 이 상위 스코프가 정해지는 시점이 함수의 선언인지 함수의 실행인지에 따라 함수의 상위 스코프가 달라진다.
함수의 상위 스코프가 함수가 실행되는 시점에서의 상위 스코프로 정해지는 것을 정적 스코프 또는 렉시컬 스코프라고 한다.
'Javascript' 카테고리의 다른 글
[JS] 객체 지향 프로그래밍 (OOP) (0) | 2024.11.28 |
---|---|
[JS] Class 작동원리 (0) | 2024.11.15 |
[JS] reduce() 에 대해서 (0) | 2024.06.20 |
[JS] 동기(synchronous) 비동기(asynchronous) (0) | 2024.05.13 |
[JS] 구조 분해 할당 (0) | 2024.04.24 |