선요약
-Js의 클로저는 함수의 일급 객체 성질을 이용한다.
-함수가 생성도리 때 함수 내부에서 사용되는 변수들이 외부에 존재하는 경우 그 변수들은 함수의 스코프에 저장된다.
-함수와 함수가 사용하는 변수들을 저장한 공간을 클로저라고 한다.
-별도의 선언 없이 외부 변수 묶어서 계산.
-자바스크립트에서 함수는 일급 객체다. 따라서 함수는 변수처럼 다룰 수 있다.
-일급 객체의 조건
//함수를 다른 함수의 인자로 넘길 수 있다.
function add(a,b){
return a+b
}
[1, 2, 3].reduce(add, 0)
// 익명 함수를 생성할 수 있다.
(() => {
console.log('땃쥐')
})()
//중첩 함수를 생성할 수 있다.
function outer(a){
function inner(b){
return a+b
}
return inner(10)
}
const Person = (name) => {
// 함수를 변수로 생성(여기선 내부에) *이 부분이 굉장히 중요, closure 이해에 중요함.
const printName = () => console.log(name)
return {printName}
} // 함수를 리턴하며 closure를 생성
const person = Person('Kim')
person.printName()
function printName(name){
console.log('name : ', name)
}
// 함수끼리 비교
// === 의 경우, 변수가 같은 객체(함수)를 가리키는지 체크한다.
console.log(printName === person.printName)
함수 생성해서 리턴하는 함수 = 팩토리 함수.
팩토리 함수 내부의 변수들은 팩토리 함수가 끝나고 메모리에 여전히 존재한다.
예시 1)
function createCard(){
let title = "";
let constent = "";
function changeTitle(text){title = text}
function changeContent(text){content = text}
function print(){
console.log("TITLE - ", title);
console.log("CONTENT - ", content);
}
return { changeTitle, changeContent, print};
// 꼭 객체로 return 할 필요 없이 하나의 함수로 리턴해도 됨.
}
const card1 = createCard(); // card1변수에 createCard를 할당해 클로저 생성
card1.changeTitle("생일카드");
card1.changeContent("생일축하");
card1.print();
const card2 = createCard(); // card2변수에 createCard를 할당해 클로저 생성
// card1과는 다른 메모리 공간에 할당.
card2.changeTitle("감사카드");
card2.changeContent("고마워");
card2.print();
예시 2)
let rate = 1.05;
function app(){
let base = 10;
return function (price) {
return price * rate + base;
};
}
const getPrice = app();
getPrice(120) // 136
// base는 app 함수 내부, rate는 외부의 스코프에 존재한다.
// 함수가 참조하는 변수는 실행 시점에 실행 컨텍스트에 의해 스코프가 결정된다.
console.log(app()(1)); // 11.05
rate = 1.1;
console.log(app()(1)); // 11.1
// 스코프에 따라서 변수에 영향을 받는다.
// rate의 변경은 두 클로저 함수 호출에 반영되지만, base는 증가해도 영향을 미치지 않는다. 왜냐면 내부적으로 해당 값이 계산되어 있기 때문.
// base는 app 호출 시 매번 생성되는 반면, rate는 매번 생성되지 않는다.
-상태를 안전하게 은닉하고 보존시키기 위함, 특정 함수한테만 클로저를 수정하는 권한을 부여.
-다수의 개발자와 함께 일을 할 때 실수를 방지하고 더 탄탄한 코드를 만들기위한 코드 패턴
function createCard() {
let title= "";
let content= "";
function changeTitle(text) {
title= text
}
function changeContent(text) {
content= text
}
function print() {
console.log("TITLE -", title);
console.log("CONTENT -", content);
}
return { changeTitle, changeContent, print};
}
일종의 템플릿인가?
let posion = 3;
function add2(a,b){
const c = a+b+poison;
return c;}
add2(6,11); // 20.