scope에 대해서 자세히 알고싶다면? 클릭
아래 코드는 어떻게 동작 한 것일까? 스코프에 주목해보자
let value0 = "value0";
function fn1() {
let value1 = "value1";
console.log(value0, value1);
}
fn1();
value0 | value1 | |
---|---|---|
Scope | Global Scope | fn1 함수의 Local Scope |
그렇다면 value0의 값은 js는 어떻게 가져올까?
js는 가장 먼저 Local을 찾는데, Local에 value0이 없으므로 Script에서 value0을 가져온다.
아래 코드는 왜 동작을 하지 않는 것일까? 역시 스코프에 주목해보자
let value0 = "value0";
function fn2() {
let value2 = "value2";
console.log(value0, value1, value2);
}
function fn1() {
let value1 = "value1";
console.log(value0, value1);
fn2();
}
fn1();
value0 | value1 | value2 | |
---|---|---|---|
Scope | Global Scope | x | Local Scope |
위 코드가 에러가 발생하는 이유는 fn1() 함수 내에서 선언된 value1 변수는 fn1()의 지역 스코프에 속한다. 따라서 fn2() 함수에서 value1 변수에 접근하려고 하면 에러가 발생한다.
마찬가지로 fn2() 함수에서 선언된 value2 변수는 fn2() 지역 스코프에 속하므로, fn1() 함수에서 접근할 수 없다.
이처럼 함수의 유효범위는 함수가 어디서 실행됐느냐가 아닌, 어디서 정의됐느냐에 따라 달라지는데, 이를 lexical scoping(렉시컬 스코핑) 또는 static scope라고 부른다.
MDN에서는 클로저(Closure)는 함수와 그 함수가 선언됐을 때의 렉시컬 환경(Lexical environment)과의 조합이라고 정의하였다.
즉, 클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 말한다.
이를 간단히 말하자면 클로저는 중첩된 함수가 외부 스코프에서 선언된 변수에 접근할 수 있는 기능을 말한다.
아래 코드 참조: 클로저Closure란
// Counter 예제
const btn = document.querySelector('button')
btn.addEventListener('click',handleClick)
let count = 0
function handleCilck(){
count++
return count
}
//위와 같은 경우에 count를 전역변수로 사용해줘야 count가 증가를 해줄 수 있음
//이럴경우 클로져를 사용해서 해결할 수 있다.
// Counter Closure 예제
const btn = document.querySelector('button')
btn.addEventListener('click',handleClick())
function handleCilck(){
let count = 0
return function (){
count++
return count
}
}
// 위와 같이 작성해 준다면 외부함수(handleClick)의 lexical environment를 참조하는 함수를
// btn의 콜백함수로 이용해 전역객체 없이 구현할 수 있다.
// (코드참조)
function Counter() {
// 카운트를 유지하기 위한 자유 변수
var counter = 0;
// 클로저
this.increase = function () {
return ++counter;
};
// 클로저
this.decrease = function () {
return --counter;
};
}
const counter = new Counter();
console.log(counter.increase()); // 1
console.log(counter.decrease()); // 0
// 새로운 태그를 만들 수 있는 함수 Closure 구현
const order = (food) => {
console.log(food + "을(를) 주문하셨습니다.");
return function (drink) {
return drink + "을(를) 추가로 주문하셨습니다."
}
}
const orderBurger = order("햄버거");
const orderPizza = order("피자");
console.log(orderBurger("콜라"));
console.log(orderPizza("사이다"));