开发者问题收集

无法获得数组的长度

2020-08-25
220

我正在尝试创建一个预算控制器。
当我尝试将一个项目推送到数组中时,出现此错误:

Uncaught TypeError: Cannot read property 'length' of undefined

错误发生在第 33 行,该行开始于:

if(data.allItems[type].length >0){

出了什么问题?

以下是完整代码:

var budgetController = (function(){

//function constructor
var Expense = function(id, description, value){
    this.id = id;
    this.description = description;
    this.value = value;
};

var Income = function(id, description, value){
    this.id = id;
    this.description = description;
    this.value = value;
};


var data = {
    allItems : {
        exp: [],
        inc: []
    },
    totals: {
        exp: 0,
        inc: 0
    }
    
};

return{
    addItem: function(type, des, val){
        var newItem, ID;
        //create new id
        if(data.allItems[type].length >0){
            ID = data.allItems[type][data.allItems[type].length - 1].id + 1;
        } else{
            ID = 0;
        }
        
        //create new item based off of inc or exp type
        if(type === 'exp'){
            newItem = new Expense(ID, des, val);
        } else if(type === 'inc'){
            newItem = new Income(ID, des, val);
        }

        //push onto data structure
        data.allItems[type].push(newItem);

        //return the new element
        return newItem;
    },

    testing: function(){
        console.log(data);
    }
}; 
})();
2个回答

可能 data.allItems[type] 未定义,因为您在变量 type 中使用了未定义的属性。只需在此行之前添加 console.log(type, data.allItems[type]); 并查找输出即可。

Sascha A.
2020-08-25

首先检查 data.allItems[type] 是否存在。

if(data.allItems[type] && data.allItems[type].length > 0){
    ID = data.allItems[type][data.allItems[type].length - 1].id + 1;
} else{
    ID = 0;
}

看起来您的 budgetController 的内部确实取决于参数 a) 存在和 b) 属于特定类型(或值)才能继续正常运行。

在这种情况下,您可能需要防止允许 budgetController 继续,如果提供的参数是意外的,则使用一些错误处理来停止执行。

var budgetController = (function() {

  //function constructor
  var Expense = function(id, description, value) {
    this.id = id;
    this.description = description;
    this.value = value;
  };

  var Income = function(id, description, value) {
    this.id = id;
    this.description = description;
    this.value = value;
  };

  var data = {
    allItems: {
      exp: [],
      inc: []
    },
    totals: {
      exp: 0,
      inc: 0
    }

  };

  return {
    addItem: function(type, des, val) {
      if (!Object.keys(data.allItems).includes(type)) {
        throw new Error(`Whoops! type must be one of ${Object.keys(data.allItems).join(', ')}`)
      }
      if (!des) {
        throw new Error(`Whoops! des is required`)
      }
      if (!val) {
        throw new Error(`Whoops! val is required`)
      }
      var newItem, ID;
      //create new id
      if (data.allItems[type].length > 0) {
        ID = data.allItems[type][data.allItems[type].length - 1].id + 1;
      } else {
        ID = 0;
      }

      //create new item based off of inc or exp type
      if (type === 'exp') {
        newItem = new Expense(ID, des, val);
      } else if (type === 'inc') {
        newItem = new Income(ID, des, val);
      }

      //push onto data structure
      data.allItems[type].push(newItem);

      //return the new element
      return newItem;
    },

    testing: function() {
      console.log(data);
    }
  };
})();


var myBudgetController = budgetController
myBudgetController.addItem('unacceptable type value', 'desc', 1)
ksav
2020-08-25