如何解决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 2015年

1
除了错误之外,stringifyJSON([1,2,3])return1,2,3stringifyJSON({foo: 'bar'})return{foo: "bar"}都是无效的JSON。
Felix Kling

4
我的猜测是这行if (obj === 'null') { return null;} // null unchanged,-null仅在给出字符串的情况下才会通过"null"。因此,如果将实际null值传递给脚本,它将在代码的“对象”部分中进行解析。并Object.keys(null)抛出TypeError提及。要解决此问题,请使用if(obj === null) {return null}-,不要使用qoutes null
veproza

1
另一个问题:您的代码无法处理"字符串中嵌入字符的可能性。
Pointy 2015年

@Pointy-是的,我需要为此添加一些逻辑...谢谢您
zahabba 2015年

Answers:


131

通用答案

当您调用以Object为参数的函数,但传递undefinednull时(例如,例如),则会导致此错误

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

因为通常这是错误的,所以解决方案是检查您的代码并修复null / undefined条件,以使该函数获得正确的Object或根本不被调用。

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

针对特定代码回答

仅当给出字符串if (obj === 'null') { return null;} // null unchangednull,该行在给出时不求值"null"。因此,如果将实际null值传递给脚本,它将在代码的“对象”部分中进行解析。并Object.keys(null)抛出TypeError提及。要解决此问题,请使用if(obj === null) {return null}-不使用null周围的qoutes。


8
突出显示:“并Object.keys(null)抛出TypeError提及。”
falsarella

1
在发生这种情况的delete obj.property地方添加另一个常见示例:whereobj===null
Gio

4

确保目标对象不为空(nullundefined)。

您可以使用空对象初始化目标对象,如下所示:

var destinationObj = {};

Object.assign(destinationObj, sourceObj);

2

这对于避免访问null或未定义对象的属性时发生错误非常有用。

空到未定义的对象

const obj = null;
const newObj = obj || undefined;
// newObj = 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

就我而言,我在Chrome中添加了Lucid扩展程序,但当时没有注意到问题。经过大约一天的时间解决问题并将程序颠倒了之后,有人在帖子中提到了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)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.