24. Can you iterate through a constructor with a method


#1


https://www.codecademy.com/en/courses/spencer-sandbox/3/5

I passed this lesson but as an extra step I wanted to see if I could iterate through the constructer using a for property in object loop and the result looks funny when it prints the method portions.

function Rectangle(height, width) {
  this.height = height;
  this.width = width;
  
  this.calcArea = function() {
      return this.height * this.width;
  };
  
  this.calcPerimeter = function () {
      return (this.height + this.width) * 2;
  };
}

var rex = new Rectangle(7,3);
var area = rex.calcArea();
var perimeter = rex.calcPerimeter();

for (key in rex) {
    console.log(key + ': ' + rex[key]); 
}

#2

You're actually iterating over the instance object, not the constructor. for..in will enumerate all the properties of the object, including methods which will log out in their .toString() form.

height: 7
width: 3
calcArea: function () {
      return this.height * this.width;
  }
calcPerimeter: function () {
      return (this.height + this.width) * 2;
  }

This is expected. If you only wish to see the values, not the functions, then filter that type in your loop.

for (var key in rex) {
    if (typeof rex[key] != 'function') {
        console.log(key + ': ' + rex[key]);
    }
}
height: 7
width: 3

There is another way to limit the output, which you may not have covered yet so ignore if this is new. It will come up shortly. By adding the methods to the prototype chain of Rectangle, and not writing them as direct properties, then we can check the hasOwnProperty() on the keys. Only direct properties will be logged.

function Rectangle(height, width) {
    this.height = height;
    this.width = width;  
}
Rectangle.prototype.calcArea = function() {
    return this.height * this.width;
};
  
Rectangle.prototype.calcPerimeter = function () {
    return (this.height + this.width) * 2;
};

var rex = new Rectangle(7,3);

for (var key in rex) {
    if (rex.hasOwnProperty(key)) {
        console.log(key + ': ' + rex[key]);
    }
}
height: 7
width: 3

#3

Thanks for the explanation @mtf . I was hoping for the output to look something like...

height: 7
width: 3
area: 21
perimeter: 20

#4

In that case, we can invoke any methods we encounter (assuming no parameters are needed)

for (var key in rex) {
    if (typeof rex[key] != 'function') {
        console.log(key + ': ' + rex[key]);
    }
    else {
        console.log(key.substring(4) + ": " + rex[key]());
    }
}
height: 7
width: 3
Area: 21
Perimeter: 20

#5

This is brilliant, Thank you @mtf !


#6

@jaydacoder,
Another approach would be

function Rectangle(height, width) {
   var private_var = "vv";
   this.height = height;
   this.width = width;
   // private function (not visible to the FOR-IN loop)
   var calcArea = function(h,w) {
                       return h * w;
                  };
   // private function (not visible to the FOR-IN loop)
   var calcPerimeter = function (h,w) {
                           return (h + w) * 2;
                       };
   this.area = calcArea(this.height,this.width);
   this.perimeter = calcPerimeter(this.height,this.width);
}

var rex = new Rectangle(7,3);
console.log( rex);

#7

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.