2016-04-26 18 views
14

मूल रूप से कॉल स्टैकपॉप के लिए बाहर समारोह एक के बाद एक कॉल शुरू कर देंगे परीक्षण पॉप करने में विफल रहता है जब आखिरी में समारोह कॉल रिटर्न । लेकिन जब भी मैं अपने अधिकतम आकार के करीब एक कॉल स्टैक बनाने की कोशिश करता हूं, तो uncaught expression उठाया जा रहा है।Recursion - कॉल स्टैक जब अधिकतम ढेर आकार

//Code for testing the stack size 
var cnt = 0; 

function test(){ 
//Max stack size is nearer to ~41800 
if(cnt++ == 41763){ 
    console.log('finished'); 
    return true; 
} 
return test(); 
} 

test(); 

तो उपरोक्त कोड 49.0.2623.112 मीटर नीचे की तरह,

Uncaught exception

< true

क्रोमियम संस्करण में मेरे लिए एक अपवाद फेंक है कृपया नहीं उपरोक्त त्रुटि इसमें कोई संदेश नहीं है। मेरा सवाल यहां है,

स्टैक में अंतिम फ़ंक्शन कॉल true लौटा दी गई है जिसका अर्थ है कि स्टैक आकार पार नहीं हुआ था। उस स्टैक में अन्य फ़ंक्शन कॉल क्यों नहीं लौटाया गया था? और इस खाली अपवाद संदेश का कारण क्या है?

+1

यह उत्सुक है कि यदि मैं इस कोड को कम पुनरावृत्तियों के साथ चलाता हूं (यानी 40763) त्रुटि तब तक चली जाती है जब तक कोई पृष्ठ रीफ्रेश नहीं होता है। –

+0

विंडोज़ v49.0.2623.87 मीटर पर क्रोम में मुझे * रेंज एरर मिल रहा है: अधिकतम कॉल स्टैक आकार पार हो गया है * जब यह पार हो गया है।और सच हो - अगर यह नहीं है। –

+0

शायद [यह] (https://www.safaribooksonline.com/library/view/high-performance-javascript/9781449382308/ch04s03.html) और [यह] (http://www.2ality.com/2014/04 /call-stack-size.html) मदद करता है? –

उत्तर

8

समस्या यहाँ

console.log('finished'); 

है इस कॉल स्टैक सीमा से अधिक पहुँच जाएँगे जो कुछ अतिरिक्त फ़ंक्शन लेता है, लेकिन अपवाद के माध्यम से अपने कोड से निपटने के लिए वैसे भी मार डाला जाता है।

कंसोल.लॉग के बिना इसे चलाने का प्रयास करें और आप देखते हैं कि आप सीमा तक पहुंचते हैं और या तो एक सत्य या अपवाद देखते हैं।

+0

यदि कॉल स्टैक 'console.log' के कॉल से अधिक है तो __Range error__ को फेंक दिया जाना चाहिए था, क्यों यह एक संदेश के साथ अपवाद फेंक रहा था? –

+3

console.log मूल कोड है, जावास्क्रिप्ट में कोई फ़ंक्शन नहीं है, इसलिए यह जावास्क्रिप्ट स्टैक ट्रेस और अपवाद के साथ नहीं आता है। – overflowed

3

console.log जावास्क्रिप्ट के विनिर्देशन में नहीं है, इसलिए व्यवहार अपरिभाषित है, और रिलीज से रिलीज़ होने के लिए बदला जा सकता है। तो आपके संस्करण में जो कुछ होता है वह शायद हमारे साथ नहीं होता है।

यहां क्या हुआ इसके लिए सबसे अधिक संभावित स्पष्टीकरण दिया गया है: यह निश्चित है कि console.log स्टैक के आकार में वृद्धि करेगा, और क्योंकि आखिरी कथन है जिसे आप रिटर्न से पहले कॉल करते हैं, यह कभी-कभी Maximum call stack उत्पन्न कर सकता है क्योंकि आप बहुत हैं सीमा के करीब। यह अधिकतम कॉल console.log कोड (जो कुछ और कहता है) के अंदर हो सकता है, और यह त्रुटि इसे कैसे संभालेगी, यह console.log के कोड पर निर्भर करती है। ऐसा लगता है कि console.log के अंदर कोड एक त्रुटि होने पर एक अपवाद अपवाद फेंकता है। अब जब आप कोशिश के साथ एक त्रुटि पकड़ते हैं, कोड जारी रहता है, यही कारण है कि सच दिखाई देता है।

यहां jsfiddle में एक उदाहरण है जहां मैं console.log को ओवरराइड करता हूं और परिणाम HTML में दिखाई देते हैं। चीजें कैसे बदलती हैं यह देखने के लिए आप console.log के ओवरराइड कोड को हटाकर खेल सकते हैं। इसे आज़माएं और हमें बताएं कि परिणाम फिर से अजीब लगता है।

यह ध्यान देने योग्य है कि जब Maximum call stack size exceeded त्रुटि प्रकट होती है तो यह स्टैक फ्रेम के आकार (स्थानीय चर) के आकार पर निर्भर करता है।

नोट: ईसीएमएस्क्रिप्ट 6 spec में, यदि फ़ंक्शन कॉल फ़ंक्शन में अंतिम क्रिया है, तो यह ढेर में नहीं जाएगी, लेकिन यह "तुरंत" चलाएगा, इसलिए आपका कोड सभी संख्याओं के लिए त्रुटि के बिना चलाएगा कोई फर्क नहीं पड़ता कि आप कितनी संख्या डालते हैं।

+0

प्लस 1 अच्छा स्पष्टीकरण। –

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