Як вирішити помилку TypeError: неможливо перетворити невизначений або 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.keys(null)кидає TypeErrorзгадане. Щоб це виправити, скористайтеся if(obj === null) {return null}- без сутичок навколо null.
вепроза

1
Інша проблема: ваш код не обробляє можливість вбудованих "символів у рядки.
Пойнті

@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.keys(null)кидає TypeErrorзгадане. Щоб виправити це, використовуйте if(obj === null) {return null}- без позначок навколо null.


8
Виділіть: Object.keys(null)кидає TypeErrorзгадане".
falsarella

1
Додамо ще один поширений приклад, коли це трапляється: delete obj.propertyдеobj===null
Джо

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

У мене така сама проблема з елементом у веб-формі. Тож те, що я зробив, щоб це виправити, було перевірити. якщо (Object === 'null') щось робити

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.