2011-05-26 5 views
5

मुझे कुछ बार बताया गया है कि जावास्क्रिप्ट में अपवादों का उपयोग करने के लिए यह "खराब" है। वास्तव में यह नहीं बताया गया है कि यह बुरा क्यों है, लेकिन इसके बजाय मुझे ब्रेक का उपयोग करना चाहिए, इसके बजाय जारी रखना और वापस करना चाहिए।जावास्क्रिप्ट में अपवाद, क्या मुझे उनका उपयोग करना चाहिए और कैसे?

जो ठीक है, सिवाय मुझे छोड़कर/ब्रेक/जारी रखने की आवश्यकता नहीं है, मुझे फेंकने की जरूरत है। मेरे पास एक ऐसा मामला है जहां मेरे पास एक-दूसरे में घूमने वाला इटरेटर फ़ंक्शन है, प्रत्येक व्यक्ति कॉल पर अगला मान देता है, इसलिए मैं यह इंगित करने के लिए अपवाद का उपयोग करता हूं कि पुनरावृत्ति करने के लिए और कुछ भी नहीं है: ऐसा करने के लिए एक तार्किक तरीका लगता है, कोड साफ़ करता है और अभ्यास में पूरी तरह से काम करता है। जेएस में अपवादों का उपयोग न करने का कोई कारण नहीं है?

दूसरा प्रश्न, जब मैं अपवादों का उपयोग कर रहा हूं, तो मुझे किस तरह की वस्तुओं को फेंकना चाहिए? त्रुटियों के लिए मैं स्पष्ट रूप से त्रुटि के उदाहरण फेंक दूंगा, लेकिन विशेष मामलों के लिए (पुनरावृत्ति रोकें, आदि) मुझे उन विशिष्ट अपवादों की जांच करने के लिए एक त्वरित तरीका चाहिए, और मैंने जो किया वह बस एक खाली नामित फ़ंक्शन (फ़ंक्शन स्टॉपइटरेशन() { }) और चूंकि कार्यों की तुलना संदर्भ से की जाती है, मैं हमेशा यह जांच सकता हूं कि यह मेरा विशेष मामला है या मुझे बस फिर से जाना चाहिए। क्या यह जेएस में ऐसा करने के लिए एक बेहतर या अधिक मूर्ख तरीका है? क्या मुझे वास्तव में अपवादों का उपयोग करने से बचने के लिए अपने कोड को दोबारा करने की कोशिश करनी चाहिए?

धन्यवाद

+0

