2012-10-05 45 views
13

जैसा कि आप जानते हैं, ईसीएमएस्क्रिप्ट स्मार्ट होने का प्रयास करता है और स्वचालित रूप से अर्धविराम डालने पर स्वचालित रूप से उनको लिख नहीं सकता है। सरल उदाहरणस्वत: अर्धविराम सम्मिलन और वापसी विवरण

function foo() { 
    var bar = 5 

    return bar 
} 

अभी भी अपेक्षित काम करेगा। लेकिन अगर आप उस पर भरोसा करते हैं तो कुछ चेतावनी हैं। इसलिए

function foo() { 
    var bar = 5 

    return 
    { 
     bar: bar 
    } 
} 

की तरह है कि समारोह अगर हम फिर से लिखें ..that समारोह अब undefined वापसी होगी क्योंकि दुभाषिया सही return बयान के बाद कि अर्धविराम सम्मिलित हैं (है कि एक कारण है कि आप हमेशा एक ही पर कर्ली कोष्ठक लाना चाहिए है एक बयान के रूप में लाइन)।

बहरहाल, यह सब जानते हुए भी मैं अब सोच रहा हूँ कैसे सुरक्षित एक return बयान निम्नलिखित की तरह है, ब्राउज़र और संस्करण के

function foo() { 
    var a = true, 
     b = true, 
     c = false; 

    return a 
      && b 
      && c; 
} 

भर में मैं सिर्फ एक उत्पादन वातावरण में एक समान return statement लिखा था। सिर्फ इसलिए कि मैं ईसीएमएस्क्रिप्ट के साथ "समस्याएं" के बारे में जानता था, अर्धविराम सम्मिलन के बारे में इतना स्मार्ट नहीं है, अब मैं सोच रहा हूं, अगर वह कोड 100% काम करता है। एफएफ/क्रोम/आईई (नवीनतम संस्करण) पर मेरे पहले परीक्षणों में यह पूरी तरह से ठीक लगता है, लेकिन क्या यह वास्तव में है?

क्या स्वत: अर्धविराम सम्मिलन "जागृत" अगर उस रेखा में return कथन है तो कुछ भी है? क्या कोई इस बारे में कार्यान्वयन-स्तर का विवरण प्रदान कर सकता है?

+1

