DanLevy.net

क्विज़: डीस्ट्रक्चरिंग का आनंद

क्या आप डीस्ट्रक्चरिंग में माहिर हैं?

या यह आपका विनाश का सिम्फनी है?

यह क्विज़ जावास्क्रिप्ट में डेस्ट्रक्चरिंग की आपकी समझ का परीक्षण करेगा: “बेसिक” ऑब्जेक्ट सिंटैक्स से लेकर नेस्टेड डेस्ट्रक्चरिंग और डिफ़ॉल्ट वैल्यूज़ तक। साथ ही टाइपस्क्रिप्ट और इनलाइन टाइप्स पर बोनस प्रश्न भी शामिल हैं!

सीधे वार्म‑अप पर जाएँ – अपनी डेस्ट्रक्चरिंग कौशल साबित करें! 👇

इस कोड का आउटपुट क्या होगा?

const person = {
name: 'Dan Levy',
location: 'Cape Town',
};
const { name, age } = person;
console.log(`Name: ${name}, Age: ${age}`);

age प्रॉपर्टी person में मौजूद नहीं है, इसलिए age undefined रहेगा। निश्चित रूप से Infinity नहीं 😅

इसका परिणाम है:

Name: Dan Levy, Age: undefined

यह कोड क्या करेगा?

const person = [ 'Dan Levy', 'Cape Town' ];
const [ name, origin, age ] = person;
console.log(`Name: ${name}, Age: ${age}`);

age वेरिएबल tuple एरे में मौजूद नहीं है, इसलिए यह undefined होगा।

इसका परिणाम है:

Name: Dan Levy, Age: undefined

नेस्टेड डीस्ट्रक्चरिंग के बारे में क्या ख्याल है?

'use strict';
const person = {
name: { first: 'Dan' },
address: { city: 'Denver' },
};
const {
name: { first },
address: { city },
birth: { place },
} = person;
console.log(
`First: ${first}, City: ${place}`,
);

birth: { place } प्रॉपर्टी person पर मौजूद नहीं है, इसलिए यह त्रुटि फेंकेगा। एक समाधान है नेस्टेड प्रॉपर्टीज़ के लिए डिफ़ॉल्ट मान प्रदान करना।

नेस्टेड प्रॉपर्टीज़ तक पहुँचते समय सावधान रहें—त्रुटियाँ पकड़ना मुश्किल हो सकता है। और त्रुटि संदेश ब्राउज़र और प्लेटफ़ॉर्म के अनुसार बदलते हैं, जिससे डिबग करना थोड़ा कठिन हो जाता है।

आधुनिक Chrome में: TypeError: Cannot read properties of undefined (reading 'place')

Node में भी यह TypeError है क्योंकि JavaScript place को undefined से डीस्ट्रक्चर करने की कोशिश करता है, इससे पहले कि place पढ़ा जाए।

सटीक शब्दावली ब्राउज़र और रनटाइम के अनुसार बदलती है।

अब कुछ डिफ़ॉल्ट्स के साथ, यह क्या करेगा?

'use strict';
const person = {
name: { first: 'Dan' },
address: { city: 'Denver' },
};
const {
name: { first = 'Unknown' },
birth: { place = 'Unknown' },
} = person;
console.log(
`Hi ${first} from ${place}`,
);

birth प्रॉपर्टी person पर मौजूद नहीं है, इसलिए पूरी ऑब्जेक्ट को डिफ़ॉल्ट चाहिए, सिर्फ नेस्टेड प्रॉपर्टी को नहीं। मूल रूप से यहाँ = {} डिफ़ॉल्ट गायब है।

जैसा लिखा है, इसका मतलब है “यदि person.birth undefined है, तो place Unknown होगा”। लेकिन person.birth undefined है, इसलिए यह undefined को डीस्ट्रक्चर करने की कोशिश कर रहा है, जिससे त्रुटि आती है।

In modern Chrome: `TypeError: Cannot read properties of undefined (reading 'place')`
In Node, this is also a `TypeError` because JavaScript tries to destructure `place` from `undefined`.
Exact wording varies between browsers and runtimes.

यह क्या करेगा?

const person = {
name: { first: 'Dan' },
address: { city: 'Denver' },
};
const {
name: { first = 'Unknown' },
birth: { place = 'Unknown' } = {},
} = person;
console.log(
`Hi ${first} from ${place}`,
);

birth प्रॉपर्टी person में मौजूद नहीं है, इसलिए यह खाली ऑब्जेक्ट = {} पर फॉल्ट करता है। इससे डिफ़ॉल्ट मान उपयोग में आता है।

अब फ़ंक्शन पैरामीटर के रूप में, यह क्या करेगा?

'use strict';
function displayUser({
name = "Unknown",
age = -1,
} = { place: "Unknown" }) {
console.log(`Hi ${name} from ${place}`);
}
displayUser({ name: "Dan" });

यह फ़ंक्शन name और age प्रॉपर्टीज़ को निकालता है, आवश्यक होने पर डिफ़ॉल्ट्स का उपयोग करता है। इस मामले में, डिफ़ॉल्ट ऑब्जेक्ट पर place कुंजी सिर्फ शोर है, यह displayUser() के अंदर उपयोग नहीं होती।

स्ट्रिक्ट मोड इसको नहीं बदलता: अनडिक्लेयर्ड place बाइंडिंग को पढ़ने से ReferenceError फेंकता है।

undefined मानों को कैसे संभाला जाता है?

