해당 글을 읽고 정리한 내용입니다!
다음과 같은 코드가 있다.
function init() {
const channel = 'YouTube';
function greet(name) {
console.log(`hey ${name}`);
console.log(`from ${channel}`);
}
setTimeout(() => {
greet('FrontendMaster');
}, 1000);
}
init();
이 코드를 보고 코드리뷰를 한다면 어떻게 할까?
다들 한 번 고민해보시라.
참고로 원글의 작성자는 이 코드를 보고 OK했다고 한다.
개선점1: setTimeout의 arrow function 삭제
greet 함수에 'FrontendMaster'라는 인자를 넘겨주고 있으니, 이 함수를 arrow function로 감싸서 작성해야하는건 아주 자연스러운 일이다.
하지만 setTimeout은, callback함수에 전달할 매개변수를 바로 작성할 수 있다.
https://developer.mozilla.org/ko/docs/Web/API/Window/setTimeout
setTimeout(code)
setTimeout(code, delay)
setTimeout(functionRef)
setTimeout(functionRef, delay)
setTimeout(functionRef, delay, param1)
setTimeout(functionRef, delay, param1, param2)
setTimeout(functionRef, delay, param1, param2, /* … ,*/ paramN)
따라서 위의 코드를 다음과 같이 수정할 수 있다.
function init() {
const channel = 'YouTube';
function greet(name) {
console.log(`hey ${name}`);
console.log(`from ${channel}`);
}
setTimeout(greet, 1000, 'FrontendMaster');
}
init();
setTimeout에 함수와 딜레이 시간만 넣어봤는데, 저렇게 추가 매개변수를 넣을 수 있다는 것을 처음 배웠다..!!
개선점2: 쓸데없는 클로저
greet 함수는 init 함수의 channel 변수를 사용하면서, 클로저를 생성한다.
클로저의 문제점은 다음과 같다:
- 클로저는 전체 스코프를 캡쳐한다: 딱 channel 변수 한 개지만, 클로저는 외부 함수의 전체 렉시컬 환경을 캡처한다. 즉, channel 변수뿐만 아니라 init 함수 내의 모든 지역 변수와 매개변수를 포함한다.
- 클로저는 변수를 유지한다: greet 함수는 init 함수의 스코프에 대한 클로저를 형성하여 channel 변수를 캡처한다. 그 결과, init 함수의 실행이 끝난 후에도 channel 변수는 setTimeout에 의해 greet 함수가 실행될 때까지 메모리에 계속 남아있게 된다.
- 메모리 부담: init 함수가 자주 호출되고, 매번 클로저에서 다른 변수를 캡처한다면, 이는 메모리 사용량 증가로 이어진다. 대규모 애플리케이션이나 빈번한 반복문에서 이러한 상황이 발생하면, 주의 깊게 관리하지 않을 경우 메모리 누수가 발생할 수 있다.
따라서 코드를 이렇게 수정하면, 클로저 문제를 해결할 수 있다.
function init() {
const channel = 'YouTube';
function greet(name, ch) {
console.log(`hey ${name}`);
console.log(`from ${ch}`);
}
setTimeout(greet, 1000, 'FrontendMaster', channel);
}
init();
'개발 > 코드리뷰' 카테고리의 다른 글
[코드리뷰] 나쁜 리액트 코드를 고치자 - DRY원칙, URL객체 (5) | 2024.10.28 |
---|