JavaScript 핵심 개념과 주요 문법 - 원시 자료형, 참조 자료형에 이어 오늘은 스코프와 클로저에 대해 학습했다.
스코프의 개념을 학습하고 이전에 포스팅한 변수 호이스팅을 다시 보니 더 명확하게 이해할 수 있었다.
기존에 알았던 함수는 아래와 같은 형식을 가졌지만 클로저 함수는 차이를 가진다.
const func = (x, y) => x + y;
func(1, 2) // 3
const func = x => y => x + y;
func(1)(2) // 3
typeof func(1) // function
func(1) // y => x + y
함수의 호출이 두 번 발생한다. 클로저 함수도 스코프의 영향을 받는다. 그렇기 때문에 변수의 선언이 중요하다. func에서 선언한 변수 x를 그 안의 함수에서 호출 가능하겠지만, 선언한 변수 y를 그 외부에선 호출할 수 없다.
const func = x => y => x + y;
const add1 = func(1);
add1(2) // 3
add1(5) // 6
다음과 같이 add1에 func(1)을 통해 리턴할 함수를 할당해도, 매개변수 x에는 인자로 받은 1이 할당되어있다. 일반적인 함수는 호출이 끝나면 함수 내부의 변수를 사용할 수 없다.
const checkEmotion = () => {
let state = '';
return {
happy: () => {
state = 'happy';
console.log(`Now, I'm ${state}`)
},
sad: () => {
state = 'sad';
console.log(`Now, I'm ${state}`)
},
surprise: () => {
state = 'surprise';
console.log(`Now, I'm ${state}`)
},
getEmotion: () => state
}
}
const nowEmotion = checkEmotion();
// {happy: ƒ, sad: ƒ, surprise: ƒ, getEmotion: ƒ}
위와 같은 패턴을 클로저 모듈 패턴이라고 한다. checkEmotion 함수를 바꾸지 않으면 안의 state 변수에 새롭게 값을 할당할 수 없다. 이를 접근 제한이라 하며 캡슐화라고 한다.
const nowEmotion1 = checkEmotion();
nowEmotion1.happy();
nowEmotion1.sad();
nowEmotion1.happy();
nowEmotion1.getEmotion(); // 'happy'
const nowEmotion2 = checkEmotion();
nowEmotion2.sad();
nowEmotion2.sad();
nowEmotion2.surprise();
nowEmotion2.getEmotion(); // 'surprise'
checkEmotion 함수를 별개의 변수에 할당하여 실행하여도 서로 영향을 미치지 않으며 state는 독립된다. 이렇게 재사용성을 극대화하여 사용하는 것을 모듈화라고 한다.
오늘 학습한 내용들이 직전에 미리 예습한 내용들을 더 이해할 수 있게 만들어줬다. 스코프에 대해서 개념이 적었기 때문에 변수 호이스팅을 공부할 때 이해가 쉽지 않았는데 오늘 그 답답함이 해소된 것 같다. 가끔 오류에 참조오류가 뜰 때 정확히 왜 뜨는지는 몰랐는데 이제 알 것 같다.
클로저 함수도 기능구현시 중복되는 기능을 담는다면 코드를 많이 줄이고, 가장 중요한 건 코드가 작동할 때 내 의도와 다르게 값을 변경시키거나 하는 불상사를 줄일 수 있을 것 같다. 애초에 모든걸 염두하고 기획하면 그럴 일이 없겠지만, 현실은 다를 것이기 때문에.. 오늘 배운 캡슐화, 모듈화 개념을 실전에 써볼 수 있도록 해야겠다.