0

I'm trying to use an existing function inside an object.

So far, all the answers I have seen focused on creating a new function inside an object, but I want to use an existing function inside an object. However, I am getting NaN as the output when I call the property name of the object.

The minimal reproducible code for my output is this:

    function bmiCalculator(weight, height) {
    bmi = weight/(height**2)
    return bmi;

}


var markDetails = {
    name:  "Mark",
    weight: 70,
    height: 175,
    bmi: bmiCalculator(this.weight,this.height),
    error: console.log(this.weight)

};



console.log(markDetails)

The problem seems to lie with the this.weight and this.height object definitions because they return NaN when I console.log(this.weight). But, I don't know exactly what went wrong

  • `this` isn't in the scope that you think it is. The easiest way to do this, especially if you expect to handle details for multiple people, is a constructor. – emsoff Apr 22 '20 at 04:54
  • Thanks for your suggestion, I followed it and have done it this way: `function Person(name,weight,height,bmi){ this.name = name; this.weight = weight; this.height = height; this.bmi = function bmiCalculator() { bmi = this.weight/(this.height**2) return bmi; } } var mark = new Person("Mark", 70, 1.75); var john = new Person("John", 80, 1.75);` Is this the most elegant way to approach this kind of problem? – Tan Kin Meng Apr 22 '20 at 07:03

2 Answers2

1

The problem is this in your objects is the window object, so when you do this.weight is undefined. So you need to change the scope of this to point to the current object, you can either do it within a function or getter.

use getters

var johnDetails = {
    name:  "John",
    weight: 80,
    height: 175,
    get bmi() {
      return bmiCalculator(this.weight,this.height)
  }
};

and then access it like this

johnDetails.bmi

use function

var johnDetails = {
    name:  "John",
    weight: 80,
    height: 175,
    bmi() {
      return bmiCalculator(this.weight,this.height)
  }
};

and then access it like this

johnDetails.bmi()
Andy Song
  • 4,404
  • 1
  • 11
  • 29
0

Since you've mentioned in the comments you've gone with a constructor approach. A constructor just initializes an object. Because it is really just a function, this would be in the function's scope.

function bmiCalculator(weight, height) {
    bmi = weight/(height**2)
    return bmi;
}

function Person(name, weight, height) {
    this.name = name;
    this.weight = weight;
    this.height = height;
    this.bmi = bmiCalculator(this.weight, this.height);
    // or this.bmi = bmiCalculator(weight, height)
}

var markDetails = new Person('Mark', 70, 175);

However, you don't really need this in this case. You can do the following:

function Person(name, weight, height) {
  return {
    name : name,
    weight: weight,
    height: height, 
    bmi : bmiCalculator(weight, height)
  }
}

This is the way I would personally do it. Getters are another good option, depending on how you want to interact with the object afterwards.

emsoff
  • 1,585
  • 2
  • 11
  • 16