मुझे बताया गया है कि {try {} पकड़ (ई) {} 'बंद करने का प्रयास निष्पादन को धीमा कर देगा। सत्यापित करने के लिए परीक्षण करने की आवश्यकता है। – timdream

+0

[जावास्क्रिप्ट ट्राई-कैच प्रदर्शन बनाम के संभावित डुप्लिकेट। त्रुटि जांच कोड] (http://stackoverflow.com/questions/3217294/javascript-try-catch-performance-vs-error-checking-code) – Pointy

उत्तर

2

अपवाद हैंडलिंग में है सामान्य सामान्य मूल्यांकन की तुलना में और केवल असाधारण स्थितियों

पुनरावृत्तियों आने के लिए एक अंतिम स्थिति के लिए एक hasNext या isEmpty समारोह को परिभाषित करने के लिए बेहतर कर रहे हैं या एक वापसी के लिए धीमी प्रहरी मूल्य (जैसे undefined) जब वहाँ कोई और अधिक तत्वों तो पाश

//with hasNext 
while(it.hasNext()){ 
var val = it.next(); 
//... 
} 
//or with a sentinal undefined 
while((val = it.next()) !== undefined){ 
//... 
} 
+0

धन्यवाद! अद्वितीय नामों के लिए नामित कार्यों का उपयोग करने के बारे में क्या? क्या ऐसा करना एक अच्छा विचार है? – fingerprint211b

+0

आपका क्या मतलब है? (और यदि आप मेरा उत्तर स्वीकार करते हैं तो इसे स्वीकार करने के लिए इसके आगे के टिकमार्क पर क्लिक करें < के लिए भीख मांगना '' –

3

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

भाषा डिजाइनर इस गड़बड़ी से अवगत हैं, इसलिए वे हमें लूप संरचनाओं के लिए लेबल (नाम) देने की अनुमति देते हैं ताकि हम उन्हें तोड़ सकें (या उन्हें जारी रखें)। इस उदाहरण पर विचार करें:

function findValueInMatrix(value, matrix) { 
    var r, c, coords, rows=matrix.length, cols=matrix[0].length; 
    found: // Label the outer loop as "found" so we can break from it. 
    for (r=0; r<rows; r++) { 
    for (c=0; c<cols; c++) { 
     if (matrix[r][c] == value) { 
     coords = [r, c] 
     break found; // Exit the loop labeled "found". 
     } 
    } 
    } 
    return coords; 
} 

आप this post about breaking from nested loops में अधिक जानकारी प्राप्त कर सकते हैं।

यह jsPerf test case यह भी दर्शाता है कि एक लेबल को तोड़ना एक अपवाद फेंकने से अधिक तेज़ है (संभवतः अधिकांश ब्राउज़रों में)।

+0

' अपवाद द्वारा कोडिंग 'से विकिपीडिया पृष्ठ आप संदर्भित करते हैं:' यह विरोधी-पैटर्न सॉफ़्टवेयर अपवाद हैंडलिंग से असंबंधित है ' । – molnarg

+0

@molnarg: हाँ, अच्छा अवलोकन। मैंने लिंक हटा दिया है। – maerics

0

कुछ लोगों के लिए, यह इंगित करने के लिए अपवाद फेंकना कि कोई और मूल्य खराब शैली नहीं है; अपवाद असाधारण व्यवहार के लिए किए गए हैं।

इसके अलावा, अपवाद हैंडलिंग आमतौर पर सरल परीक्षणों से धीमी होती है। अंतर वास्तव में मामूली है (और हो सकता है कि यहां तक ​​कि अस्तित्व में न हो) यदि फेंक दिया गया उदाहरण हर बार नहीं बनाया जाता है। तो स्थिर StopIteration और इसे फेंकना वास्तव में काफी तेज़ है।

आपकी समस्या के लिए, आप https://developer.mozilla.org/en/JavaScript/Guide/Iterators_and_Generators देख सकते हैं (वे पुनरावृत्ति रोकने के लिए अपवादों का उपयोग करते हैं)। मैंने पाया कि गतिशील रूप से टाइप की गई भाषाओं में अपवादों का भी इस तरह के उद्देश्यों के लिए उपयोग किया जाता है।

-1

एक अपवाद फेंकने एक नेस्टेड पुनरावर्ती खोज/पैदल दूरी से बाहर तोड़ सबसे आसान और अधिक सुरुचिपूर्ण जाने का रास्ता है।

आप एक पेड़ चलना, recursivelly एक समारोहवर्तमान नोड को संभालने के लिए बुला रहे हैं, अपने बच्चों और इतने पर से प्रत्येक के लिए फिर से कॉल कहो।

के रूप में आप प्रक्रिया प्रत्येक नोड, आप पूरे कॉल स्टैक तोड़ने completelly और वापसी पाया मूल्य (सामान्य रूप में पुनरावृत्ति या बंद), सभी छोरों पिछले में इंतजार कर रहे हैं कि को तोड़ते करना चाह सकते हैं कहता है। आपको लगता है कि ये पिछली कॉल & मेमोरी को संसाधित करने में महंगा हो सकती है, लेकिन यदि आप अपना परिणाम "पाया" बेकार है। एक अपवाद फेंकना यह हासिल करने का सबसे प्रभावी और सरल तरीका है, लेकिन निश्चित रूप से इसे ध्यान देने की जरूरत है।

सरल (यहां तक ​​कि नेस्टेड) ​​के लिए इसे एक ओवरकिल लूप करता है और सही ढंग से एंटी-पैटर्न के रूप में कहा जाता है।

+0

रुचि रखने वाले किसी भी व्यक्ति के लिए, जावास्क्रिप्ट अपवादों का उपयोग अपवादों का उपयोग करके पूंछ-कॉल अनुकूलन सजावट की नकल करने के लिए किया जा सकता है http://jacob.jkrall.net/js-tco/। –

+0

प्रदर्शन हालांकि हास्यास्पद रूप से खराब है, इसलिए सिर्फ इसलिए कि आप _can_, इसका मतलब यह नहीं है कि आप _should_। –

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