Will find a way
[JS] 클로저와 스코프 본문
목차
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();
렉시컬 스코프
함수의 위치에 따라 함수의 상위 스코프가 정해지는데 이 상위 스코프가 정해지는 시점이 함수의 선언인지 함수의 실행인지에 따라 함수의 상위 스코프가 달라진다.
함수의 상위 스코프가 함수가 실행되는 시점에서의 상위 스코프로 정해지는 것을 정적 스코프 또는 렉시컬 스코프라고 한다.
'Language > 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 |