클로저(Closure)는 외부 변수를 기억하고 외부 변수에 접근할 수 있는 함수를 의미한다.
함수 내부에 함수가 존재하는 경우 클로저가 생성된다.
자바스크립트는 렉시컬 스코프(lexical scope)를 따르기 때문에 식별자가 현재 스코프에 존재하지 않으면 선언된 위치를 기준으로 외부 환경에서 해당 변수를 찾는다.
그렇기 때문에 결과적으로 자바스크립트의 함수는 모두 클로저이다.
⚡️ 렉시컬 스코프(lexical scope)?
함수를 어디서 선언하였는지에 따라 상위 스코프를 결정하며, 다른 말로 정적 스코프(static scope)라 부르기도 한다
클로저를 사용한 대표적인 예로 커링함수가 있다
여러 개의 인자를 받아야하는 함수의 경우 인자를 필요에 따라 하나씩 받아서 호출할 수 있도록 한다.
const server = ip => connectionInfo => {
console.log(`${ip}: ${JSON.stringify(connectionInfo)}`);
}
const connection1 = server("localhost:3000");
connection1({id: "1", password: "1"});
// localhost:3000: {"id":"1","password":"1"}
위 에제에서 server 함수는 한 개의 인수(ip)를 가지며 내부에 정의된 익명함수를 반환한다.
익명함수는 한 개의 인수(connectionInfo)를 가지며, 조합된 문자열을 반환한다.
렉시컬 스코프가 적용되는 과정은 아래와 같다
-- 전역 렉시컬 환경 --
server: function
connection1: 사용불가
const connection1 = server("localhost:3000")
실행 시점-- 전역 렉시컬 환경 --
server: function
connection1: function
-- server 렉시컬 환경 (전역 렉시컬 환경 참조) --
ip: "localhost:3000"
connection1({id: "1", password: "1"});
실행 시점-- 전역 렉시컬 환경 --
server: function
connection1: function
-- server 렉시컬 환경 (전역 렉시컬 환경 참조) --
ip: "localhost:3000"
-- server 안 익명함수 렉시컬 환경 (server 렉시컬 환경 참조) --
connectionInfo: {id: "1", password: "1"}
클로저 기능을 사용하면 메모리에서 제거되지 않기 때문에 효율적으로 사용해야하고, 사용이 끝났을 때는 낭비를 방지하기 위해 클로저 함수에 null을 대입하여 메모리를 해제해주어야한다.