클로저 (closure)
함수와 함수가 선언된 어휘적 환경의 조합.
외부 함수의 지역 변수에 접근할 수 있는 함수의 환경.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>클로저 closure 1</title>
<style>
.box {
margin-top: 20px;
width: 200px;
height: 200px;
background-color: lightpink;
}
</style>
</head>
<body>
<button>click</button>
<div class="box" id="box"></div>
<script>
const btn = document.body.querySelector("button");
const box = document.body.querySelector("#box");
const toggle = (function () {
let state = false; // 내부 함수가 이 변수를 사용할 수 있음
return function () {
// 이 내부함수가 '클로저'이며 값을 외부 함수에 반환한다.
box.style.display = state ? 'block' : 'none'; // 삼항연산자
state = !state; // false면 true 대입
};
})();
// btn.onclick = toggle
btn.addEventListener("click", toggle); // btn을 클릭하면 toggle 함수 호출.
</script>
</body>
</html>
<script>
function count1() {
for (var i = 1; i <= 5; i++) {
console.log(i);
}
}
count1();
console.log("비동기 함수 사용시 클로저 문제");
function count2() {
for (var i = 1; i <= 5; i++) {
setTimeout(function () {
console.log(i);
}, 1000);
}
}
count2();
/*
i = 1일 때 setTimeout() 함수가 실행되나 1초 기다렸다가 콘솔 실행
1초를 기다리는 동안 for반복문의 실행이 끝나기 때문에 i의 값은 마지막 i++가 끝난 6이고
i의 값이 6이 된 후에 setTimeout()이 대기시간을 끝내고 console.log(i)를 실행하면서
console.log(i) = 6을 5번 실행함.
*/
console.log("즉시 실행 함수를 사용해 해결");
function count3() {
for (var i = 1; i <= 5; i++) {
(function (count) {
setTimeout(function () {
console.log(count);
}, 1000);
})(i); // 즉시실행함수의 인수 i를 매개변수로 받아 변수값을 가진 상태로 대기하기 때문에 i를 순차적으로 출력.
}
}
count3();
function count4() {
console.log('let을 이용한 해결');
// 블록 레벨 스코프이기 때문에 반복문의 각 단계가 같은 변수 i를 공유하지 않음
for (let i = 1; i <= 5; i++) {
setTimeout(function () {
console.log(i)
}, 1000)
}
}
count4();
</script>
변수의 유효 범위 지정 (Lexical scoping)
'JavaScript' 카테고리의 다른 글
[JavaScript] DOM객체 노드 탐색 (0) | 2022.12.08 |
---|---|
[JavaScript] 모듈 (module), import, export (0) | 2022.12.08 |
[JavaScript] 전개 구문 (spread syntax) _ more (0) | 2022.12.07 |
[JavaScript] 배열의 메서드 종류_more (0) | 2022.12.07 |
[JavaScript] 객체 프로퍼티 설정 (0) | 2022.12.06 |