Не удается получить длину массива

#javascript #arrays

#javascript #массивы

Вопрос:

Я пытаюсь создать бюджетный контроллер.
Когда я пытаюсь поместить элемент в массив, я получаю эту ошибку:

Неперехваченная ошибка типа: не удается прочитать свойство ‘length’ неопределенного

Ошибка в строке 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);
    }
}; 
})();
  

Комментарии:

1. в чем ошибка?

2. совершенно забыл указать это в lol. Ошибка является неперехваченной TypeError: не удается прочитать свойство ‘length’ из undefined

3. Ошибка сообщает вам, что это data.allItems[type] не undefined такой массив, как вы ожидаете. Чтобы выяснить, почему, воспользуйтесь советами из этой статьи , чтобы выяснить, что происходит. В частности, вы должны добавить console.log(type) и console.log(data.allItems[type]) , чтобы увидеть их значения.

Ответ №1:

Вероятно, data.allItems[type] не определено, потому что вы использовали с переменной type свойство, которое не определено. Просто добавьте console.log(type, data.allItems[type]); перед этой строкой и посмотрите результат.

Комментарии:

1. Я поместил эту консоль. войдите в систему, и я все еще получаю сообщение об ошибке: (

2. Конечно, вы получаете ошибку, это просто для получения дополнительной информации, почему вы ее получаете. Воспользуйтесь инструментами разработчика и посмотрите на вывод консоли. Вы можете запустить их в большинстве браузеров, нажав F12.

3. Я заставил это работать. Просто удалил консоль. войдите в систему полностью и протестируйте ее, запустив budgetcontrol.testing(). Спасибо!

Ответ №2:

Сначала проверьте, data.allItems[type] существует ли.

 if(data.allItems[type] amp;amp; 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)  

Комментарии:

1. Это сработает, но это может привести к более поздним ошибкам, если type был случайно установлен в неправильное значение, и поэтому OP получает неправильное значение из-за неправильных предположений. Так что лучше взгляните на значение type и добавьте свое улучшение дополнительно.