परिचय: वह सवाल जिसने Stack Overflow को हिला दिया
\n\nएक स्थिति की कल्पना करें: आप एक इंटरव्यू में हैं, और इंटरव्यूअर मुस्कुराते हुए पूछता है: "क्या a == 1 && a == 2 && a == 3 कभी true हो सकता है?"। पहली प्रतिक्रिया होती है — "बिल्कुल नहीं! एक वेरिएबल एक साथ तीन अलग-अलग संख्याओं के बराबर नहीं हो सकता।"
लेकिन, अगर आप JavaScript को थोड़ा गहराई से जानते हैं, तो आप जानते हैं: इस भाषा में सबसे अनपेक्षित चीजें भी संभव हैं। इस सवाल ने Stack Overflow पर हज़ारों व्यूज़ पाए और टाइप कोअर्शन, गेटर्स और ऑब्जेक्ट रैपर्स की समझ जांचने के लिए यह एक क्लासिक बन गया है।
\n\nइस लेख में, हम न सिर्फ यह साबित करेंगे कि यह संभव है, बल्कि (a==1 && a==2 && a==3) को true करने के 5 अलग-अलग तरीके भी समझाएंगे। आप जानेंगे कि नॉन-स्ट्रिक्ट कम्पेरिजन (==) कैसे काम करता है, यह स्ट्रिक्ट (===) से कैसे अलग है, और आप इसका उपयोग कैसे कर सकते हैं।
यह लेख शुरुआती लोगों के लिए भी उपयोगी है जो JavaScript को गहराई से समझना चाहते हैं, और अनुभवी डेवलपर्स के लिए भी जो इंटरव्यू की तैयारी कर रहे हैं। चलिए शुरू करते हैं!
\n\nतरीका नंबर 1: valueOf का जादू (सबसे लोकप्रिय)
\n\nसबसे सुंदर और सबसे अधिक उद्धृत तरीका है — कस्टम ऑब्जेक्ट का उपयोग करना जिसमें valueOf मेथड को ओवरराइड किया गया हो। JavaScript में, जब आप किसी ऑब्जेक्ट की तुलना किसी प्रिमिटिव से == के माध्यम से करते हैं, तो इंजन ऑटोमैटिकली ऑब्जेक्ट को प्रिमिटिव में बदलने के लिए valueOf() (या toString()) को कॉल करता है।
हम एक काउंटर ऑब्जेक्ट बनाएंगे, जो हर बार valueOf कॉल होने पर अपनी वैल्यू को 1 से बढ़ा देगा।
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 लौटाता है,value3 हो जाता है। \n - तीसरी तुलना
a == 3सफलतापूर्वक चेन पूरी करती है। \n
यह टाइप कोअर्शन (फोर्स्ड टाइप कन्वर्जन) का एक आदर्श उदाहरण है। यही तंत्र JavaScript को एक साथ लचीली और खतरनाक भाषा बनाता है।
\n\nतरीका नंबर 2: toString — valueOf का जुड़वां
\n\nअगर आप valueOf के बजाय toString को ओवरराइड करते हैं, तो परिणाम वही होगा। JavaScript नॉन-स्ट्रिक्ट कम्पेरिजन में ऑब्जेक्ट को बदलने के लिए इन दोनों में से किसी भी मेथड का उपयोग कर सकता है।
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 को। लेकिन हमारे मामले में, दोनों ही पूरी तरह से काम करते हैं।
तरीका नंबर 3: ग्लोबल स्कोप में गेटर्स
\n\nबहुत से लोगों को पता भी नहीं है कि ग्लोबल वेरिएबल JavaScript में वास्तव में ग्लोबल ऑब्जेक्ट (window ब्राउज़र में, global Node.js में) के प्रॉपर्टी होते हैं। और प्रॉपर्टी को गेटर्स (getter) के माध्यम से डिफाइन किया जा सकता है।
हम ग्लोबल ऑब्जेक्ट पर ही वेरिएबल a के लिए एक गेटर डिफाइन कर सकते हैं:
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 को एक्सेस करते हैं, गेटर एक नई वैल्यू लौटाता है।