LeetCode 30 Days of JavaScript Closures

황고은·2025년 10월 8일
0

LeetCode에 30 Days of JavaScript라는 것이 있길래 풀어보고 있습니다.
아직 4문제밖에 안 풀어봤지만 문제들이 생각보다 알찬 것 같습니다.

2667. Create Hello World Function

createHelloWorld라는 함수를 작성해야 합니다.
이때, 반환값은 새로운 함수여야 하며, 이 함수의 반환값은 'Hello World'라는 문자열이여야 합니다.

var createHelloWorld = function() {
  
    return function(...args) {
      
        return 'Hello World';
    }
};

클로저의 개념을 처음 공부할 때 봤던 함수 반환값입니다.
클로저란, 함수 내부에서 함수가 생성되었을 때, 생성된 함수는 외부 함수의 값에 접근할 수 있는 것을 의미합니다.
근데 사실 이 문제에서 클로저 개념이 적용되는 것 같진 않고... 워밍업 문제라는 생각이 듭니다.

다른 제출된 코드를 봐도 제 코드와 다른 점이 없어 코드 비교는 생략하겠습니다.



2620. Counter

counter라는 변수에 createCounter() 함수를 할당합니다.
createCounter() 함수를 counter 변수를 통해 정수 n과 함께 호출할 때, 처음에는 n을 반환하고, 이후 함수가 호출될 때마다 이전 반환값에 1씩 더한 값을 반환해야 합니다.

var createCounter = function(n) {
  
  return function() {
        for (let i = 0; i < arguments.length; i++) {
            createCounter(n);
        }

        return n++;
    };
};
/** 
 * const counter = createCounter(10)
 * counter() // 10
 * counter() // 11
 * counter() // 12
 */

테스트 케이스에 calls라는 부분이 있길래 arguments 객체로 값을 받아서 그 길이만큼 반복했습니다만...
댓글을 보니 이 부분은 무시해도 된다고(...) 합니다.

본격적으로 클로저의 개념이 등장하는 문제입니다.
문제 밑에 주석으로 counter 변수가 선언되어 있고, createCounter() 함수가 할당되어 있는 것을 알 수 있습니다.
이후 counter() 코드를 통해 함수를 반복적으로 실행하네요.

자바스크립트에서 모든 객체는 도달 가능한 상태일 때만 메모리에 유지되기 때문에, 함수 호출이 끝났을 때에는 n 값도 사라지는 것이 보통입니다.
하지만 위 코드의 경우 createCounter() 함수가 counter 변수를 통해 지속적으로 도달 가능한 상태에 있어, n 값은 계속 메모리에 유지되고 있고, 이를 통해 n 값을 1씩 증가시키며 반환할 수 있는 것입니다. (우와! 클로저!)

var createCounter = function(n) {
  
    return function() {
      
        return n++
    };
};

calls를 신경쓰지 않고 코드를 작성하면 위와 같이 매우 간단하게 작성할 수 있습니다.



2704. To Be Or Not To Be

expect라는 함수를 작성해야 합니다.
아무 값이나 받을 수 있는 파라미터 val가 있어야 하며, 다음 두 개의 함수를 가지고 있는 객체를 반환해야 합니다.

  • toBe(val):
    다른 변수를 인자로 받아 expect의 인자와 값이 일치할 때 true를 반환합니다.
    만약 값이 일치하지 않으면 'Not Equal' 에러를 throw 해야 합니다.
  • notToBe(val):
    다른 변수를 인자로 받아 expect의 인자와 값이 일치하지 않을 때 true를 반환합니다.
    만약 값이 일치하면 'Equal' 에러를 throw 해야 합니다.
var expect = function(val) {

  	return {
    	toBe: function(arg) {
            if (val === arg) {
                return true;
            } else {
                throw new Error('Not Equal');
                return false;
            }
        },
      
      	notToBe: function(arg) {
            if (val !== arg) {
                return true;
            } else {
                throw new Error('Equal');
                return false;
            }
        }     
    };
};

객체를 반환해야 한다는 의미가 {"value":true}와 같은 형태로 반환해야 한다는 뜻인 줄 알았는데, 리트코드 사이트 내에서 return 값에 따라 알아서 객체 형태로 만들어줬습니다.
문제 조건에 따라 true 혹은 false 값을 반환하는 메서드를 만들어 객체를 return 하면 됩니다.

항상 댓글 보면 리트코드는 문제 풀이보다 문제 이해가 더 어렵다는 내용이 나오는데, 음... 무슨 말인지 실감했습니다.

다른 정답 코드들도 제 코드와 크게 벗어나지 않아서 비교는 생략하도록 하겠습니다.



2665. Counter II

처음에는 init 파라미터를 통해 정수를 전달받는 createCounter 함수를 만들어야 합니다.
아래 3가지 함수를 포함한 객체를 반환해야 합니다.

  • increment():
    현재 값에서 1을 증가하여 반환합니다.
  • decrement()
    현재 값에서 1을 감소하여 반환합니다.
  • reset()
    현재 값을 init과 동일하게 만든 뒤, 그 값을 반환합니다.
var createCounter = function(init) {
    let currentValue = init;

    return {
        increment: function() {
            currentValue += 1;
            return currentValue;
        },

        decrement: function() {
            currentValue -= 1;
            return currentValue;
        },

        reset: function() {
            currentValue = init;
            return currentValue;
        }
    };
};

/**
 * const counter = createCounter(5)
 * counter.increment(); // 6
 * counter.reset(); // 5
 * counter.decrement(); // 4
 */

객체에 메소드 세 개 만들고 반환했습니다.
처음 currentValueinit을 할당해주는 부분에서, this.init을 할당해줬는데 undefined 값을 확인했습니다.

처음 counter 변수에 함수를 할당 할 때의 this는 글로벌 객체를 참조하니 당연한 일입니다.
this에 대해 공부를 열심히 했다고 생각했는데, 헷갈리지 않을 때까지 반복 학습을 해야겠습니다.

const createCounter = (init) => {
  let val = init;
  return {
    increment: () => ++val,
    decrement: () => --val,
    reset: () => (val = init)
  };
};

제출 된 정답 코드 중 하나를 가져왔습니다.
화살표 함수를 이용해 코드를 간단하게 구현했네요.
개인적으로 화살표 함수는 가독성 측면에서나 코드 유지보수 측면에서나 불호에 가깝습니다만, 이런 간단한 코드 작성 시에는 화살표 함수만큼 좋은 문법이 또 없는 것 같습니다.
오히려 코드가 짧을 때는 화살표 함수가 가독성을 높여주는 것 같기도 합니다.

profile
영차영차 눈을 굴려보아요 ⛄

0개의 댓글