Как разрешить TypeError: невозможно преобразовать undefined или null в объект

90

Я написал несколько функций, которые эффективно реплицируют JSON.stringify (), преобразуя диапазон значений в строковые версии. Когда я переношу свой код на JSBin и запускаю его с некоторыми примерами значений, он работает нормально. Но я получаю эту ошибку в программе запуска спецификаций, предназначенной для проверки этого.

Мой код:

  // five lines of comments
  var stringify = function(obj) {
  if (typeof obj === 'function') { return undefined;}  // return undefined for function
  if (typeof obj === 'undefined') { return undefined;} // return undefined for undefined
  if (typeof obj === 'number') { return obj;} // number unchanged
  if (obj === 'null') { return null;} // null unchanged
  if (typeof obj === 'boolean') { return obj;} // boolean unchanged
  if (typeof obj === 'string') { return '\"' + obj + '\"';} // string gets escaped end-quotes
  if (Array.isArray(obj)) { 
    return obj.map(function (e) {  // uses map() to create new array with stringified elements
        return stringify(e);
    });
  } else {
    var keys = Object.keys(obj);   // convert object's keys into an array
    var container = keys.map(function (k) {  // uses map() to create an array of key:(stringified)value pairs
        return k + ': ' + stringify(obj[k]);
    });
    return '{' + container.join(', ') + '}'; // returns assembled object with curly brackets
  }
};

var stringifyJSON = function(obj) {
    if (typeof stringify(obj) != 'undefined') {
        return "" + stringify(obj) + "";
    }
};

Сообщение об ошибке, которое я получаю от тестера:

TypeError: Cannot convert undefined or null to object
    at Function.keys (native)
    at stringify (stringifyJSON.js:18:22)
    at stringifyJSON (stringifyJSON.js:27:13)
    at stringifyJSONSpec.js:7:20
    at Array.forEach (native)
    at Context.<anonymous> (stringifyJSONSpec.js:5:26)
    at Test.Runnable.run (mocha.js:4039:32)
    at Runner.runTest (mocha.js:4404:10)
    at mocha.js:4450:12
    at next (mocha.js:4330:14)

Кажется, что это не работает с: stringifyJSON (null), например

захабба
источник
1
предоставьте ввод, для которого вы получаете ошибку, так как он работает для stringifyJSON ({a: 'b', c: 'd'})
vinayakj
1
Помимо ошибки, stringifyJSON([1,2,3])возвращается 1,2,3и stringifyJSON({foo: 'bar'})возвращается {foo: "bar"}, оба из которых не являются допустимым JSON.
Феликс Клинг
4
Я предполагаю, что это будет эта строка if (obj === 'null') { return null;} // null unchanged- она ​​не пройдет, если задана null, только если задана строка "null". Итак, если вы передадите фактическое nullзначение вашему скрипту, оно будет проанализировано в части кода Object. И Object.keys(null)кидает TypeErrorупомянутый. Чтобы исправить это, используйте if(obj === null) {return null}- без кавычек null.
veproza
1
Другая проблема: ваш код не обрабатывает возможность встроенных "символов в строки.
Pointy
@Pointy - да, мне нужно добавить немного логики для этого ... спасибо
zahabba

Ответы:

131

Общий ответ

Эта ошибка возникает, когда вы вызываете функцию, которая ожидает объект в качестве аргумента, но вместо этого передаете undefined или null , например,

Object.keys(null)
Object.assign(window.UndefinedVariable, {})

Поскольку это обычно происходит по ошибке, решение состоит в том, чтобы проверить ваш код и исправить условие null / undefined, чтобы функция либо получала правильный объект , либо вообще не вызывалась.

Object.keys({'key': 'value'})
if (window.UndefinedVariable) {
    Object.assign(window.UndefinedVariable, {})
}

Ответ, относящийся к рассматриваемому коду

Строка if (obj === 'null') { return null;} // null unchanged не будет оцениваться, если дана null, только если дана строка "null". Итак, если вы передадите фактическое nullзначение вашему скрипту, оно будет проанализировано в части кода Object. И Object.keys(null)кидает TypeErrorупомянутый. Чтобы исправить это, используйте if(obj === null) {return null}- без кавычек вокруг нуля.

вепроза
источник
8
Выделите: «И Object.keys(null)кидает TypeErrorупомянутый».
falsarella
1
Чтобы добавить еще один распространенный пример, где это происходит: delete obj.propertyгдеobj===null
Gio
4

Убедитесь, что целевой объект не пуст ( nullили undefined).

Вы можете инициализировать целевой объект с пустым объектом, как показано ниже:

var destinationObj = {};

Object.assign(destinationObj, sourceObj);
Юврай Патил
источник
2

Это очень полезно, чтобы избежать ошибок при доступе к свойствам нулевых или неопределенных объектов.

от нуля до неопределенного объекта

const obj = null;
const newObj = obj || undefined;
// newObj = undefined

undefined для пустого объекта

const obj; 
const newObj = obj || {};
// newObj = {}     
// newObj.prop = undefined, but no error here

от нуля до пустого объекта

const obj = null;
const newObj = obj || {};
// newObj = {}  
// newObj.prop = undefined, but no error here
Банзи
источник
0

Я решил ту же проблему в проекте React Native. Я решил это с помощью этого.

let data = snapshot.val();
if(data){
  let items = Object.values(data);
}
else{
  //return null
}
зиггибаба
источник
0

В моем случае я добавил расширение Lucid в Chrome и в тот момент не заметил проблемы. Примерно через день работы над проблемой и переворачивания программы с ног на голову кто-то упомянул Lucid в посте. Я вспомнил, что сделал, удалил расширение из Chrome и снова запустил программу. Проблема исчезла. Я работаю с React. Я думал, это может помочь.

Бехзад Акбари
источник
0

Заменить

if (typeof obj === 'undefined') { return undefined;} // return undefined for undefined
if (obj === 'null') { return null;} // null unchanged

с участием

if (obj === undefined) { return undefined;} // return undefined for undefined 
if (obj === null) { return null;} // null unchanged
Гев
источник
0

Если вы используете Laravel , моя проблема заключалась в имени моего маршрута. Вместо:

Route::put('/reason/update', 'REASONController@update');

Я написал:

Route::put('/reason/update', 'RESONController@update');

и когда я исправил имя контроллера, код заработал!

Никодемос душ Сантуш
источник
0

В моем случае у меня была лишняя пара скобок ()

Вместо того

export default connect(
  someVariable
)(otherVariable)()

Это должно было быть

export default connect(
  someVariable
)(otherVariable)
Несущий справедливость
источник
-2

У меня такая же проблема с элементом в веб-форме. Итак, что я сделал, чтобы исправить это, было подтверждено. if (Object === 'null') что-то делать

Иван Фернандес
источник