संभवतः बेहतर डुप्लिकेट: [परिणाम घुंघराले ब्रेस प्लेसमेंट के आधार पर क्यों भिन्न होते हैं?] (Http://stackoverflow.com/q/3641519/1048572) – Bergi

उत्तर

10

जावास्क्रिप्ट दुभाषिया/कंपाइलर केवल स्वचालित अर्धविराम डालने के लिए इतना स्मार्ट है यदि बाद में वैध जावास्क्रिप्ट है।

आपका कोड काम करता है, क्योंकि && b यह खड़ा के रूप में कोई वैध अभिव्यक्ति है - यही कारण है कि कोई अर्धविराम return a में जिसके परिणामस्वरूप के बाद सम्मिलित हो जाता है:

return a && b && c; 
हालांकि

:

return (undefined);//implicitely inserted 
{ 
    .... 
} 

पूरी तरह से वैध है और यही कारण है कि एक अर्धविराम क्यों डाला जाता है।

पूर्णता के लिए 'spec को रेफरी: automatic semicolon insertion। ये उदाहरण पढ़ने के लायक हैं।

+0

प्रतिक्रिया के लिए धन्यवाद - मुझे पहले से ही स्पेक का वह अनुभाग मिला है, हालांकि, मैं अभी भी सोच रहा हूं कि (मोबाइल) ब्राउज़र और संस्करणों के लिए उस विशेष अनुभाग को कितना अच्छा/सही किया गया था और यदि हम उस व्यवहार पर 100% भरोसा कर सकते हैं। – jAndy

+0

कुछ छोटे मोबाइल ब्राउज़र हैं जो ecmascript के केवल सीमित सबसेट का समर्थन करते हैं लेकिन ये अधिकतर विशेष कार्य हैं। हालांकि, मुझे पूरा भरोसा है कि spec के इन "मूल" भागों को ब्राउज़रों में लगातार लगातार लागू किया जाता है। – Christoph

+1

कम से कम क्रोम में, दावा * जावास्क्रिप्ट दुभाषिया/कंपाइलर केवल स्वचालित अर्धविराम डालने के लिए इतना स्मार्ट है अगर बाद में वैध जावास्क्रिप्ट है। * गलत है। उदाहरण के लिए, ओपी का उदाहरण लें और उद्धरणों में कुंजी 'बार' को लपेटें ताकि वह 'बार' पढ़ सके। अब, वापसी के समान लाइन पर खुले ब्रेस के साथ, सबकुछ काम करता है; उनके बीच लाइन ब्रेक डालने के साथ, स्वचालित सेमी-कॉलन सम्मिलन एक वाक्यविन्यास त्रुटि बनाता है। –

0

क्रिस्टोफ बताते हैं कि आपका रिटर्न स्टेटमेंट सभी ब्राउज़रों में सही तरीके से काम करेगा। मैं कम से कम और ऑपरेटरों को अलग ढंग से रखकर कंप्यूटर के लिए नहीं तो लेकिन मनुष्य के लिए, यह और भी अधिक स्पष्ट बनाने के लिए पसंद करते हैं:

return a && 
     b && 
     c; 

इस मामले में कोई भी सोच स्वत: अर्द्ध कोलन कर रहे हैं एक दूसरे खर्च करने की जरूरत में विनाश को खत्म करने जा रहा है। मैं केवल जावास्क्रिप्ट के लिए इसे पसंद करता हूं, आपका मूल कोड पढ़ने में आसान है।

2

ब्राउज़र/इम्प्लांटेशन विशिष्ट नहीं है, लेकिन ECMAScript Language Specification के Section 7.9 Automatic Semicolon Insertion पढ़ने योग्य है।

7।9 स्वत: अर्द्धविराम निवेशन

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

7.9.1 स्वत: अर्द्धविराम प्रविष्टि के नियम अर्धविराम प्रविष्टि के तीन बुनियादी नियम नहीं हैं:

  1. करते हैं, के रूप में कार्यक्रम बाएं से दाएं पार्स किया गया है, एक टोकन (हमलावर टोकन कहा जाता है) है

    • offe: कि व्याकरण के किसी भी उत्पादन से अनुमति नहीं है सामना करना पड़ा, तो एक अर्धविराम स्वचालित रूप से हमलावर टोकन अगर एक या निम्न स्थितियों के और अधिक सच है से पहले डाला जाता है nding टोकन को कम से कम एक लाइन टर्मिनेटर द्वारा पिछले टोकन से अलग किया जाता है।
    • अपमानजनक टोकन} है।
  2. करते हैं, के रूप में कार्यक्रम बाएं से दाएं पार्स किया गया है, टोकन के इनपुट धारा के अंत का सामना करना पड़ा है और पार्सर एक एकल पूर्ण ECMAScript कार्यक्रम के रूप में इनपुट टोकन धारा पार्स करने में अक्षम है, तो इनपुट स्ट्रीम के अंत में एक अर्धविराम स्वचालित रूप से डाला जाता है।

  3. करते हैं, के रूप में कार्यक्रम बाएं से दाएं पार्स किया गया है, एक टोकन का सामना करना पड़ा है कि व्याकरण के कुछ उत्पादन द्वारा अनुमति दी है, लेकिन उत्पादन एक प्रतिबंधित उत्पादन और टोकन एक के लिए पहली टोकन होगा एनोटेशन के तुरंत बाद टर्मिनल या nonterminal? [कोई लाइन टर्मिनेटर यहाँ]? प्रतिबंधित उत्पादन (और इसलिए इस तरह के टोकन को प्रतिबंधित टोकन कहा जाता है) के भीतर, और प्रतिबंधित टोकन कम से कम एक लाइन टर्मिनेटर द्वारा पिछले टोकन से अलग किया गया है, फिर एक अर्धविराम स्वचालित टोकन से पहले डाला गया है। हालांकि, पिछले नियमों पर एक अतिरिक्त ओवरराइडिंग स्थिति है: अर्धविराम को स्वचालित रूप से कभी नहीं डाला जाता है यदि अर्धविराम को खाली वक्तव्य के रूप में पार्स किया जाएगा या यदि वह सेमीकॉलन बन जाएगा, तो इसके लिए हेडर में दो अर्धविरामों में से एक बयान (12.6.3 देखें)। नोट निम्नलिखित व्याकरण में ही सीमित प्रस्तुतियों हैं: PostfixExpression: LeftHandSideExpression [यहाँ कोई LineTerminator] ++ LeftHandSideExpression [यहाँ कोई LineTerminator] - ContinueStatement: जारी रखने के लिए [यहाँ कोई LineTerminator] पहचानकर्ता; ब्रेकस्टेटमेंट: ब्रेक [कोई लाइन टर्मिनेटर यहाँ] पहचानकर्ता; रिटर्नस्टेटमेंट: वापसी [यहां कोई लाइन टर्मिनेटर नहीं] अभिव्यक्ति; थ्रोस्टेटमेंट: फेंक [कोई लाइन टर्मिनेटर यहाँ] अभिव्यक्ति; इन प्रतिबंधित प्रस्तुतियों का व्यावहारिक प्रभाव इस प्रकार है: जब एक ++ या - टोकन का सामना करना पड़ता है जहां पार्सर इसे पोस्टफिक्स ऑपरेटर के रूप में मानता है, और कम से कम एक लाइन टर्मिनेटर पिछले टोकन और ++ या - टोकन, फिर एक अर्धविराम स्वचालित रूप से +12 या - टोकन से पहले डाला जाता है। जब कोई जारी, ब्रेक, रिटर्न, या टोकन फेंक दिया जाता है और अगले टर्नकेन से पहले एक लाइन टर्मिनेटर का सामना करना पड़ता है, तो जारी रखने, ब्रेक करने, वापसी करने या टोकन फेंकने के बाद अर्धविराम स्वचालित रूप से डाला जाता है। ईसीएमएस्क्रिप्ट प्रोग्रामर के लिए परिणामी व्यावहारिक सलाह है: एक पोस्टफिक्स ++ या - ऑपरेटर अपने ऑपरेंड के समान लाइन पर दिखाई देना चाहिए। वापसी या फेंक कथन में एक अभिव्यक्ति वापसी या फेंक टोकन के समान लाइन पर शुरू होनी चाहिए। ब्रेक या जारी कथन में एक पहचानकर्ता ब्रेक या टोकन जारी रखने के समान लाइन पर होना चाहिए।

