Jak rozwiązać błąd TypeError: Nie można przekonwertować wartości undefined lub null na obiekt


90

Napisałem kilka funkcji, które skutecznie replikują JSON.stringify (), konwertując zakres wartości na wersje z ograniczeniami. Kiedy przenoszę swój kod do JSBin i uruchamiam go na przykładowych wartościach, działa dobrze. Ale otrzymuję ten błąd w programie do uruchamiania specyfikacji zaprojektowanym do testowania tego.

Mój kod:

  // 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) + "";
    }
};

Komunikat o błędzie, który otrzymuję od testera to:

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)

Na przykład wygląda na to, że nie działa: stringifyJSON (null)


1
podaj dane wejściowe, dla których otrzymujesz błąd, ponieważ działa on dla stringifyJSON ({a: 'b', c: 'd'})
vinayakj

1
Oprócz błędu stringifyJSON([1,2,3])zwraca 1,2,3i stringifyJSON({foo: 'bar'})zwraca {foo: "bar"}, z których oba nie są poprawnymi kodami JSON.
Felix Kling

4
Domyślam się, że linia if (obj === 'null') { return null;} // null unchanged- nie przejdzie, gdy zostanie podana null, tylko jeśli zostanie podana jako ciąg "null". Więc jeśli przekażesz rzeczywistą nullwartość do swojego skryptu, zostanie ona przeanalizowana w części kodu Object. I Object.keys(null)wyrzuca TypeErrorwspomniane. Aby to naprawić, użyj if(obj === null) {return null}- bez qoutes dookoła null.
veproza

1
Kolejna kwestia: Twój kod nie obsługuje możliwości osadzania "znaków w łańcuchach.
Pointy

@Pointy - tak, muszę dodać do tego trochę logiki ... dziękuję
zahabba

Odpowiedzi:


131

Ogólna odpowiedź

Ten błąd jest spowodowany wywołaniem funkcji, która oczekuje obiektu jako argumentu, ale zamiast tego przekazuje wartość undefined lub null , jak na przykład

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

Ponieważ zwykle dzieje się to przez pomyłkę, rozwiązaniem jest sprawdzenie kodu i naprawienie warunku zerowego / niezdefiniowanego , tak aby funkcja albo otrzymała właściwy obiekt , albo w ogóle nie została wywołana.

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

Odpowiedź specyficzna dla danego kodu

Linia if (obj === 'null') { return null;} // null unchanged nie będzie oceniana, gdy zostanie podana null, tylko wtedy, gdy podany zostanie łańcuch "null". Więc jeśli przekażesz rzeczywistą nullwartość do swojego skryptu, zostanie ona przeanalizowana w części kodu Object. I Object.keys(null)wyrzuca TypeErrorwspomniane. Aby to naprawić, użyj if(obj === null) {return null}- bez qoutes wokół null.


8
Wyróżnij: „I Object.keys(null)wyrzuca TypeErrorwspomniane”.
falsarella

1
Aby dodać kolejny typowy przykład, gdzie to się dzieje: delete obj.propertygdzieobj===null
Gio

4

Upewnij się, że obiekt docelowy nie jest pusty ( nulllub undefined).

Możesz zainicjować obiekt docelowy pustym obiektem, jak poniżej:

var destinationObj = {};

Object.assign(destinationObj, sourceObj);

2

Jest to bardzo przydatne, aby uniknąć błędów podczas uzyskiwania dostępu do właściwości obiektów zerowych lub niezdefiniowanych.

null do niezdefiniowanego obiektu

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

undefined do pustego obiektu

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

null do pustego obiektu

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

0

Rozwiązałem ten sam problem w projekcie React Native. Rozwiązałem to używając tego.

let data = snapshot.val();
if(data){
  let items = Object.values(data);
}
else{
  //return null
}

0

W moim przypadku dodałem rozszerzenie Lucid do Chrome i nie zauważyłem w tym momencie problemu. Po około dniu pracy nad problemem i wywrócenia programu do góry nogami, w poście ktoś wspomniał o Lucidzie. Przypomniałem sobie, co zrobiłem, usunąłem rozszerzenie z Chrome i ponownie uruchomiłem program. Problem zniknął. Pracuję z Reactem. Pomyślałem, że to może pomóc.


0

Zastąpić

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

z

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

0

Jeśli używasz Laravel , mój problem dotyczył mojej trasy. Zamiast:

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

Napisałem:

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

a kiedy naprawiłem nazwę kontrolera, kod zadziałał!


0

W moim przypadku miałem dodatkową parę nawiasów ()

Zamiast

export default connect(
  someVariable
)(otherVariable)()

To musiało być

export default connect(
  someVariable
)(otherVariable)

-2

Mam ten sam problem z elementem w formularzu internetowym. Więc co zrobiłem, aby to naprawić, zostało potwierdzone. if (Object === 'null') zrób coś

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.