7

मैंने देखा कि जेएसलिंट के नए संस्करण को लूप के कुछ रूप पसंद नहीं हैं। मैंने पाया कि अजीब होना, और कुछ स्पष्टीकरण के लिए खोदना शुरू कर दिया। जेएसलिंट के help page के तहत, आप यह पा सकते हैं:जेएसलिंट के बारे में, लूप के लिए इसका नापसंद, और पूंछ कॉल अनुकूलन

ईएस 6 की सबसे महत्वपूर्ण नई सुविधा उचित पूंछ कॉल है। इसमें कोई नया वाक्यविन्यास नहीं है, इसलिए जेएसलिंट इसे नहीं देखता है। लेकिन यह रिकर्सन को और अधिक आकर्षक बनाता है, जो लूप बनाता है, खासकर लूप के लिए, बहुत कम आकर्षक।

और यह:

jsLint बयान के लिए के उपयोग की सलाह नहीं है। इसके बजाय प्रत्येक के लिए सरणी विधियों का उपयोग करें। विकल्प के लिए कुछ चेतावनियों को दबाएगा। नए जेएस 6 फॉर्म को छोड़कर, जेएसलिंट स्वीकार करने के लिए फॉर्म प्रतिबंधित हैं।

इन दोनों बयानों ने मुझे एक बाइट उलझन में छोड़ दिया। मैं हमेशा यह धारणा थी छोरों के लिए पाशन का सबसे अच्छा तरीका थे, जिसका मुख्य कारण:

  1. कुछ यात्रा तरीकों बहुत अच्छी तरह से अभी तक समर्थित नहीं हैं
  2. छोरों के लिए कम है अन्य यात्रा तरीकों
  3. से 'सुन'

मैंने कहीं भी पढ़ा है कि forEach जैसे विधियों को अनुकूलित और साथ ही लूप के लिए अनुकूलित नहीं किया जा सकता है, हालांकि मुझे यकीन नहीं है कि मुझे विश्वास करना चाहिए या नहीं। (ECMAScript 5 में शायद सच?)

तो, अन्य यात्रा तरीकों के पक्ष में एक तर्क है कि वे अधिक पठनीय हैं, लेकिन, पूंछ कॉल अनुकूलन खेलने में आने के साथ, वे के रूप में तेजी से या शायद तेजी से एक से के लिए किया जा सकता है पाश?

मैं यहां मान रहा हूं कि, उदाहरण के लिए, प्रत्येक के लिए पूंछ-कॉल अनुकूलित किया जा सकता है, क्या यह सही है?

तो, मुख्य प्रश्न यह है: ईसीएमएस्क्रिप्ट 6 में लूप के अलावा पुनरावृत्ति विधियों के पक्ष में निर्णय लेने पर पूंछ कॉल अनुकूलन वास्तव में कैसे खेलता है?

और शायद यह भी इस: यह सही माना कि JSLInt अन्य यात्रा तरीकों बेहतर पसंद करती है क्योंकि वे अधिक पठनीय हैं, और क्योंकि, ECMAScript 6 में अनुकूलन के साथ, वे बस के रूप में तेजी से छोरों के लिए के रूप में किया जा सकता है ? क्या मैंने JSLint सहायता पृष्ठ पर कथन के ओवर की सही व्याख्या की है?

मुझे पता है कि प्रश्नों में केवल एक मुख्य प्रश्न होना चाहिए, और मेरे पास बहुत से लोग हैं; लेकिन, मैं उन्हें एक-दूसरे से बहुत संबंधित मानता हूं, और इसलिए मुझे लगता है कि उनमें से एक का जवाब शायद उन सभी का जवाब देता है।

धन्यवाद, और लंबी पोस्ट के लिए खेद है!

+8

