วิธีการแก้ไข TypeError: ไม่สามารถแปลงที่ไม่ได้กำหนดหรือ null เป็นวัตถุ


92

ฉันได้เขียนฟังก์ชันสองสามอย่างที่จำลอง 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 ที่ถูกต้อง
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

@Pointy - ใช่ฉันจะต้องเพิ่มตรรกะสำหรับสิ่งนั้น ... ขอบคุณ
zahabba

คำตอบ:


134

คำตอบทั่วไป

ข้อผิดพลาดนี้เกิดขึ้นเมื่อคุณเรียกใช้ฟังก์ชันที่คาดว่าObjectเป็นอาร์กิวเมนต์ แต่ส่งผ่านundefinedหรือnullแทนเช่น

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

ตามที่มักเกิดขึ้นโดยไม่ได้ตั้งใจวิธีแก้ปัญหาคือการตรวจสอบโค้ดของคุณและแก้ไขเงื่อนไขว่าง / ไม่ได้กำหนดเพื่อให้ฟังก์ชันได้รับObjectที่เหมาะสมหรือไม่ได้รับการเรียกใช้เลย

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}- โดยไม่มี qoutes รอบ null


8
ไฮไลต์: "และObject.keys(null)พ่นสิ่งที่TypeErrorกล่าวถึง"
falsarella

1
หากต้องการเพิ่มอีกตัวอย่างทั่วไปที่เกิดขึ้น: delete obj.propertyโดยที่obj===null
Gio

4

ตรวจสอบให้แน่ใจว่าวัตถุปลายทางไม่ว่างเปล่า ( nullหรือundefined)

คุณสามารถเริ่มต้นวัตถุปลายทางด้วยวัตถุว่างดังต่อไปนี้:

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

null เป็นวัตถุว่างเปล่า

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)

0

ตัวอย่างข้อมูลด้านล่างนี้เพียงพอที่จะเข้าใจว่าฉันพบปัญหาเดียวกันได้อย่างไร แต่อยู่ในสถานการณ์ที่แตกต่างออกไปและฉันจะแก้ไขได้อย่างไรโดยใช้คำแนะนำในคำตอบที่ยอมรับ ในกรณีของฉันฉันพยายามบันทึกคีย์ของวัตถุที่มีอยู่ในดัชนีที่ 0 ของอาร์เรย์ 'defaultViewData' โดยใช้เมธอด Object.keys ()

defaultViewData = [{"name": "DEFAULT_VIEW_PLP","value": {"MSH25": "LIST"}}] 

console.log('DEFAULT_VIEW', Object.keys(this.props.defaultViewData[0]));

console.log ไม่ได้รับการพิมพ์และฉันได้รับข้อผิดพลาดเดียวกันกับที่โพสต์ในคำถามนี้ เพื่อป้องกันข้อผิดพลาดนั้นฉันได้เพิ่มเงื่อนไขด้านล่าง

    if(this.props.defaultViewData[0]) {
  console.log('DEFAULT_VIEW', Object.keys(this.props.defaultViewData[0]));
}

การเพิ่มการตรวจสอบนี้ทำให้มั่นใจได้ว่าฉันไม่ได้รับข้อผิดพลาดนี้ ฉันหวังว่านี่จะช่วยใครบางคนได้

หมายเหตุ: นี่คือโค้ด React.js (แม้ว่าจะเข้าใจปัญหา แต่ก็ไม่สำคัญ)


-2

ฉันมีปัญหาเดียวกันกับองค์ประกอบในเว็บฟอร์ม สิ่งที่ฉันทำเพื่อแก้ไขคือการตรวจสอบความถูกต้อง ถ้า (Object === 'null') ทำอะไรบางอย่าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.