Bagaimana mengatasi TypeError: Tidak dapat mengubah undefined atau null menjadi objek

90

Saya telah menulis beberapa fungsi yang secara efektif mereplikasi JSON.stringify (), mengubah rentang nilai menjadi versi yang dirangkai. Ketika saya mem-port kode saya ke JSBin dan menjalankannya pada beberapa nilai sampel, itu berfungsi dengan baik. Tapi saya mendapatkan kesalahan ini di pelari spesifikasi yang dirancang untuk menguji ini.

Kode saya:

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

Pesan kesalahan yang saya dapatkan dari penguji adalah:

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)

Tampaknya gagal dengan: stringifyJSON (null) misalnya

zahabba
sumber
1
berikan masukan yang Anda dapatkan kesalahannya, karena ini berfungsi untuk stringifyJSON ({a: 'b', c: 'd'})
vinayakj
1
Selain kesalahan, stringifyJSON([1,2,3])pengembalian 1,2,3dan stringifyJSON({foo: 'bar'})pengembalian {foo: "bar"}, keduanya bukan JSON yang valid.
Felix Kling
4
Dugaan saya adalah baris ini if (obj === 'null') { return null;} // null unchanged, - yang tidak akan lewat saat diberikan null, hanya jika diberi string "null". Jadi jika Anda meneruskan nilai sebenarnya nullke skrip Anda, itu akan diurai di bagian Objek kode. Dan Object.keys(null)melempar yang TypeErrordisebutkan. Untuk memperbaikinya, gunakan if(obj === null) {return null}- tanpa qoutes null.
veproza
1
Masalah lain: kode Anda tidak menangani kemungkinan "karakter yang disematkan dalam string.
Pointy
@Pointy - ya, saya perlu menambahkan beberapa logika untuk itu ... terima kasih
zahabba

Jawaban:

131

Jawaban umum

Kesalahan ini terjadi saat Anda memanggil fungsi yang mengharapkan Objek sebagai argumennya, tetapi meneruskan undefined atau null sebagai gantinya, seperti misalnya

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

Karena itu biasanya karena kesalahan, solusinya adalah memeriksa kode Anda dan memperbaiki kondisi null / undefined sehingga fungsi tersebut mendapatkan Objek yang tepat , atau tidak dipanggil sama sekali.

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

Jawaban khusus untuk kode yang dimaksud

Garis if (obj === 'null') { return null;} // null unchanged tidak akan dievaluasi saat diberikan null, hanya jika diberi string "null". Jadi jika Anda meneruskan nilai sebenarnya nullke skrip Anda, itu akan diurai di bagian Objek kode. Dan Object.keys(null)melempar yang TypeErrordisebutkan. Untuk memperbaikinya, gunakan if(obj === null) {return null}- tanpa qoutes di sekitar null.

veproza.dll
sumber
8
Sorot: "Dan Object.keys(null)melempar yang TypeErrordisebutkan."
falsarella
1
Untuk menambahkan contoh umum lainnya di mana ini terjadi: di delete obj.propertymanaobj===null
Gio
4

Pastikan objek tujuan tidak kosong ( nullatau undefined).

Anda dapat menginisialisasi objek tujuan dengan objek kosong seperti di bawah ini:

var destinationObj = {};

Object.assign(destinationObj, sourceObj);
Yuvraj Patil
sumber
2

Ini sangat berguna untuk menghindari kesalahan saat mengakses properti dari objek null atau tidak terdefinisi.

null ke objek yang tidak ditentukan

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

tidak ditentukan ke objek kosong

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

null untuk mengosongkan objek

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

Saya memecahkan masalah yang sama dalam proyek React Native. Saya menyelesaikannya menggunakan ini.

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

Dalam kasus saya, saya menambahkan ekstensi Lucid ke Chrome dan tidak melihat masalah pada saat itu. Setelah sekitar satu hari mengerjakan masalah dan membalikkan program, dalam sebuah posting seseorang menyebut Lucid. Saya ingat apa yang telah saya lakukan dan menghapus ekstensi dari Chrome dan menjalankan program lagi. Masalahnya hilang. Saya bekerja dengan React. Saya pikir ini mungkin membantu.

Behzad Akbari
sumber
0

Menggantikan

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

dengan

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

Jika Anda menggunakan Laravel , masalah saya adalah pada nama Route saya. Sebagai gantinya:

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

Saya menulis:

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

dan ketika saya memperbaiki nama pengontrol, kodenya berfungsi!

Nicodemos dos Santos
sumber
0

Dalam kasus saya, saya memiliki sepasang tanda kurung tambahan ()

Dari pada

export default connect(
  someVariable
)(otherVariable)()

Itu harus

export default connect(
  someVariable
)(otherVariable)
Justice Bringer
sumber
-2

Saya memiliki masalah yang sama dengan elemen di formulir web. Jadi apa yang saya lakukan untuk memperbaikinya adalah validasi. jika (Object === 'null') melakukan sesuatu

Ivan Fernandez
sumber