[TIL] Day10 헷갈리는 VanillaJS

Loopy·2023년 6월 14일
0
post-thumbnail

회고

오늘은 사전퀴즈들을 풀어보고 그 퀴즈들에 대한 풀이를 보는 시간을 가졌었는데 생각보다 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. 직접적으로 접근할 수 없음
  • logger에는 log, getLogCount를 묶은 객체가 들어가게 된다. 이렇게 되면 외부에서 logCount를 접근할 수 없게된다(정보은닉)
  • logger만 전역에 묶이게 되고 내부에 선언된 변수나 함수는 전역에 묶이지 않기 때문에 전역변수의 오염을 최소화 시킬 수 있다. 또 이런식으로 네임스페이스 효과를 줄 수도 있다.

setTimeout과 관련된 Code

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의 값이 고유해진다!

0개의 댓글