오늘은 사전퀴즈들을 풀어보고 그 퀴즈들에 대한 풀이를 보는 시간을 가졌었는데 생각보다 this와 bind함수와 관련된 내용이 생소해서 놀랐다. 그동안 코더처럼 bind나 this 신경안쓰고 코드를 짰던 나...😱😱 본격적인 Vanilla.js 프로젝트 들어가기 전에 모던 JS 딥다이브 책의 this 챕터는 꼭 읽고 프로젝트에 들어가야 할 것같다. 물론 모던 JS딥다이브 북스터디에서도 다루겠지만 지금 당장 필요한 것 같다😥 알고리즘 문제도 풀어야하고 코드리뷰도 해야하고 할 공부는 정말 많지만 오늘 그래도 첫 모던 JS 딥다이브 북스터디에서 발표하는 시간을 가진건 스스로한테 아주 칭찬하고싶다. 내일 꼭 this 챕터 읽고 블로그에 글을 올리자🔥🔥
ES6 모듈을 사용하기 전에는 컴포넌트들을 모듈 하는데 함수를 즉시 실행 함수로 묶어 모듈 패턴으로 사용했다. 쉽게 말하자면 필요한 것들을 모듈화 해서 쓰는 방법 중 하나이다.
const logger = (function(){
// logCount는 밖에서 접근할 수 없다. 일종의 private 효과
let logCount = 0;
function log(message){
console.log(message);
logCount = logCount + 1;
}
function getLogCount() {
return logCount;
}
return {
log: log,
getLogCount: getLogCount
}
})()
console.log(logger.logCount)//undefined. 직접적으로 접근할 수 없음
const numbers = [0,1,2,3,4]
for(var i =0; i< numbers.length; i++){
setTimeout(function(){
console.log(`[${i}] number ${numbers[i]} turn!`)
}, i * 1000) //원래 의도: 0은 0초뒤 출력, 1은 1초뒤 출력 ...
}
이 코드를 실행해보면 원래 의도와는 다른 결과가 나온다. 그 이유는 setTimout함수 이후 참조하는 i는 이미 for문이 끝난 상태의 i이기 때문이다. 즉 i = 5가 된다.
그렇다면 어떻게 해결 할 수 있을까?
👉 즉시 실행 함수를 사용한다
👉 var 대신 let을 사용한다
const numbers = [0,1,2,3,4]
for(let i =0; i< numbers.length; i++){
setTimeout(function(){
console.log(`[${i}] number ${numbers[i]} turn!`)
}, i * 1000)
}
let과 const는 블록 레벨 스코프 이므로 for 루프 안에서만 유효한 변수가 된다.
그래서 setTimeout 내에서 let i가 0일때, 1일 때 각각 참조되기 때문에 정상 동작한다.
👉 for 대신 forEach를 사용한다
const numbers = [0,1,2,3,4]
numbers.forEach(function (number, i){
setTimeout(() =>{
console.log(`[${i}] number ${numbers[i]} turn!`)
}, i * 1000)
})
forEach로 numbers를 순회하면서 각각 function을 만들기 때문에 i의 값이 고유해진다!