String बनाम string: आपके कोड का मूक प्रदर्शन हत्यारा
\n\nक्या आपने कभी सोचा है कि एक जगह TypeScript String पर आपत्ति क्यों करता है, और दूसरी जगह string पर? या हो सकता है, आपने अनुभवी डेवलपर्स को new String("hello") देखकर नाक-भौं सिकोड़ते देखा हो? यह प्रश्न Stack Overflow पर एक वास्तविक हिट है, जिसने हजारों बार देखा गया है। और यह बिना कारण नहीं है। String और string के बीच का अंतर भाषा की कोई सनक नहीं है, बल्कि एक मौलिक अंतर है जो आपके कोड के प्रदर्शन, सुरक्षा और पठनीयता को प्रभावित करता है।
इस लेख में, हम केवल एक शुष्क परिभाषा नहीं देंगे। हम यह समझेंगे कि इनमें से प्रत्येक प्रकार के पीछे क्या है, वे रनटाइम में कैसे व्यवहार करते हैं, और क्यों सही चुनाव आपके एप्लिकेशन को दसियों प्रतिशत तक तेज कर सकता है। तैयार हो जाइए, यह दिलचस्प होने वाला है!
\n\nआदिम बनाम ऑब्जेक्ट: मूलभूत बातें
\n\nअंतर को समझने के लिए, हमें यह याद रखना होगा कि JavaScript (और इसलिए TypeScript) डेटा के साथ कैसे काम करता है। भाषा में दो प्रकार के मान होते हैं:
\n\n- \n
- आदिम (primitives):
string,number,boolean,null,undefined,symbol,bigint। ये अपरिवर्तनीय होते हैं और मान द्वारा संग्रहीत किए जाते हैं। \n - ऑब्जेक्ट (objects):
Object,Array,Function, औरString(बड़े अक्षर के साथ),Number,Boolean। ये परिवर्तनीय होते हैं और संदर्भ द्वारा संग्रहीत किए जाते हैं। \n
जब आप let name: string = "Alice" लिखते हैं, तो आप एक आदिम बना रहे हैं। जब आप let name: String = new String("Alice") लिखते हैं, तो आप एक ऑब्जेक्ट-रैपर बना रहे हैं। और यहीं से सबसे दिलचस्प शुरुआत होती है।
प्रकार string (छोटे अक्षर के साथ)
\nयह आदिम प्रकार है। इसका उपयोग 99.9% मामलों में किया जाता है। यह हल्का, तेज़ और पूर्वानुमानित है। दो आदिमों की तुलना मान द्वारा होती है:
\n\nlet a: string = "hello";\nlet b: string = "hello";\nconsole.log(a === b); // true\n\nTypeScript इसी का उपयोग करने की अनुशंसा करता है। स्ट्रिंग वेरिएबल्स, फ़ंक्शन पैरामीटर और रिटर्न वैल्यू घोषित करने के लिए यह वास्तविक मानक है।
\n\nप्रकार String (बड़े अक्षर के साथ)
\nयह ऑब्जेक्ट प्रकार है, एक कंस्ट्रक्टर-रैपर। यह JavaScript के समय से स्ट्रिंग विधियों के साथ काम करने के लिए मौजूद है। हालांकि, इसका सीधा उपयोग एक एंटी-पैटर्न है, जब तक कि आपके पास कोई बहुत विशिष्ट कार्य न हो। दो String ऑब्जेक्ट्स की तुलना संदर्भ द्वारा होती है:
let a: String = new String("hello");\nlet b: String = new String("hello");\nconsole.log(a === b); // false! ये मेमोरी में अलग-अलग ऑब्जेक्ट हैं\n\nइससे मुश्किल से पकड़ में आने वाली बग हो सकती हैं। कल्पना करें कि आप जाँच रहे हैं कि स्ट्रिंग का मान "hello" के बराबर है या नहीं, और आपको false मिलता है, सिर्फ इसलिए कि किसी ने new String() का उपयोग किया।
प्रदर्शन: क्यों string जीतता है?
\n\nअब सबसे दिलचस्प भाग पर आते हैं - संख्याएँ और अनुकूलन। आइए एक सरल प्रदर्शन परीक्षण लिखें (आप इसे अपने वातावरण में चला सकते हैं, जैसे Node.js या ब्राउज़र में)।
\n\n// प्रदर्शन परीक्षण\nconst iterations = 1_000_000;\n\nconsole.time("string (primitive)");\nlet sum = "";\nfor (let i = 0; i < iterations; i++) {\n sum += "a";\n}\nconsole.timeEnd("string (primitive)");\n\nconsole.time("String (object)");\nlet sumObj = new String("");\nfor (let i = 0; i < iterations; i++) {\n sumObj += "a"; // यहाँ ऑटो-बॉक्सिंग और अनबॉक्सिंग होती है\n}\nconsole.timeEnd("String (object)");\n\nएक सामान्य मशीन पर परिणाम नाटकीय रूप से भिन्न होगा (आदिम के पक्ष में 2-5 गुना)। क्यों? क्योंकि:
\n- \n
- आदिम
string— मेमोरी में वर्णों का एक सरल अनुक्रम है। इस पर संचालन इंजन स्तर पर अनुकूलित होते हैं। \n