JavaScript对象:为什么不起作用?

时间:2018-08-21 06:31:05

标签: javascript javascript-objects

我编写了以下代码。它没有给出答案,而是输出NaN。我希望代码返回John和Mark的权重。请解释。

'use script';

//  Declaring variables
var infoJohn;
var infoMark;
var bmiCalculator;
var higherBmi;

bmiCalculator = function (height, mass) {
    var calculatedBmi;

    calculatedBmi = mass / (height * height);
    return calculatedBmi;
};

infoJohn = {
    name: 'John',
    mass: 85,
    height: 110,
    bmi: bmiCalculator(this.height, this.mass)
};

infoMark = {
    name: 'Mark',
    mass: 120,
    height: 85,
    bmi: bmiCalculator(this.height, this.mass)
};

console.log('Mark\'s BMI: ' + infoMark.bmi, 'John\'s BMI: ' + infoJohn.bmi, 
'\n\n');

7 个答案:

答案 0 :(得分:4)

您需要将bmiCalculator调用包装到function,因为否则this指的是全局(window)上下文。

这应该有效:

var bmiCalculator = function(height, mass) {
  var calculatedBmi;

  calculatedBmi = mass / (height * height);
  return calculatedBmi;
};

var infoJohn = {
  name: 'John',
  mass: 85,
  height: 110,
  bmi: function() {
    return bmiCalculator(this.height, this.mass);
  }
};

var infoMark = {
  name: 'Mark',
  mass: 120,
  height: 85,
  bmi: function() {
    return bmiCalculator(this.height, this.mass);
  }
};

//higherBmi = function (h)

console.log('Mark\'s BMI: ' + infoMark.bmi(), 'John\'s BMI: ' + infoJohn.bmi(),
  '\n\n');

答案 1 :(得分:2)

如果要使用this引用对象,可以使用getters

这里是一个例子:

'use strict'
//  Declaring variables
var infoJohn;
var infoMark;
var bmiCalculator;
var higherBmi;

bmiCalculator = function (height, mass) {
    var calculatedBmi;

    calculatedBmi = mass / (height * height);
    return calculatedBmi;
};

infoJohn = {
    name: 'John',
    mass: 85,
    height: 110,
    get bmi(){ 
      return bmiCalculator(this.height, this.mass);
    }
};

infoMark = {
    name: 'Mark',
    mass: 120,
    height: 85,
    get bmi(){ 
      return bmiCalculator(this.height, this.mass);
    }
};

console.log('Mark\'s BMI: ' + infoMark.bmi, 'John\'s BMI: ' + infoJohn.bmi, 
'\n\n');

与在您的示例中尝试在创建对象时设置bmi属性的示例不同,在这里,每次您访问bmiCalculator属性时,都会调用bmi函数对象之一。

答案 2 :(得分:1)

这应该有帮助:

'use strict';

//  Declaring variables
var infoJohn;
var infoMark;
var bmiCalculator;
var higherBmi;

var bmiCalculator = function(height, mass) {
  return mass / (height * height);
};

var infoJohn = {
  name: 'John',
  mass: 85,
  height: 110,
  get bmi() {
    return bmiCalculator(this.height, this.mass)
  }
};

var infoMark = {
  name: 'Mark',
  mass: 120,
  height: 85,
  get bmi() {
    return bmiCalculator(this.height, this.mass)
  }
};

console.log(`Mark's BMI: ${infoMark.bmi}, John's BMI: ${infoJohn.bmi}\n\n`);

这里没有什么要注意的:

bmiCalculator可以简单地作为返回值,因为它可以进行基本计算。 infoJohninfoMark bmi函数现在为getters,这使得它们可以在不带括号的情况下被调用,并且通过这种方式,我们在返回{{1 }}

最后,我们使用template literals

答案 3 :(得分:1)

实例化对象和利用this的方式就是问题。您正在使用对象文字,并且在为属性分配值时,this引用了window(或Node中的global)。

infoJohn = {
  ...
  bmi:  ... // here - this does not refer to infoJohn
}

可以在分配其他属性后修改您的代码以分配BMI属性,以使它们在通过bmiCalculator函数运行之前存在于对象上-但您仍然不会使用this。 / p>

infoJohn = {
  name: 'John',
  mass: 85,
  height: 110
};
infoJohn.bmi = bmiCalculator(infoJohn.height, infoJohn.mass)

如果要使用this,则它必须在正确的上下文中。这里还有其他一些答案,它们可以将BMI作为功能或吸气剂提供,这可能是一种更好的方法-每当高度或质量发生变化时,它们都会始终显示更新的BMI。

  // as a function property
  bmi: function(){ return this.mass / (this.height*this.height) }
  // or as a getter
  get bmi(){ return this.mass / (this.height*this.height) }

另一种重写现有内容的方法是采用一种更加面向对象的方法。例如

var Person = function(name, mass, height){
  this.name = name
  this.mass = mass
  this.height = height
  // assign a value as a static value - does not update
  this.bmi = mass / (height * height)
}

var infoJohn = new Person('John',85,110)
var infoMark = new Person('Mark',120,85)

console.log('Mark\'s BMI: ' + infoMark.bmi, 'John\'s BMI: ' + infoJohn.bmi, '\n\n');

infoMark.mass = 110
console.log('Mark\'s new BMI: '+ inforMark.bmi) // will not update

答案 4 :(得分:0)

您正在使用之前未定义的变量!在变量定义之前放置var,以便程序应该知道您在说什么。同样,您不能直接在对象中调用函数!您应该使用另一个函数来调用所需的函数。像这样:

var infoJohn = {
    name: 'John',
    mass: 85,
    height: 110,
    bmi: function() {
        return bmiCalculator(this.height, this.mass);
    }
};

因此,之后必须使用bmi作为函数:

console.log('Mark\'s BMI: ' + infoMark.bmi(), 'John\'s BMI: ' + infoJohn.bmi(), '\n\n');

答案 5 :(得分:0)

  

使用 getter 功能。

infoJohn = {
    name: 'John',
    mass: 85,
    height: 110,
    bmi: bmiCalculator(this.height, this.mass) // . <<--This is incorrect
};

在这里,对象未指向您所期望的infoJohn对象。相反,它指向全局window对象(如果使用的是客户端JS)。而且,由于没有window.heightwindow.mass属性,它将通过undefined作为您的参数 bmiCalculator功能。对非数字值(例如undefined)进行数学运算会得出NaN。因此,您将得到相同的结果。您可以按以下步骤纠正此问题:

bmiCalculator = function (height, mass) {
    var calculatedBmi;

    calculatedBmi = mass / (height * height);
    return calculatedBmi;
};

infoJohn = {
    name: 'John',
    mass: 85,
    height: 110,
    get bmi() { return bmiCalculator(this.height, this.mass)}
};

console.log(infoJohn.bmi);

答案 6 :(得分:0)

更优雅的方式...

const bmiCalculator = (height, mass) => mass / (height * height);

const infoJohn = {
    name: 'John',
    mass: 85,
    height: 110,
    get bmi() {
        return bmiCalculator(this.height, this.mass);
    }
};

console.log(infoJohn.bmi);