7.9.2 स्वत: अर्द्धविराम निवेशन

स्रोत

{ 1 2 } 3 

के उदाहरण ECMAScript व्याकरण में एक वैध वाक्य, यहां तक ​​कि स्वचालित अर्धविराम प्रविष्टि के नियमों के साथ नहीं है। इसके विपरीत, स्रोत

{ 1 
2 } 3 

में भी एक वैध ECMAScript वाक्य नहीं है, लेकिन निम्नलिखित में स्वत: अर्धविराम प्रविष्टि द्वारा तब्दील हो जाता है:

{ 1 
;2 ;} 3; 

जो एक वैध ECMAScript वाक्य है। स्रोत

for (a; b 
) 

एक वैध ECMAScript वाक्य नहीं है और क्योंकि अर्धविराम बयान के लिए एक के शीर्षक के लिए आवश्यक है स्वत: अर्धविराम प्रविष्टि से परिवर्तित नहीं होता। स्वत: अर्धविराम सम्मिलन किसी कथन के शीर्षलेख में दो अर्धविरामों को में से किसी एक को कभी भी सम्मिलित नहीं करता है। स्रोत

return 
a + b 

में स्वत: अर्धविराम प्रविष्टि द्वारा तब्दील हो जाता है निम्नलिखित:

return; 
a + b; 

नोट अभिव्यक्ति ए + बी, वापसी कथन द्वारा दिए जाते एक मूल्य के रूप में इलाज नहीं है, क्योंकि एक LineTerminator इसे टोकन रिटर्न से अलग करता है। स्रोत

a = b 
++c 

में स्वत: अर्धविराम प्रविष्टि द्वारा तब्दील हो जाता है निम्नलिखित:

a = b; 
++c; 

नोट टोकन ++, एक पोस्टफ़िक्स ऑपरेटर चर ख के लिए आवेदन के रूप में इलाज नहीं है, क्योंकि एक LineTerminator होता बी और ++ के बीच। स्रोत

if (a > b) 
else c = d 

एक वैध ECMAScript वाक्य नहीं है और फिर किसी और टोकन से पहले स्वत: अर्धविराम प्रविष्टि से परिवर्तित नहीं होता, भले ही व्याकरण की कोई उत्पादन, उस बिंदु पर लागू होता है क्योंकि एक स्वचालित रूप से डाले अर्धविराम हैं एक खाली बयान के रूप में पार्स किया जाना चाहिए। स्रोत

a = b + c 
(d + e).print() 

, स्वत: अर्धविराम प्रविष्टि से बदल नहीं है, क्योंकि parenthesised अभिव्यक्ति है कि दूसरी पंक्ति शुरू होता है एक समारोह कॉल के लिए एक तर्क सूची के रूप में व्याख्या की जा सकती:

a = b + c(d + e).print() 

परिस्थिति में कि एक असाइनमेंट कथन बाएं कोष्ठक के साथ शुरू होना चाहिए, प्रोग्रामर के लिए स्वचालित अर्धविराम सम्मिलन पर भरोसा करने के बजाय पिछले कथन के अंत में एक स्पष्ट अर्धविराम प्रदान करने के लिए यह एक अच्छा विचार है।