जेएसलिंट 'लूप्स' से बेहतर रिकर्सन पसंद करता है क्योंकि डगलस क्रॉकफोर्ड 'लूप्स' से बेहतर रिकर्सन पसंद करता है। तो इतना ही है। वह वास्तव में कार्यात्मक शैली में है। जो ठीक होगा अगर वह लगातार इस सामान को अन्य लोगों पर फेंक नहीं रहा था, हालांकि यह सिर्फ राय के बजाय तथ्य था। –

+0

और क्या कोई विशेष कारण है कि उसे रिकर्सन बेहतर क्यों पसंद है? आह, आपके द्वारा अभी तक आपकी टिप्पणी में किए गए संपादन के आधार पर, हाहा नहीं है। –

+2

वह कार्यात्मक प्रोग्रामिंग में है, जो लूप के लिए रिकर्सन का उपयोग करता है। वह जावास्क्रिप्ट का उपयोग नहीं करता है जैसे अधिकांश लोग जावास्क्रिप्ट का उपयोग करते हैं। (वह वास्तव में, वास्तव में अपनी खुद की भाषा लिखना चाहिए और इसे पारदर्शी बनाना चाहिए।) –

उत्तर

1

मैंने कहीं भी पढ़ा है कि प्रत्येक के लिए तरीकों को अनुकूलित करने के साथ-साथ लूप के लिए अनुकूलित नहीं किया जा सकता है, हालांकि मुझे यकीन नहीं है कि मुझे विश्वास करना चाहिए या नहीं। (शायद ईसीएमएस्क्रिप्ट 5 में सच है?)

forEach, क्योंकि आप दो समारोह कॉल की भूमि के ऊपर मिल गया है अनुकूलन करने के लिए कठिन है कॉलबैक तीन तर्कों पारित हो जाता है (या नहीं, आप उन्हें प्रयोग) और इसके अलावा अगर आप map या filter (लेकिन forEach का उपयोग) आपको चीजों को करने के बजाय, एक नया ऐरे बनाने का ओवरहेड भी मिला है।

तो, अन्य पुनरावृत्ति विधियों के पक्ष में एक तर्क यह है कि वे अधिक पठनीय हैं, लेकिन पूंछ कॉल अनुकूलन के साथ खेलने के साथ, क्या वे लूप के लिए तेज़ या संभवतः तेज हो सकते हैं?

filter और map और तरह के लिए मुख्य तर्क है कि वे नई सरणी बना सकते हैं और इस प्रकार अचल स्थिति के लिए प्रोत्साहित करते है। इसके अलावा, उन्हें जंजीर बनाया जा सकता है और यह अच्छा और पठनीय दिखता है। यदि प्रदर्शन वास्तव में एक मुद्दा बन जाता है तो आप while लूप या for लूप का उपयोग कर सकते हैं, लेकिन समय-समय पर अनुकूलित न करें।

जैसा कि मैं नीचे समझाऊंगा, पूंछ कॉल अनुकूलन पुनरावृत्ति विधियों (forEach, map इत्यादि) के साथ खेल में नहीं आता है।

मैं यहां मान रहा हूं कि, उदाहरण के लिए, प्रत्येक के लिए पूंछ-कॉल अनुकूलित किया जा सकता है, क्या यह सही है?

forEach पूंछ कॉल अनुकूलित नहीं है (जहां तक ​​मुझे पता है, ब्राउजर इसे कैसे लागू करता है इस पर निर्भर करता है)। पूंछ कॉल अनुकूलन केवल में किक एक समारोह एक और समारोह (है कि एक पूंछ कॉल है) को कॉल करने के परिणाम देता है, उदाहरण के लिए, यदि:

function factorial(n){ 
    if(n < 2){ 
    return 1; 
    } else { 
    return n * factorial(n - 1); 
    } 
} 

