![](https://habrastorage.org/getpro/habr/post_images/ade/9bb/322/ade9bb322bafb763c7f503a383036a27.jpg)
नए साल की छुट्टियों के बाद, मैंने पहले ही सुझाव दिया था कि समुदाय जावास्क्रिप्ट में पहेली स्थितियों के माध्यम से अपने मन को फैलाएंगे। उस पोस्ट को काफी समय बीत चुका है, कई अन्य छुट्टियां हो गई हैं, इसलिए मैं सुझाव देता हूं कि कार्यों के एक नए हिस्से के बारे में सोचें।
मैं बिगाड़ने के तहत पिछली बार की तरह इस व्यवहार को तार्किक क्यों है, इस स्पष्टीकरण के जवाब और मेरे अपने संस्करण को छिपाऊंगा। तुरंत एक आरक्षण करें कि मैं अपने संस्करणों के अटल सत्य का ढोंग न करूं और मुझे उन पर चर्चा करने में खुशी होगी। ECMAScript 5 विनिर्देशन का एक उत्कृष्ट रूसी अनुवाद आपको इसे हल करने में मदद कर सकता है, जिसके लिए बहुत धन्यवाद iliakan !
1. जीवन का मुख्य मुद्दा, ब्रह्मांड और वह सब
"3" -+-+-+ "1" + "1" / "3" * "6" + "2"
निर्णय
जैसा कि हम पहले से ही पिछले पोस्ट से जानते हैं, + ऑपरेटर या तो स्ट्रिंग्स का संयोजन करता है, या इसके अलावा, या किसी संख्या में कमी करता है। यानी
5 नहीं, जैसा कि आप सोच सकते हैं।
इसके अलावा, आप अपने चिह्न को बदलने और चीजों को और अधिक सुंदर और पठनीय बनाने के लिए एक अभिव्यक्ति पर अनियोजित ऑपरेटर "+" या "-" फेंक सकते हैं।
उपरोक्त सभी को देखते हुए:
अगला, संचालन की प्राथमिकता को याद रखें: / * +
"3" -+-+-+ "1" + "1" / "3" * "6" + "2" == "42"
जैसा कि हम पहले से ही पिछले पोस्ट से जानते हैं, + ऑपरेटर या तो स्ट्रिंग्स का संयोजन करता है, या इसके अलावा, या किसी संख्या में कमी करता है। यानी
“3” + 2 == “32”
5 नहीं, जैसा कि आप सोच सकते हैं।
इसके अलावा, आप अपने चिह्न को बदलने और चीजों को और अधिक सुंदर और पठनीय बनाने के लिए एक अभिव्यक्ति पर अनियोजित ऑपरेटर "+" या "-" फेंक सकते हैं।
उपरोक्त सभी को देखते हुए:
+ “1” === 1 -+ “1” === -1 +-+ “1” === -1 … -+-+-+ === -1 "3" -+-+-+ "1" === 2 //
अगला, संचालन की प्राथमिकता को याद रखें: / * +
“1”/”3” === 0.3333… “1” / ”3” * ”6” === 2 2 + 2 === 4 4 + “2” === “42”
2. अधिकतमवाद
Math.max(3, 0); Math.max(3, {}); Math.max(3, []); Math.max(-1, [1]); Math.max(-1, [1, 4]); Math.max(3, true); Math.max(3, 'foo'); Math.max(-1, null); Math.max(-1, undefined);
निर्णय
यहां सब कुछ सरल है।
{} के लिए toNumber निष्पादित करने का प्रयास करें:
valueOf निष्पादित करें और जांचें कि क्या यह आदिम है - नहीं, तब
निष्पादित करें और आगे बढ़ें, "[ऑब्जेक्ट ऑब्जेक्ट]" ;
परिणामी स्ट्रिंग toNumber के लिए निष्पादित करें और NaN प्राप्त करें;
यदि NaN प्राप्त होता है, तो Math.max () हमेशा NaN लौटाता है।
[] के लिए toNumber निष्पादित करने का प्रयास करें:
valueOf निष्पादित करें और जांचें कि क्या यह आदिम है - नहीं, तब
निष्पादित करें और प्राप्त करें "";
परिणामी स्ट्रिंग toNumber के लिए निष्पादित करें और 0 प्राप्त करें;
३> ०
[1] के लिए toNumber निष्पादित करने का प्रयास करें:
valueOf निष्पादित करें और जांचें कि क्या यह आदिम है - नहीं, तब
निष्पादित करें और आगे बढ़ें "1";
परिणामी स्ट्रिंग toNumber के लिए निष्पादित करें और 1 प्राप्त करें;
-1 <१
[1,4] के लिए toNumber निष्पादित करने का प्रयास करें:
valueOf निष्पादित करें और जांचें कि क्या यह आदिम है - नहीं, तब
निष्पादित करें और आगे बढ़ें "1.4";
परिणामी स्ट्रिंग toNumber के लिए निष्पादित करें और NaN प्राप्त करें;
यदि NaN प्राप्त होता है, तो Math.max () हमेशा NaN लौटाता है।
सत्य के लिए toNumber निष्पादित करने का प्रयास करें:
valueOf निष्पादित करें और जांचें कि क्या यह आदिम है - हां, तब
३> १
'फू' के लिए toNumber रिटर्न NaN ।
यदि NaN प्राप्त होता है, तो Math.max () हमेशा NaN लौटाता है।
यदि NaN प्राप्त होता है, तो Math.max () हमेशा NaN लौटाता है।
Math.max(3, 0); // 3
यहां सब कुछ सरल है।
Math.max(3, {}); // NaN
{} के लिए toNumber निष्पादित करने का प्रयास करें:
valueOf निष्पादित करें और जांचें कि क्या यह आदिम है - नहीं, तब
निष्पादित करें और आगे बढ़ें, "[ऑब्जेक्ट ऑब्जेक्ट]" ;
परिणामी स्ट्रिंग toNumber के लिए निष्पादित करें और NaN प्राप्त करें;
यदि NaN प्राप्त होता है, तो Math.max () हमेशा NaN लौटाता है।
Math.max(3, []); // 3
[] के लिए toNumber निष्पादित करने का प्रयास करें:
valueOf निष्पादित करें और जांचें कि क्या यह आदिम है - नहीं, तब
निष्पादित करें और प्राप्त करें "";
परिणामी स्ट्रिंग toNumber के लिए निष्पादित करें और 0 प्राप्त करें;
३> ०
Math.max(-1, [1]); // 1
[1] के लिए toNumber निष्पादित करने का प्रयास करें:
valueOf निष्पादित करें और जांचें कि क्या यह आदिम है - नहीं, तब
निष्पादित करें और आगे बढ़ें "1";
परिणामी स्ट्रिंग toNumber के लिए निष्पादित करें और 1 प्राप्त करें;
-1 <१
Math.max(-1, [1, 4]); // NaN
[1,4] के लिए toNumber निष्पादित करने का प्रयास करें:
valueOf निष्पादित करें और जांचें कि क्या यह आदिम है - नहीं, तब
निष्पादित करें और आगे बढ़ें "1.4";
परिणामी स्ट्रिंग toNumber के लिए निष्पादित करें और NaN प्राप्त करें;
यदि NaN प्राप्त होता है, तो Math.max () हमेशा NaN लौटाता है।
Math.max(3, true); // 3
सत्य के लिए toNumber निष्पादित करने का प्रयास करें:
valueOf निष्पादित करें और जांचें कि क्या यह आदिम है - हां, तब
toNumber(true) === 1
३> १
Math.max(3, 'foo'); // NaN
'फू' के लिए toNumber रिटर्न NaN ।
यदि NaN प्राप्त होता है, तो Math.max () हमेशा NaN लौटाता है।
Math.max(-1, null); // 0
toNumber(null) === 0 -1 < 0
Math.max(-1, undefined); // NaN
toNumber(undefined) === NaN
यदि NaN प्राप्त होता है, तो Math.max () हमेशा NaN लौटाता है।
3. जीवन अल्पविराम
[,,,].join() [,,,undefined].join()
छिपा हुआ पाठ
यहाँ मैं केवल फलागन का उल्लेख कर सकता हूँ। 7.1:
“यदि एक सरणी शाब्दिक में कई लगातार अल्पविराम होते हैं, जिनके बीच कोई मान नहीं है, तो एक विरल सरणी बनाई जाती है। ऐसे अनुपलब्ध मानों के अनुरूप तत्व ऐरे में अनुपस्थित हैं, लेकिन जब उन्हें एक्सेस किया जाता है, तो अपरिभाषित मान को लौटा दिया जाता है। ”
"सरणी शाब्दिकों का वाक्यविन्यास आपको एक वैकल्पिक अनुगामी अल्पविराम सम्मिलित करने की अनुमति देता है।"
ऐसा क्यों किया गया यह मेरे लिए स्पष्ट नहीं है। अंतिम पोस्ट पर टिप्पणियों में , यह एक विशेषता के रूप में प्रस्तुत किया गया था। मेरी राय में, यह अभी भी कोड में त्रुटियों से एक ब्राउज़र बैसाखी है।
[,,,].join() // ",," [,,,undefined].join() // ",,,"
यहाँ मैं केवल फलागन का उल्लेख कर सकता हूँ। 7.1:
“यदि एक सरणी शाब्दिक में कई लगातार अल्पविराम होते हैं, जिनके बीच कोई मान नहीं है, तो एक विरल सरणी बनाई जाती है। ऐसे अनुपलब्ध मानों के अनुरूप तत्व ऐरे में अनुपस्थित हैं, लेकिन जब उन्हें एक्सेस किया जाता है, तो अपरिभाषित मान को लौटा दिया जाता है। ”
"सरणी शाब्दिकों का वाक्यविन्यास आपको एक वैकल्पिक अनुगामी अल्पविराम सम्मिलित करने की अनुमति देता है।"
ऐसा क्यों किया गया यह मेरे लिए स्पष्ट नहीं है। अंतिम पोस्ट पर टिप्पणियों में , यह एक विशेषता के रूप में प्रस्तुत किया गया था। मेरी राय में, यह अभी भी कोड में त्रुटियों से एक ब्राउज़र बैसाखी है।
4. खजाना नक्शा
Array(20).map(function(elem) { return 'a'; });
छिपा हुआ पाठ
ऐरे कंस्ट्रक्टर को एक तर्क के साथ कॉल करने से 20 तत्वों की एक सरणी नहीं बनती है, लेकिन 20 की लंबाई वाला एक सरणी है। और मानचित्र विधि पहले एक खाली सरणी बनाती है, जिसकी लंबाई स्थानांतरित सरणी की लंबाई के बराबर होती है, और फिर स्थानांतरित सरणी के प्रत्येक तत्व के लिए कॉलबैक कहती है। हमारे मामले में, सरणी में कोई तत्व नहीं है और विधि मूल के समान लंबाई का एक खाली सरणी देता है।
Array(20).map(function(elem) { return 'a'; }); // Array of undefined x 20
ऐरे कंस्ट्रक्टर को एक तर्क के साथ कॉल करने से 20 तत्वों की एक सरणी नहीं बनती है, लेकिन 20 की लंबाई वाला एक सरणी है। और मानचित्र विधि पहले एक खाली सरणी बनाती है, जिसकी लंबाई स्थानांतरित सरणी की लंबाई के बराबर होती है, और फिर स्थानांतरित सरणी के प्रत्येक तत्व के लिए कॉलबैक कहती है। हमारे मामले में, सरणी में कोई तत्व नहीं है और विधि मूल के समान लंबाई का एक खाली सरणी देता है।
5. फिनिटा ला कोमेडिया
isFinite(42); isFinite(1/0); isFinite(0/0); isFinite('42'); isFinite('hi'); isFinite(); isFinite(undefined); isFinite(null);
छिपा हुआ पाठ
isFinite तर्क को एक संख्या में परिवर्तित करता है , और यदि यह NaN, + Infinity या -Infinity को बदल देता है, तो वह गलत हो जाता है । अन्य सभी मामलों में, सच है ।
'हाय' से ToNumber NaN लौटाएगा, अपरिभाषित NaN लौटेगा, और नल 0 पर लौटेगा।
isFinite(42); // true isFinite(1/0); // false isFinite(0/0); // NaN is not finite -> false isFinite('42'); // true isFinite('hi'); // false isFinite(); // false isFinite(undefined); // false isFinite(null); // true
isFinite तर्क को एक संख्या में परिवर्तित करता है , और यदि यह NaN, + Infinity या -Infinity को बदल देता है, तो वह गलत हो जाता है । अन्य सभी मामलों में, सच है ।
'हाय' से ToNumber NaN लौटाएगा, अपरिभाषित NaN लौटेगा, और नल 0 पर लौटेगा।
6. सच्ची कहानी भाई
'true' == true
छिपा हुआ पाठ
समानता ऑपरेटर क्रमिक रूप से संख्याओं को सत्य बनाता है, फिर 'सत्य'। यह NaN == 1 निकला, जो स्पष्ट रूप से गलत है।
'true' == true //false
समानता ऑपरेटर क्रमिक रूप से संख्याओं को सत्य बनाता है, फिर 'सत्य'। यह NaN == 1 निकला, जो स्पष्ट रूप से गलत है।
7. कुछ नहीं
null == false !null
छिपा हुआ पाठ
शून्य से बूल तक कास्टिंग के साथ , सब कुछ स्पष्ट है। तुलना के साथ सौदा करते हैं। नल और बूल का संयोजन विनिर्देश के खंड 11.9.3 में किसी भी तुलना \ डाली विकल्प के तहत नहीं आता है और इसलिए तुलना झूठी होती है ।
null == false // false !null // true
शून्य से बूल तक कास्टिंग के साथ , सब कुछ स्पष्ट है। तुलना के साथ सौदा करते हैं। नल और बूल का संयोजन विनिर्देश के खंड 11.9.3 में किसी भी तुलना \ डाली विकल्प के तहत नहीं आता है और इसलिए तुलना झूठी होती है ।
8. अनिश्चितता परीक्षण
/^[az]{1,10}$/.test(null); /^[az]{1,10}$/.test(undefined);
छिपा हुआ पाठ
अशक्त और अपरिभाषित स्ट्रिंग के लिए डाले गए हैं: "अशक्त" और "अपरिभाषित" - और इस तरह के तार नियमित अभिव्यक्ति को संतुष्ट करते हैं। और NaN , वैसे, "NaN" भी बन जाएगा।
/^[az]{1,10}$/.test(null); //true /^[az]{1,10}$/.test(undefined); //true
अशक्त और अपरिभाषित स्ट्रिंग के लिए डाले गए हैं: "अशक्त" और "अपरिभाषित" - और इस तरह के तार नियमित अभिव्यक्ति को संतुष्ट करते हैं। और NaN , वैसे, "NaN" भी बन जाएगा।
9. शून्य की उपेक्षा
0 === -0 1/0 === 1/-0
छिपा हुआ पाठ
शून्य नकारात्मक शून्य है, लेकिन जब एक संकेत के साथ विभाजित होता है, तो संकेत को ध्यान में रखा जाता है और यह निकलता है
0 === -0 //true 1/0 === 1/-0 //false
शून्य नकारात्मक शून्य है, लेकिन जब एक संकेत के साथ विभाजित होता है, तो संकेत को ध्यान में रखा जाता है और यह निकलता है
Infinity === -Infinity
उन नायकों के लिए जिन्होंने अंत तक पढ़ा है, शायद सबसे दिलचस्प पहेली। मैं एक और स्पॉइलर के तहत स्पष्टीकरण को छिपाना नहीं चाहता, इसलिए मैं आपको सलाह देता हूं कि आप जवाब देने के बाद देवटूल और वहां जांच करें। यह संभावना है कि परिणाम आपको आश्चर्यचकित करेगा और आप फिर से सोचना चाहेंगे।
10. स्लेश
n = 1 /1*"\/\//.test(n + '"//') n = 1; /1*"\/\//.test(n + '"//');
छिपा हुआ पाठ
एक स्लैश का उपयोग तीन मामलों में किया जा सकता है: नियमित अभिव्यक्ति, विभाजन और टिप्पणी। यहां, पहली नज़र में, हम केवल एक नियमित अभिव्यक्ति देखते हैं। लेकिन, वास्तव में, अर्धविराम के बिना, पहला स्लैश विभाजन करता है। इस प्रकार, विभाजन पहले किया जाता है, और फिर परिणाम को एक स्ट्रिंग से गुणा किया जाता है। शेष पूंछ केवल एक टिप्पणी है। जिस लाइन से हम गुणा करते हैं वह संख्या कम नहीं होती है और NaN प्राप्त होती है।
n = 1 /1*"\/\//.test(n + '"//') //NaN n = 1; /1*"\/\//.test(n + '"//'); //true
एक स्लैश का उपयोग तीन मामलों में किया जा सकता है: नियमित अभिव्यक्ति, विभाजन और टिप्पणी। यहां, पहली नज़र में, हम केवल एक नियमित अभिव्यक्ति देखते हैं। लेकिन, वास्तव में, अर्धविराम के बिना, पहला स्लैश विभाजन करता है। इस प्रकार, विभाजन पहले किया जाता है, और फिर परिणाम को एक स्ट्रिंग से गुणा किया जाता है। शेष पूंछ केवल एक टिप्पणी है। जिस लाइन से हम गुणा करते हैं वह संख्या कम नहीं होती है और NaN प्राप्त होती है।