Search code examples
javascriptmethodsjavascript-objects

Why can't I create a method that 'for / in' loops through the values within that same object?


Can anyone explain why the sum and mul functions aren't working in the following:

https://jsfiddle.net/jcq5010/xdvwh9s4/

I know I can just return this.v1 + this.v2, and this.v1 * this.v2, but I was hoping to write it flexible enough to handle any number of new properties and values that are created in read().

This is for a challenge question in javascript.info. The flexibility isn't part of the question, but I was curious if it was possible.

  read() {
    this.v1 = parseInt(prompt('Please give a value:'));
    this.v2 = parseInt(prompt('Please give another value:'))
  },

  sum() {
      let result = 0;
      for(let prop in calculator){
        result += this.prop
      };
      return result
  },

    mul() {
        let result = 0;
        for(let prop in calculator){ 
         result *= this.prop
      };
        return result
  },
};

calculator.read();
alert( calculator.sum() );
alert( calculator.mul() );

calculator.read() should add properties v1 and v2, with each having a value given through prompt

alert( calculator.sum() ); should alert with the sum of the values of v1 and v2 (+ any others created in read()

alert( calculator.mul() ); should alert with the product of the values of v1 and v2 (+ any others created in read()


Solution

  • Several issues:

    1. this.prop is undefined - you want this[prop]
    2. your for/in loops will also enumerate sum, mul and read
    3. your mul function starts with 0 so will always result in 0

    One way to fix it is to test the properties to see if they are sum, mul or read and ignore them in the loop

    But there's an easier way, using Object.defineProperties - the default enumerable property of a property created this way is false - so it won't end up in your for in loop

    Note, I've hardcoded the inputs and console.log the output because prompt and alert are annoying

    let calculator = {};
    Object.defineProperties(calculator, {
        read: {
            value: function() {
                this.v1 = 12;
                this.v2 = 13;
            },
        },
        sum: {
            value: function() {
                let result = 0;
                for(let prop in this){
                    result += this[prop];
                }
                return result;
            }
        },
        mul: {
            value: function() {
                let result = 1;
                for(let prop in this){
                    result *= this[prop];
                }
                return result
            }
        }
    });
    calculator.read();
    console.log( calculator.sum() );
    console.log( calculator.mul() );