यदि आप एक ब्राउज़र है कि पूंछ कॉल का समर्थन नहीं किया था में उपरोक्त कोड भाग गया , आपको क्रोम में मेरे लिए एक त्रुटि (RangeError: Maximum call stack size exceeded) मिल जाएगी) यदि आप इसे एक बड़ी संख्या देते हैं (उदाहरण के लिए 10000), क्योंकि बहुत से फ़ंक्शन एक बार में कॉल किए जाएंगे। टेल कॉल रिकर्सन का अर्थ है कि जावास्क्रिप्ट इंजन देखता है कि आप एक ही फ़ंक्शन को दोबारा कॉल कर रहे हैं, और तदनुसार अनुकूलित करेंगे और अधिकतम कॉल स्टैक आकार से अधिक होने से रोकेंगे।

जब तक forEach के भीतर आपकी कॉलबैक रिकर्सन का उपयोग नहीं कर रही है, तो पूंछ कॉल अनुकूलन forEach की सहायता नहीं करेगा। चूंकि जावास्क्रिप्ट में पहले पूंछ कॉल अनुकूलन की कमी थी, इसलिए पिछले factorial फ़ंक्शन को थोड़ी देर के लूप के साथ लिखा गया होगा। लूप कॉल के बजाय इन रिकर्सिव फ़ंक्शंस के लिए अब टेल कॉल को प्राथमिकता दी जाती है।

तो, मुख्य प्रश्न यह है कि: ईसीएमएस्क्रिप्ट 6 में लूप के अलावा पुनरावृत्ति विधियों के पक्ष में निर्णय लेने पर पूंछ कॉल अनुकूलन वास्तव में कैसे खेलता है?

जैसा कि मैंने ऊपर कहा है, बहुत से लोग रिकर्सिव फ़ंक्शंस के बजाए लूप का उपयोग कर रहे हैं ताकि वे कॉल स्टैक आकार त्रुटियों में भाग न सकें। अब, ईएस 6 में पूंछ कॉल अनुकूलन के साथ, इन पुनरावर्ती कार्यों का उपयोग करने के लिए अधिक सुरक्षित हो जाता है और कॉल स्टैक आकार त्रुटियों को फेंकना नहीं चाहिए। इन मामलों में, अब इसे लूप के बजाय रिकर्सन का उपयोग करने के लिए पसंद किया गया है।

और शायद यह भी इस: यह सही माना कि JSLInt अन्य यात्रा तरीकों बेहतर पसंद करती है क्योंकि वे अधिक पठनीय हो है, और क्योंकि, ECMAScript 6 में अनुकूलन के साथ, वे बस के रूप में तेजी से छोरों के लिए के रूप में हो सकता है?क्या मैंने JSLint सहायता पृष्ठ पर कथन के ओवर की सही व्याख्या की है?

पठनीयता छोरों (उन्हें आसानी से पालन करने के लिए बनाता है) के बजाय प्रत्यावर्तन का उपयोग कर कार्यों के लिए और यात्रा तरीकों जहां संभव हो (map बल्कि एक for पाश से दर-मूल्य मान-एक सरणी को बदलने के लिए, का उपयोग कर के लिए एक बड़ा कारण है)।

यदि प्रदर्शन एक मुद्दा बन जाता है, तो आप शायद for लूप या while लूप का उपयोग करना चाहते हैं, लेकिन ऐसी कई चीजें हैं जिन पर जेएसलिंट पसंद नहीं करता है।

+1

ध्यान दें कि 'के लिए' नया सरणी नहीं बनाता है, और यह श्रृंखला योग्य नहीं है - इसका एकमात्र उद्देश्य एक श्रृंखला के अंत में दुष्प्रभाव कर रहा है। इमो ने इसके उपयोग के मामलों को 'के लिए 'खो दिया है। – Bergi

+0

@ बर्गि हाँ मैं अपने उत्तर को यह स्पष्ट करने के लिए संपादित करूंगा कि 'प्रत्येक के लिए कोई नई सरणी नहीं है - लेकिन' मानचित्र 'और' फ़िल्टर' करें। और मैं पूरी तरह से सहमत हूं - जब तक आपको 'मानचित्र' और 'फ़िल्टर' की श्रृंखला नहीं मिलती,' 'के लिए '' के लिए' से अधिक पढ़ने योग्य है। –

संबंधित मुद्दे