(a==1 && a==2 && a==3) true? JavaScript का जादू

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

परिचय: वह सवाल जिसने Stack Overflow को हिला दिया

\n\n

एक स्थिति की कल्पना करें: आप एक इंटरव्यू में हैं, और इंटरव्यूअर मुस्कुराते हुए पूछता है: "क्या a == 1 && a == 2 && a == 3 कभी true हो सकता है?"। पहली प्रतिक्रिया होती है — "बिल्कुल नहीं! एक वेरिएबल एक साथ तीन अलग-अलग संख्याओं के बराबर नहीं हो सकता।"

\n\n

लेकिन, अगर आप JavaScript को थोड़ा गहराई से जानते हैं, तो आप जानते हैं: इस भाषा में सबसे अनपेक्षित चीजें भी संभव हैं। इस सवाल ने Stack Overflow पर हज़ारों व्यूज़ पाए और टाइप कोअर्शन, गेटर्स और ऑब्जेक्ट रैपर्स की समझ जांचने के लिए यह एक क्लासिक बन गया है।

\n\n

इस लेख में, हम न सिर्फ यह साबित करेंगे कि यह संभव है, बल्कि (a==1 && a==2 && a==3) को true करने के 5 अलग-अलग तरीके भी समझाएंगे। आप जानेंगे कि नॉन-स्ट्रिक्ट कम्पेरिजन (==) कैसे काम करता है, यह स्ट्रिक्ट (===) से कैसे अलग है, और आप इसका उपयोग कैसे कर सकते हैं।

\n\n

यह लेख शुरुआती लोगों के लिए भी उपयोगी है जो JavaScript को गहराई से समझना चाहते हैं, और अनुभवी डेवलपर्स के लिए भी जो इंटरव्यू की तैयारी कर रहे हैं। चलिए शुरू करते हैं!

\n\n

तरीका नंबर 1: valueOf का जादू (सबसे लोकप्रिय)

\n\n

सबसे सुंदर और सबसे अधिक उद्धृत तरीका है — कस्टम ऑब्जेक्ट का उपयोग करना जिसमें valueOf मेथड को ओवरराइड किया गया हो। JavaScript में, जब आप किसी ऑब्जेक्ट की तुलना किसी प्रिमिटिव से == के माध्यम से करते हैं, तो इंजन ऑटोमैटिकली ऑब्जेक्ट को प्रिमिटिव में बदलने के लिए valueOf() (या toString()) को कॉल करता है।

\n\n

हम एक काउंटर ऑब्जेक्ट बनाएंगे, जो हर बार valueOf कॉल होने पर अपनी वैल्यू को 1 से बढ़ा देगा।

\n\n
const a = {\n  value: 1,\n  valueOf() {\n    return this.value++;\n  }\n};\n\nconsole.log(a == 1 && a == 2 && a == 3); // true
\n\n

यह कैसे काम करता है:

\n
    \n
  • पहली तुलना a == 1 में valueOf() कॉल होता है, यह 1 लौटाता है, और value बढ़कर 2 हो जाता है।
  • \n
  • दूसरी तुलना a == 2 में फिर से valueOf() कॉल होता है, यह 2 लौटाता है, value 3 हो जाता है।
  • \n
  • तीसरी तुलना a == 3 सफलतापूर्वक चेन पूरी करती है।
  • \n
\n\n

यह टाइप कोअर्शन (फोर्स्ड टाइप कन्वर्जन) का एक आदर्श उदाहरण है। यही तंत्र JavaScript को एक साथ लचीली और खतरनाक भाषा बनाता है।

\n\n

तरीका नंबर 2: toString — valueOf का जुड़वां

\n\n

अगर आप valueOf के बजाय toString को ओवरराइड करते हैं, तो परिणाम वही होगा। JavaScript नॉन-स्ट्रिक्ट कम्पेरिजन में ऑब्जेक्ट को बदलने के लिए इन दोनों में से किसी भी मेथड का उपयोग कर सकता है।

\n\n
const a = {\n  value: 1,\n  toString() {\n    return this.value++;\n  }\n};\n\nconsole.log(a == 1 && a == 2 && a == 3); // true
\n\n

अंतर सूक्ष्म है: संख्यात्मक तुलनाओं के लिए valueOf को प्राथमिकता दी जाती है, और स्ट्रिंग तुलनाओं के लिए toString को। लेकिन हमारे मामले में, दोनों ही पूरी तरह से काम करते हैं।

\n\n

तरीका नंबर 3: ग्लोबल स्कोप में गेटर्स

\n\n

बहुत से लोगों को पता भी नहीं है कि ग्लोबल वेरिएबल JavaScript में वास्तव में ग्लोबल ऑब्जेक्ट (window ब्राउज़र में, global Node.js में) के प्रॉपर्टी होते हैं। और प्रॉपर्टी को गेटर्स (getter) के माध्यम से डिफाइन किया जा सकता है।

\n\n

हम ग्लोबल ऑब्जेक्ट पर ही वेरिएबल a के लिए एक गेटर डिफाइन कर सकते हैं:

\n\n
let value = 1;\nObject.defineProperty(window, 'a', {\n  get() {\n    return value++;\n  }\n});\n\nconsole.log(a == 1 && a == 2 && a == 3); // true
\n\n

यह तरीका विशेष रूप से दिलचस्प है क्योंकि a एक सामान्य वेरिएबल की तरह व्यवहार करता है, जबकि वास्तव में यह एक गेटर वाली प्रॉपर्टी है। हर बार जब आप a को एक्सेस करते हैं, गेटर एक नई वैल्यू लौटाता है।

ब्लॉग

पुस्तक अनुशंसाएँ