자바스크립트에서 함수는 객체이다.
클로저는 자바스크립트가 일급객체의 성질을 갖는다는 것(함수를 변수처럼 다룰 수 있다는 것)을 이용해서 만들수 있는 공간임. 내부에 변수가 있을 때 자바스크립트는 그 변수를 클로저 공간에 저장을 한다음 리턴된 함수와 그 변수가 생명을 같이하도록 만든다. 함수를 생성해서 리턴하는 함수를 팩토리함수라고도 부른다. 팩토리 함수 내부에서 생성된 변수들이 있는데 함수가 끝나도 변수들이 살아있게 된다. 그 변수들이 어딨을까? 하는게 클로저의 의미임.
클로저의 예 1
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};
}
const card1 = createCard();
card1.changeTitle("생일카드")
card1.changeContent("생일축하해")
card1.print()
클로저의 예2
let rate = 1.05;
function app(){
let base = 10;
return function (price){
return price * rate + base;
}
}
console.log(app()(50)) //62.5
rate = 1.1;
console.log(app()(1)) //11.1
클로저를 왜 사용?
상태를 안전하게 은닉하고 보존시키기 위함.
createCard 함수 본문에 있는 title, content 변수는 외부에서 접근할 수 없습니다.
따라서 changeTitle, changeContent 함수를 통해 수정할 수 있도록 해주었습니다.
값을 읽을 수 있도록 제공하는 함수는 print로 해주었습니다.
그리고 이 모든 함수를 객체로 묶어서 createCard 함수에서 return 합니다.
const myCard = createCard()와 같은 형태로 인스턴스를 만들어서 사용할 수 있습니다.
클로저를 이용해서 카운팅 어플 만들기
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Template</title>
</head>
<body>
<div id="root">
<main>
<h2>Counter App</h2>
<div class="app">
<div id="current-count">0</div>
<button id="increase-button">카운터 증가</button>
<button id="decrease-button">카운터 감소</button>
</div>
</main>
</div>
<script src="./index.js"></script>
</body>
</html>
App.js
import "./app.css";
import Counter from "./Counter";
const App = () => {
const counter = Counter();
const increaseButton = document.getElementById("increase-button");
const decreaseButton = document.getElementById("decrease-button");
const currentCount = document.getElementById("current-count");
increaseButton.addEventListener("click", () => {
counter.increase();
currentCount.innerHTML = counter.getCount();
});
decreaseButton.addEventListener("click", () => {
counter.decrease();
currentCount.innerHTML = counter.getCount();
});
};
export default App;
Counter.js
const Counter = () => {
// Counter 클로저를 작성하세요.
let count = 0;
function getCount() {
return count;
}
function increase() {
count = count + 1;
}
function decrease() {
count = count - 1;
}
return { getCount, increase, decrease };
};
export default Counter;
'Javascript' 카테고리의 다른 글
타입스크립트 오류) error TS2584: Cannot find name 'console'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'. (0) | 2022.10.24 |
---|---|
함수 내보내기, 가져오기 관련 (0) | 2022.10.19 |
this, (0) | 2022.10.18 |
HTTP request, response, CSR, SSR, FETCH API (1) | 2022.10.11 |
Map에 대하여 (0) | 2022.10.07 |