skip to Main Content

When I call a function using a method, it’s returns undefined and Nan.

When it’s called counter.increment, it should return the input "init" + 1, counter.decrement should return "init" – 1 and counter.reset should return the initial value of "init". But instead for some reason, the three console.log returns undefined and the function createCounter returns NaN.

var createCounter = function(init) {

  return {

    increment: (init) => {

      console.log(init);
      return init++;

    },

    decrement: (init) => {

      console.log(init);
      return init--;

    },

    reset: (init) => {

      console.log(init);
      return init;

    }

  }

};


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

3

Answers


  1. Remove init from all the function calls so they correctly use the outer init closed over in scope from the createCounter call. You are trying to update an undefined local init value which results in NaN.

    Save the initial init into a local variable that can be mutated.

    Note also the console logs are logging the starting value, not the resulting value. It’s trivial to capture the result first for logging before returning it.

    var createCounter = function(init) {
      let _init = init;
      
      return {
        increment: () => {
          console.log(_init); // (1) 5
          return _init++;     // (1) 5 -> 6
        },
        decrement: () => {
          console.log(_init); // (3) 5
          return _init--;     // (3) 5 -> 4
        },
        reset: () => {
          console.log(_init); // (2) 6
          _init = init;
          return _init;       // (2) 5
        }
      }
    };
    
    const counter = createCounter(5);
    counter.increment(); // (1) 5
    counter.reset();     // (2) 6
    counter.decrement(); // (3) 5

    Note also that your logic uses postfix ++/-- operators, meaning that the value is returned and then the value is incremented/decremented.

    If you desire for the returned value to be the updated value then use the prefix ++/-- operators instead, which increments/decrements first and returns the updated value. Just move the operator in front of the variable you are incrementing/decrementing.

    let foo = 5, bar = 5;
    // Postfix
    console.log(foo++); // 5
    console.log(bar--); // 5
    foo = 5, bar = 5;
    // Prefix
    console.log(++foo); // 6
    console.log(--bar); // 4

    Suggested edit:

    var createCounter = function(init) {
      let _init = init;
      
      return {
        increment: () => ++_init,
        decrement: () => --_init,
        reset: () => _init = init,
      }
    };
    
    const counter = createCounter(5);
    console.log(counter.increment()); // 6
    console.log(counter.reset());     // 5
    console.log(counter.decrement()); // 4
    Login or Signup to reply.
  2. EDIT: This answer merely illustrates the problem; for the solution, see @Drew Reese’s answer.

    Your outer init is not being used, since its being shadowed by the init passed as argument to the inner functions. So to use your code as it is now, you would need to do the following:

    [Please don’t do this, it defeats the whole purpose of a counter]

    /* Do NOT use the following code. It's bad code.
    It's only here for illustrating the problem. */
    
    var createCounter = function(init) {
        return {
            increment: (init) => {
                console.log(init);
                return ++init;
            },
            decrement: (init) => {
                console.log(init);
                return --init;
            },
            reset: (init) => {
                console.log(init);
                return init;
            }
        }
    };
    
    const counter = createCounter()
    console.log(counter.increment(5)); // 5, 6
    console.log(counter.reset(8)); // 8, 8
    console.log(counter.decrement(2)); // 2, 1

    Notice the change of init++ to ++init (and similarly with --init).

    Of course, the above code isn’t very useful, so to do what you really want to do, remove the init argument of the inner functions, as @Drew Reese shows in their answer.

    Login or Signup to reply.
  3.   var createCounter = function(init) {
         
        return {
           increment: () => {
        
           return init++, //The value increases and becomes 6
              console.log(init), //Returns 6
              init-- //Reverses the value back to the original
            }  ,
        
          
        
        
            decrement: () => {
        
             
              return init--, //Value goes down and becomes 4
              console.log(init), //Returns 4
              init++ //Returns to default 5
            
        
            },
        
            reset: () => {
        
              
              return init,//Return Default value
              console.log(init)
             
        
            }
        
          }
        
        };
        const counter = createCounter(5)
        counter.increment(); // 6
        counter.decrement(); // 4
        counter.reset(); // 5
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search