当对象属性不存在时返回值

时间:2017-12-08 23:52:34

标签: javascript arrays object

对我的代码运行测试。如果传递给函数的属性不存在,则应返回0。但它没有返回任何东西。我输错了吗?

var obj = {
  key: [1, 2, 3]
};

function getAverageOfElementsAtProperty(obj, key) {
  if (obj[key].length === 0 || Array.isArray(obj[key]) === false || obj.hasOwnProperty(key) === false) {
    return 0;
  }
  var average = 0;
  for (var i = 0; i < obj[key].length; i++) {
    average += obj[key][i];
  }
  average /= obj[key].length;
  return average;
}

console.log(getAverageOfElementsAtProperty(obj, 'notKey'));

2 个答案:

答案 0 :(得分:3)

如果你没有将数组传递给你的函数,它在尝试获取传递的对象的length时会失败,所以这不应该是你最初测试的方式。您只需要查看该属性是否存在,并且只需尝试以if条件访问该属性即可完成。

现在,如果您要添加测试以查看属性是否存在以及它是否为数组,那么您必须添加更多测试以检查数组中的项目以查看它们是否为数字,否则尝试得到一个数字平均值将失败。

由于确实有两件事要做(检查属性是否存在并获得数学平均值),我会将其分解为两个函数:

var obj1 = {
  key: [1, 2, 3]
};

var obj2 = {
  key: [1, "test", 3]
};

function getAverageOfElementsAtProperty(obj, key) {
  if (obj[key] && Array.isArray(obj[key])) { 
    // Ok, we have the right property and there is an array there,
    // now we have to test that each item in the array is a number
    var numbers = obj[key].every(function (currentValue) {
      return typeof currentValue === "number";
    });
    
    // Return the average if we have all numbers or 0 if not
    return numbers ? getAverage(obj[key]) : 0;
  } else {
    return 0;
  }
}

function getAverage(arr){
  var average = 0;
  // Array.forEach() is much simpler than counting loops
  arr.forEach(function(item) {
    average += item;
  });
  return average / arr.length;
}

console.log(getAverageOfElementsAtProperty(obj1, 'notkey'));  // 0
console.log(getAverageOfElementsAtProperty(obj1, 'key'));     // 2
console.log(getAverageOfElementsAtProperty(obj2, 'key'));     // 0 - obj2 does not contain all numbers

答案 1 :(得分:1)

由于obj['notKey']不存在,因此不会返回数组。因此,您无法执行未定义的.length。我会将其更改为typeof以查看其是否已定义。

var obj = {
  key: [1, 2, 3]
};

function getAverageOfElementsAtProperty(obj, key) {

  if (typeof obj[key] == 'undefined' || Array.isArray(obj[key]) === false || obj.hasOwnProperty(key) === false) {
    return 0;
  }

  var average = 0;
  for (var i = 0; i < obj[key].length; i++) {
    average += obj[key][i];
  }
  average /= obj[key].length;
  return average;
}

console.log(getAverageOfElementsAtProperty(obj, 'notKey'));