TypeError: Cannot read properties of undefined (reading 'x')जावास्क्रिप्ट में सबसे आम रनटाइम त्रुटि है। एक बार जब आप इसे पढ़ना सीख जाते हैं तो संदेश सटीक हो जाता है, और फिक्स लगभग हमेशा पांच पैटर्न में से एक होता है। यह मार्गदर्शिका बताती है कि कारण का तुरंत पता कैसे लगाया जाए और इसकी पुनरावृत्ति को कैसे रोका जाए।
📋 Table of Contents
- त्रुटि का वास्तव में क्या मतलब है
- कारण 1: Async डेटा आने से पहले पढ़ा जाता है
- आपने लिखा
- रिटर्न
- डिस्ट्रक्टिंग गुणों को पढ़ता है, इसलिए यह बिल्कुल उसी कारण से फेंकता है – बस कम स्पष्ट स्टैक लाइन के साथ।
- अपना बंधन खो दियाthisजब किसी विधि को कॉलबैक के रूप में पारित किया जाता है,
- वैकल्पिक श्रृखंला
- जब त्रुटि दिखाई दे तो इस क्रम पर काम करें।
- टाइपस्क्रिप्ट
- प्रश्न: इसमें और "शून्य के गुण नहीं पढ़ सकते" के बीच क्या अंतर है?
- निष्कर्ष
त्रुटि का वास्तव में क्या मतलब है
आपने किसी ऐसी चीज़ से एक गुण पढ़ने का प्रयास किया जोundefinedहै . कोष्ठक का भाग आपको बताता है कि आपने किस गुण को पढ़ने का प्रयास किया।
const user = undefined;
console.log(user.name);
// TypeError: Cannot read properties of undefined (reading 'name')
महत्वपूर्ण अंतर्दृष्टि:समस्या संपत्ति नहीं है, यह बिंदु से पहले की चीज़ है। जब देखो(reading 'name'), बग यह है कि जो कुछ भी उपयोगकर्ता ऑब्जेक्ट को धारण करना चाहिए वहundefinedहै . हर कोई डिबगिंग में समय बर्बाद करता हैname जबकि उन्हें पूछना चाहिए कि क्योंuser खाली है.
एक श्रृंखला में, पहला अपरिभाषित लिंक ढूंढने के लिए बाएं से दाएं काम करें।
const response = { data: { items: [] } };
console.log(response.data.results.length);
// TypeError: Cannot read properties of undefined (reading 'length')
// 'results' does not exist on data, so response.data.results is undefined.
कारण 1: Async डेटा आने से पहले पढ़ा जाता है
वास्तविक अनुप्रयोगों में अब तक का सबसे आम कारण। स्थिति खाली प्रारंभ होती है, रेंडर चलता है, और फ़ेच अभी तक हल नहीं हुआ है।
function Profile({ userId }) {
const [user, setUser] = useState(); // undefined on first render
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(r => r.json())
.then(setUser);
}, [userId]);
return <h1>{user.name}</h1>; // throws on the very first render
}
एक समझदार खाली मान को आरंभ करके और रेंडर की सुरक्षा करके ठीक करें।
function Profile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let cancelled = false;
setLoading(true);
fetch(`/api/users/${userId}`)
.then(r => {
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return r.json();
})
.then(data => { if (!cancelled) setUser(data); })
.catch(err => { if (!cancelled) console.error(err); })
.finally(() => { if (!cancelled) setLoading(false); });
return () => { cancelled = true; };
}, [userId]);
if (loading) return <p>Loading…</p>;
if (!user) return <p>User not found.</p>;
return <h1>{user.name}</h1>;
}
ध्वज दूसरे सामान्य बग को भी रोकता है: पिछलेcancelledसे धीमी प्रतिक्रिया प्रोप बदलने के बाद नए डेटा को ओवरराइट करना।userIdकारण 2: एपीआई प्रतिक्रिया आकार वह नहीं है जो आपने माना था
आपने लिखा
लेकिन एपीआई रिटर्नdata.items, या यह हर चीज़ को{ results: [...] }में लपेट देता है . एक्सियोस के साथ गलती करना विशेष रूप से आसान है, जो अपना खुद का{ data: { ... } }जोड़ता है प्रतिक्रिया निकाय के शीर्ष पर रैपर।dataइसमें अनुक्रमणित करने से पहले संपूर्ण प्रतिक्रिया लॉग करें। एक
// Axios puts the response body in .data — so the payload is often data.data
const response = await axios.get('/api/users');
console.log(response.data.users); // correct
console.log(response.users); // undefined -> throws downstream
प्रश्न का तुरंत उत्तर देता है, जहां अनुमान लगाना संभव नहीं होता।console.log(JSON.stringify(response, null, 2))कारण 3: सारणी खोज विधियाँ जिनमें कुछ नहीं मिला
रिटर्न
find जब कोई तत्व मेल नहीं खाता है, और यह सूची-हैंडलिंग कोड में त्रुटि का सबसे आम स्रोत है।undefinedपरिणाम को हमेशा संभवतः गायब मानें।
const users = [{ id: 1, name: 'Ada' }];
const match = users.find(u => u.id === 99);
console.log(match.name);
// TypeError: Cannot read properties of undefined (reading 'name')
यही बात
const match = users.find(u => u.id === 99);
if (!match) {
return null; // or throw a clear domain error
}
console.log(match.name);
// Or with optional chaining when a missing value is acceptable:
console.log(match?.name ?? 'Unknown user');
पर भी लागू होती है , जो रिटर्नdocument.querySelector जब कुछ भी मेल नहीं खाता, औरnull औरMap.getकारण 4: एक अपरिभाषित वस्तु को नष्ट करनाArray.at.
डिस्ट्रक्टिंग गुणों को पढ़ता है, इसलिए यह बिल्कुल उसी कारण से फेंकता है – बस कम स्पष्ट स्टैक लाइन के साथ।
पैरामीटर को एक डिफ़ॉल्ट दें ताकि डिस्ट्रक्चर में हमेशा काम करने के लिए एक ऑब्जेक्ट हो।
function greet({ name }) {
return `Hello ${name}`;
}
greet();
// TypeError: Cannot destructure property 'name' of 'undefined'
कारण 5:
function greet({ name = 'friend' } = {}) {
return `Hello ${name}`;
}
greet(); // "Hello friend"
greet({ name: 'Ada' }); // "Hello Ada"
अपना बंधन खो दियाthisजब किसी विधि को कॉलबैक के रूप में पारित किया जाता है,
अब वस्तु नहीं है, इसलिए इस पर पढ़ी गई प्रत्येक संपत्ति विफल हो जाती है।thisइसे बाइंड करें, या एरो फ़ंक्शन वाले क्लास फ़ील्ड का उपयोग करें, जो
class Counter {
constructor() { this.count = 0; }
increment() { this.count++; } // 'this' is undefined when detached
}
const c = new Counter();
button.addEventListener('click', c.increment);
// TypeError: Cannot read properties of undefined (reading 'count')
को कैप्चर करता है शाब्दिक रूप से।thisउपकरण जो इसे रोकते हैं
class Counter {
count = 0;
increment = () => { this.count++; }; // arrow field — always bound
}
const c = new Counter();
button.addEventListener('click', c.increment); // works
वैकल्पिक श्रृखंला
शॉर्ट-सर्किट से फेंकने के बजाय.undefinedअशक्त सहवास
const city = user?.address?.city; // undefined, no throw
const first = users?.[0]?.name; // works on arrays too
const result = api.getUser?.(id); // and on possibly-missing methods
केवलके लिए फ़ॉलबैक प्रदान करता है औरnull, विपरीतundefined जो||को भी प्रतिस्थापित करता है और खाली तार.0वैकल्पिक शृंखला का उपयोग करें जहां गायब मान वास्तव में मान्य है। त्रुटियों को शांत करने के लिए इसे हर जगह न बिखेरें – यदि
const count = data?.count ?? 0; // 0 stays 0
const wrong = data?.count || 0; // a real 0 becomes 0 anyway, but '' becomes 0 too
उस बिंदु तक हमेशा अस्तित्व में रहना चाहिए, इसकी अनुपस्थिति को छिपाने से एक ज़ोरदार बग एक मूक बग में बदल जाता है जो बाद में बिना किसी स्टैक ट्रेस के सामने आता है।userडिबगिंग विधि
जब त्रुटि दिखाई दे तो इस क्रम पर काम करें।
कोष्ठक में संपत्ति का नाम पढ़ें. बग अभिव्यक्ति में है
- पहले वह संपत्ति.स्टैक ट्रेस खोलें और लाइब्रेरी फ़्रेमों को अनदेखा करते हुए, अपने कोड में सबसे ऊपरी फ़्रेम पर क्लिक करें।
- उस लाइन पर एक ब्रेकप्वाइंट सेट करें और युक्त अभिव्यक्ति का निरीक्षण करें, संपत्ति का नहीं।
- अपरिभाषित पहला लिंक ढूंढने के लिए श्रृंखला पर बाएं से दाएं चलें।
- पूछें कि वह मान खाली क्यों है – क्या फ़ेच का समाधान नहीं हुआ, क्या कोई खोज छूट गई, क्या कोई प्रोप कभी पारित नहीं हुआ?
- उत्पादन में, स्रोत मानचित्र आवश्यक हैं। उनके बिना न्यूनतम कोड पर ट्रेस पॉइंट और यह प्रक्रिया असंभव है।
इसे संरचनात्मक रूप से रोकना
टाइपस्क्रिप्ट
इनमें से अधिकांश को संकलन समय पर पकड़ता है, विशेष रूप सेके साथ सक्षम. यह आपको कोड चलने से पहले अपरिभाषित मामले को संभालने के लिए बाध्य करता है।strictNullChecksसीमाओं पर मान्य करें.
function getName(user: User | undefined): string {
// Error: 'user' is possibly 'undefined' — caught before runtime
return user.name;
}
ज़ोड जैसे स्कीमा सत्यापनकर्ता के साथ पार्स एपीआई प्रतिक्रियाएं, इसलिए एक अप्रत्याशित आकार आपके रेंडरिंग कोड में एक अपरिभाषित तीन परतों को प्रचारित करने के बजाय एक स्पष्ट संदेश के साथ तुरंत विफल हो जाता है।खाली संग्रह लौटाएँ, अपरिभाषित नहीं।
एक फ़ंक्शन जोलौटाता है इसके बजाय[] कॉल करने वालों को बिना किसी शर्त के परिणाम देखने की सुविधा देता है।undefinedअक्सर पूछे जाने वाले प्रश्न
प्रश्न: इसमें और “शून्य के गुण नहीं पढ़ सकते” के बीच क्या अंतर है?
ए: केवल मूल्य.
आमतौर पर इसका मतलब है कि कोई वैरिएबल कभी असाइन नहीं किया गया था या कोई संपत्ति मौजूद नहीं है; undefined आमतौर पर इसका मतलब है कि कुछ स्पष्ट रूप से इसे खाली पर सेट करता है। डिबगिंग दृष्टिकोण समान है.nullप्रश्न: क्या मुझे हर जगह वैकल्पिक चेनिंग जोड़नी चाहिए?
प्रश्न: क्या मुझे हर जगह वैकल्पिक चेनिंग जोड़नी चाहिए?
उ: नहीं। इसका उपयोग वहां करें जहां कोई मान वैध रूप से वैकल्पिक है। किसी त्रुटि को शांत करने के लिए इसका उपयोग करना जिसे आप नहीं समझते हैं, स्टैक ट्रेस के साथ क्रैश को बिना किसी ट्रेस के गलत व्यवहार में परिवर्तित कर देता है।
प्रश्न: यह स्थानीय स्तर पर काम क्यों करता है लेकिन उत्पादन में विफल रहता है?
उत्तर: आमतौर पर समय या डेटा। स्थानीय एपीआई तेजी से प्रतिक्रिया करते हैं, इसलिए दौड़ की स्थितियाँ छिप जाती हैं; और उत्पादन डेटा में ऐसे आकार होते हैं जो आपके परीक्षण डेटा में नहीं होते हैं, जैसे अनुपलब्ध वैकल्पिक फ़ील्ड वाले रिकॉर्ड।
प्रश्न: जब स्टैक ट्रेस केवल लाइब्रेरी कोड दिखाता है तो मैं त्रुटि कैसे ढूंढूं?
उ: स्रोत मानचित्र सक्षम करें, फिर फ़्रेमवर्क फ़्रेम को छिपाने के लिए Chrome DevTools में “इग्नोर लिस्ट” का उपयोग करें ताकि सबसे ऊपर दिखाई देने वाला फ़्रेम आपका अपना कोड हो।
प्रश्न: क्या टाइपस्क्रिप्ट इस त्रुटि को पूरी तरह से समाप्त कर देता है?
उत्तर: नहीं। यह उस कोड को हटा देता है जिसे वह सत्यापित कर सकता है, लेकिन डेटा रनटाइम सीमाओं को पार कर जाता है – एपीआई प्रतिक्रियाएं, JSON पार्सिंग,any कास्ट – रनटाइम पर अभी भी अपरिभाषित हो सकता है। टाइपस्क्रिप्ट में भी बाहरी डेटा को मान्य करें।
निष्कर्ष
फिक्सिंगCannot read properties of undefined एक बार जब आप नियम जान लें तो यह यांत्रिक है:त्रुटि संपत्ति से पहले अभिव्यक्ति में है, संपत्ति में नहीं। पाँच सामान्य कारणों की जाँच करें – एसिंक डेटा बहुत जल्दी पढ़ा गया, एक बेमेल एपीआई आकार, एकfind जो किसी भी चीज़ से मेल नहीं खाता, एक अनुपस्थित वस्तु को नष्ट कर देता है, और एक खो जाता हैthis बंधन. फिर वैकल्पिक श्रृंखला के साथ पुनरावृत्ति को रोकें जहां मान वास्तव में वैकल्पिक हैं, टाइपस्क्रिप्टstrictNullChecksके साथ , और प्रत्येक सीमा पर स्कीमा सत्यापन जहां बाहरी डेटा आपके सिस्टम में प्रवेश करता है।
🔗 Share this article
✍️ Leave a Comment