'use strict';
function displayPlace({
name = "N/A",
place = "N/A",
age = -1,
} = { place: "Unknown" }) {
console.log(`${place}`);
}
displayPlace({ name: "Dan" });
displayPlace({ name: "Dan", place: undefined });
displayPlace({ name: "Dan", place: "Joburg" });

displayPlace फ़ंक्शन केवल तब ही डिफ़ॉल्ट ऑब्जेक्ट का उपयोग करेगा जब कोई ऑब्जेक्ट पास नहीं किया गया हो। इसलिए { place: "Unknown" } डिफ़ॉल्ट प्राप्त करने का एक ही तरीका है जब आप शून्य आर्ग्यूमेंट्स के साथ displayPlace() कॉल करते हैं।

यहाँ एक और उल्लेखनीय व्यवहार यह है कि place के लिए undefined पास करने पर डिफ़ॉल्ट मान इस्तेमाल होगा, जो JSON.stringify के व्यवहार जैसा है (undefined को अनदेखा करता है, null को पहचानता है)।

इसका परिणाम है:

displayPlace() // Unknown
displayPlace({ name: "Dan" }) // N/A
displayPlace({ name: "Dan", place: undefined }) // N/A

पिछले वाले जैसा… null को कैसे संभालते हैं?_

function displayPlace({
name = "N/A",
place = "N/A",
age = -1,
} = { place: "Unknown" }) {
console.log(`${place}`);
}
displayPlace({ name: "Dan", place: null });
displayPlace({ name: "Dan", place: undefined });

इस केस में, पहली कॉल में place प्रॉपर्टी null पर सेट होती है, और दूसरी में undefinedplace के लिए डिफ़ॉल्ट मान केवल तब उपयोग होता है जब पूरा ऑब्जेक्ट गायब या undefined हो। null मान 그대로 null रहेगा।

अब टाइपस्क्रिप्ट में… यह क्या करेगा?

'use strict';
function displayPlace(
{
name = 'N/A',
place = 'N/A',
}: {
name: string;
place: string;
age: number;
},
) {
console.log(`${place}`);
}
displayPlace({ name: 'Dan', place: null });

टाइपस्क्रिप्ट एक त्रुटि रिपोर्ट करता है क्योंकि place को string के रूप में टाइप किया गया है, लेकिन कॉल null पास करता है। कॉल आवश्यक age प्रॉपर्टी को भी छोड़ देता है।

यदि आप टाइप त्रुटियों को अनदेखा करते हैं, तो कोड चलाने पर कंसोल में null प्रिंट होगा।

चलो कुछ रीनेमिंग/असाइनमेंट आज़माते हैं…

'use strict';
function displayPlace({
name = 'N/A',
place: location = 'N/A',
}: {
name: string;
place: string;
age?: number;
}) {
console.log(`${location}`);
}
displayPlace({ name: 'Dan', place: 'Denver' });

यह कंसोल में Denver प्रिंट करेगा। फ़ंक्शन सिग्नेचर में place प्रॉपर्टी को location में रीनेम किया गया है। यह एक सामान्य पैटर्न है (डिस्ट्रक्चरिंग के दौरान प्रॉपर्टी का नाम बदलना) जब आप थर्ड‑पार्टी डेटा स्ट्रक्चर को अनुकूलित कर रहे हों।

टाइप एरर को खोजें:

function greet({
name: {first = "N/A", last = "N/A"},
birth: {place = "N/A"} = {},
age = -1,
}: {
name: {first?: string, last?: string};
birth: {place?: string};
age: number;
}) {
console.log(`Hi ${first} ${last} from ${place}`);
}
greet({ name: {first: 'Dan'} });

त्रुटि greet फ़ंक्शन सिग्नेचर में है। पास किए गए ऑब्जेक्ट में age और birth प्रॉपर्टी गायब हैं, इसलिए उन्हें टाइप डिफ़िनिशन में वैकल्पिक होना चाहिए।

हालांकि birth प्रॉपर्टी डिफॉल्ट वैल्यू के साथ डीस्ट्रक्चर की गई है, टाइप डिफ़िनिशन इसे मौजूद होने की आवश्यकता रखता है। TypeScript में प्रॉपर्टी को वैकल्पिक बनाने के लिए आपको ? ऑपरेटर का उपयोग करना चाहिए।

ध्यान दें कि birth?: { place?: string } वही नहीं है जो birth: { place?: string } | undefined

अब असाइनमेंट के साथ (ध्यान दें f, l और p वेरिएबल्स)

'use strict';
function greet(
{
name: {first: f = "N/A", last: l = "N/A"},
birth: {place: p = "N/A"} = {},
age = -1,
}: {
name: {first?: string, last?: string};
birth?: {place?: string};
age?: number;
}
) {
console.log(`Hi ${f} ${l} from ${place}`);
// What will 👆 do?
}
greet({
name: {first: 'Dan', last: 'Levy'},
birth: {place: 'Cape Town'},
});

एक और त्रुटि! आप अनुमान लगाना शुरू कर रहे हैं, है ना?!

डीस्ट्रक्चरिंग की कई परतों को पढ़ना कठिन है, जिसमें डिफॉल्ट, असाइनमेंट और टाइप्स शामिल हैं!

जैसे ही place को p वेरिएबल को पुनः असाइन किया जाता है, वह console.log स्टेटमेंट के स्कोप में अब परिभाषित नहीं रहता।

console.log(`Hi ${f} ${l} from ${place}`); // ❌
// to:
console.log(`Hi ${f} ${l} from ${p}`); // ✅