본 내용은 프로그래머스의 코딩테스트 광탈 방지 A to Z : JavaScript 강의를 토대로 작성하였습니다.
1. 스코프
- 유효 범위
- 변수가 어느 범위까지 참조되는 지를 뜻함
- 전역 스코프(Global Scope): 어디서든 접근 가능
- 지역 스코프(Local Scope): 해당 스코프 내에서만 접근 가능
var
- 예기치 못한 오류가 생길 수 있음
- 호이스팅되어 변수 선언이 함수 상단으로 올라가 버림
- 함수 수준의 스코프를 가짐
- 블록 내부에 새롭게 선언하더라도 블록 외부 변수값도 같이 변하게 됨
- 변수 선언 시, var 키워드는 지양
2. 클로저
- 함수가 선언된 스코프를 기억하여 함수가 스코프 밖에서 실행되어도 기억한 스코프에 접근할 수 있게 만드는 문법
- 닫힘, 폐쇄
- 외부에서 접근이 불가능한 영역을 클로저를 통해서만 접근 가능
- 은닉화
- 내부 변수와 함수를 숨길 수 있음
예시1
function example() {
// example 함수 내 지역 스코프
// 본래 함수가 종료되면 메모리에서 사라짐
const inner = '내부 변수';
// 반환된 함수가 inner를 참조
// 해당 변수는 메모리에서 사라지지 않음
return function() {
console.log(inner);
}
}
const closure = example();
closure(); // '내부 변수'가 출력
예시2
- 클로저로 인해 예기치 못한 상황이 발생할 수 있음
function timeoutCounting() {
let i = 0;
for (i = 0; i < 5; i+= 1){
setTimeout(function () {
console.log(i);
}, i * 100);
}
}
timeoutCounting(); // 5 5 5 5 5
// 1 2 3 4 5가 아닌, 5만 다섯번이나옴
// closure가 원인
// setTimeout의 대기시간이 끝나 콜백함수가 실행되는 시점에는 루프가 종료되어 i가 5가되었기 때문
3. 클로저 해결 방법
- 상기, 클로저로 인해 예기치 못한 현상이 발생할 수 있음
IIFE
- IIFE(Immediately Invoked Function Expression)
- 즉시 실행 함수
function counting() {
let i = 0;
for (i = 0; i < 5; i+= 1){
// 즉시 실행 함수로 인해 각 루프마다 closure가 생성됨
(function (number) {
setTimeout(function () {
console.log(number);
}, number * 100);
})(i);
}
}
counting(); // 0 1 2 3 4
let
- 블록 수준의 스코프기 때문에 매 루프마다 클로저가 생성
function counting() {
for (let i = 0; i < 5; i+= 1){
setTimeout(function () {
console.log(i);
}, i * 100);
}
}
counting(); // 0 1 2 3 4
Reference
'programming study > JavaScript' 카테고리의 다른 글
클린코드 자바스크립트 - 변수(var) (0) | 2022.12.14 |
---|---|
기초 JS, CS 상식 - 모듈 (0) | 2022.11.19 |
기초 JS, CS 상식 - 이벤트 루프 (0) | 2022.11.17 |
기초 JS, CS 상식 - 흐름 제어 (0) | 2022.11.16 |
기초 JS, CS 상식 - 표현식과 연산자 (0) | 2022.10.06 |