जावास्क्रिप्ट के स्वचालित अर्धविराम सम्मिलन (एएसआई) के नियम क्या हैं?


445

खैर, पहले मुझे यह पूछना चाहिए कि क्या यह ब्राउज़र पर निर्भर है।

मैंने पढ़ा है कि यदि एक अमान्य टोकन पाया जाता है, लेकिन कोड का अनुभाग उस अमान्य टोकन तक मान्य है, तो टोकन से पहले एक अर्धविराम सम्मिलित किया जाता है यदि यह एक पंक्ति विराम से पहले है।

हालांकि, अर्धविराम सम्मिलन के कारण होने वाले कीड़े के लिए उद्धृत सामान्य उदाहरण है:

return
  _a+b;

.. जो इस नियम का पालन नहीं करता है, क्योंकि _ एक वैध टोकन होगा।

दूसरी ओर, कॉल चेन टूटने से उम्मीद के मुताबिक काम होता है:

$('#myButton')
  .click(function(){alert("Hello!")});

क्या किसी के पास नियमों का अधिक गहराई से वर्णन है?


22
वहाँ है एक कल्पना ...
मीलों

33
@Miles बस अपने टूटे हुए लिंक ;-) पर नहीं ecma-international.org/publications/standards/Ecma-262.htm
ज़ैक Lysobey

3
पी देखें। उपरोक्त 26 पीडीएफ।
ᴠɪɴᴄᴇɴᴛ


खंड 11.9 स्वचालित अर्धविराम प्रविष्टि
एंड्रयू लैम

जवाबों:


454

सबसे पहले आपको पता होना चाहिए कि स्वचालित अर्धविराम सम्मिलन से कौन से कथन प्रभावित होते हैं (संक्षिप्तता के लिए एएसआई के रूप में भी जाना जाता है):

  • खाली बयान
  • var बयान
  • अभिव्यक्ति कथन
  • do-while बयान
  • continue बयान
  • break बयान
  • return बयान
  • throw बयान

एएसआई के ठोस नियम, विनिर्देश में वर्णित हैं .111.9.1 स्वचालित अर्धविराम सम्मिलन के नियम

तीन मामलों का वर्णन किया गया है:

  1. जब एक टोकन ( LineTerminatorया }) का सामना किया जाता है जिसे व्याकरण द्वारा अनुमति नहीं दी जाती है, तो इससे पहले एक अर्धविराम डाला जाता है:

    • टोकन को पिछले टोकन से कम से कम एक से अलग किया जाता है LineTerminator
    • टोकन है }

    जैसे :

    { 1
    2 } 3

    में तब्दील हो गया है

    { 1
    ;2 ;} 3;

    NumericLiteral 1पहली शर्त, निम्नलिखित टोकन एक लाइन टर्मिनेटर है पूरा करती है। दूसरी शर्त, वह इस प्रकार है टोकन को पूरा करती है ।
    2}

  2. जब टोकन के इनपुट स्ट्रीम का अंत होता है और पार्सर इनपुट टोकन स्ट्रीम को एक पूर्ण प्रोग्राम के रूप में पार्स करने में असमर्थ होता है, तो इनपुट स्ट्रीम के अंत में एक अर्धविराम स्वचालित रूप से डाला जाता है।

    जैसे :

    a = b
    ++c

    में तब्दील हो गया है:

    a = b;
    ++c;
  3. यह मामला तब होता है जब व्याकरण के कुछ उत्पादन द्वारा एक टोकन की अनुमति दी जाती है, लेकिन उत्पादन एक प्रतिबंधित उत्पादन है , प्रतिबंधित टोकन से पहले एक अर्धविराम स्वचालित रूप से डाला जाता है।

    प्रतिबंधित प्रोडक्शंस:

    UpdateExpression :
        LeftHandSideExpression [no LineTerminator here] ++
        LeftHandSideExpression [no LineTerminator here] --
    
    ContinueStatement :
        continue ;
        continue [no LineTerminator here] LabelIdentifier ;
    
    BreakStatement :
        break ;
        break [no LineTerminator here] LabelIdentifier ;
    
    ReturnStatement :
        return ;
        return [no LineTerminator here] Expression ;
    
    ThrowStatement :
        throw [no LineTerminator here] Expression ; 
    
    ArrowFunction :
        ArrowParameters [no LineTerminator here] => ConciseBody
    
    YieldExpression :
        yield [no LineTerminator here] * AssignmentExpression
        yield [no LineTerminator here] AssignmentExpression

    क्लासिक उदाहरण, के साथ ReturnStatement:

    return 
      "something";

    में तब्दील हो गया है

    return;
      "something";

4
# 1: व्याकरण द्वारा अनुमति नहीं दी गई टोकन आमतौर पर एक लाइन टर्मिनेटर नहीं है, क्या यह है (जब तक कि आप # 3 से प्रतिबंधित प्रस्तुतियों का मतलब नहीं है)? ऐसा लगता है कि आपको कोष्ठक को छोड़ देना चाहिए। # 2 ++cस्पष्टता के लिए उदाहरण केवल प्रविष्टि नहीं दिखाना चाहिए ?
बरगी

3
कृपया ध्यान दें कि एएसआई को वास्तव में "अर्धविराम सम्मिलित करें" की आवश्यकता नहीं है, बस एक इंजन के पार्सर में बयान को समाप्त करने के लिए ...
अप्रैल

1
इसे "इनपुट स्ट्रीम" कहते हैं, क्या इसका मतलब "एक लाइन" है? "इनपुट टोकन स्ट्रीम" को समझने के लिए कुछ हद तक कठिन बना दिया जाता है
गैर

क्या किसी और के लिए कल्पना लिंक काम करता है? यह मुझे लगभग एक खाली पृष्ठ पर ले गया, जिस पर एक मृत लिंक था।
इंटेक्रीट

कृपया बताएं कि इन नियमों के अनुसार, "ए [लाइनब्रीक] = [लाइनब्रीक] 3" to to how how how द्वारा नीचे दिए गए उदाहरण अभी भी काम करते हैं
Nir O.

45

ECMA-262 से सीधे , पांचवें संस्करण ECMAScript विशिष्टता :

7.9.1 स्वचालित अर्धविराम सम्मिलन के नियम

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

  1. जब, कार्यक्रम को बाएं से दाएं तरफ पार्स किया जाता है, तो एक टोकन (जिसे अपमानजनक टोकन कहा जाता है ) का सामना करना पड़ता है, जो व्याकरण के किसी भी उत्पादन की अनुमति नहीं है, तो निम्न के अधिक या अधिक होने पर, टोकन से पहले एक अर्धविराम स्वचालित रूप से डाला जाता है स्थितियां सत्य हैं:
    • अपमानजनक टोकन को पिछले टोकन से कम से कम एक से अलग किया जाता है LineTerminator
    • अपमानजनक टोकन है }
  2. जब, कार्यक्रम को बाएं से दाएं तक पार्स किया जाता है, तो टोकन के इनपुट स्ट्रीम का अंत होता है और पार्सर इनपुट टोकन स्ट्रीम को एक ही पूर्ण ECMAScript के रूप में पार्स करने में असमर्थ होता है Program, फिर अर्धविराम स्वचालित रूप से अंत में डाला जाता है आगत प्रवाह।
  3. जब, के रूप में कार्यक्रम बाएं से दाएं पार्स किया गया है, एक टोकन का सामना करना पड़ा है व्याकरण के कुछ उत्पादन द्वारा अनुमति है कि है, लेकिन उत्पादन एक है प्रतिबंधित उत्पादन और टोकन एक टर्मिनल या nonterminal के लिए पहले टोकन होगा तुरंत एनोटेशन निम्नलिखित " [कोई LineTerminatorयहाँ] " प्रतिबंधित उत्पादन के भीतर (और इसलिए इस तरह के एक टोकन एक प्रतिबंधित टोकन कहा जाता है), और प्रतिबंधित टोकन कम से कम एक से पिछले टोकन से अलग है LineTerminator , तो अर्धविराम स्वचालित रूप से प्रतिबंधित टोकन से पहले डाला जाता है।

हालांकि, पूर्ववर्ती नियमों पर एक अतिरिक्त ओवरराइडिंग की स्थिति है: अर्धविराम को स्वचालित रूप से कभी भी डाला नहीं जाता है यदि अर्धविराम को तब एक खाली कथन के रूप में रखा जाएगा या यदि अर्धविराम forकथन के शीर्ष लेख में दो अर्धविरामों में से एक बन जाएगा (देखें 12.6 देखें) .3)।


44

मैं उन 3 नियमों को बहुत अच्छी तरह से समझ नहीं सका - उम्मीद है कि कुछ ऐसा है जो अधिक सादा अंग्रेजी है - लेकिन यहां मैं जावास्क्रिप्ट से इकट्ठा किया गया है: निश्चित गाइड, 6 वें संस्करण, डेविड फ्लैगन, ओ'रेली, 2011:

उद्धरण:

जावास्क्रिप्ट प्रत्येक लाइन ब्रेक को अर्धविराम के रूप में नहीं मानता है: यह आमतौर पर लाइन ब्रेक को अर्धविराम के रूप में मानता है केवल अगर यह अर्धविराम के बिना कोड को पार्स नहीं कर सकता है।

एक और उद्धरण: कोड के लिए

var a
a
=
3 console.log(a)

जावास्क्रिप्ट दूसरी लाइन ब्रेक को अर्धविराम के रूप में नहीं मानता है क्योंकि यह लंबे समय तक बयान को जारी रख सकता है a = 3;

तथा:

सामान्य नियम के दो अपवाद जो जावास्क्रिप्ट व्याख्या रेखा को अर्धविराम के रूप में तोड़ते हैं जब यह पहली पंक्ति पर बयान की निरंतरता के रूप में दूसरी पंक्ति को पार्स नहीं कर सकता है। पहले अपवाद में रिटर्न, ब्रेक और स्टेटमेंट जारी रखना शामिल है

... यदि इन शब्दों में से किसी के बाद एक लाइन ब्रेक दिखाई देता है ... जावास्क्रिप्ट हमेशा उस लाइन ब्रेक को अर्धविराम के रूप में व्याख्या करेगा।

... दूसरे अपवाद में ++ और ... ऑपरेटर शामिल हैं ... यदि आप पोस्ट ऑपरेटर्स के रूप में इन ऑपरेटरों में से किसी एक का उपयोग करना चाहते हैं, तो उन्हें उसी पंक्ति पर दिखाई देना चाहिए जिस अभिव्यक्ति पर वे लागू होते हैं। अन्यथा, लाइन ब्रेक को अर्धविराम के रूप में माना जाएगा, और ++ या - कोड के लिए लागू होने वाले उपसर्ग ऑपरेटर के रूप में पार्स किया जाएगा। इस कोड पर विचार करें, उदाहरण के लिए:

x 
++ 
y

यह जैसा है x; ++y;, वैसा नहीं हैx++; y

तो मुझे लगता है कि इसे सरल बनाने का मतलब है:

सामान्य तौर पर, जावास्क्रिप्ट तक यह समझ में आता है के रूप में कोड की निरंतरता के रूप में यह व्यवहार करेगा - 2 मामलों को छोड़कर: (1) कुछ कीवर्ड को बाद return, break, continue, और (2) अगर यह देखता है ++या --एक नई लाइन पर है, तो यह जोड़ देगा ;पिछले पंक्ति के अंत में।

"इसे तब तक कोड की निरंतरता के रूप में समझें जब तक यह समझ में आता है" यह नियमित अभिव्यक्ति के लालची मिलान की तरह महसूस करता है।

उपर्युक्त के साथ, इसका मतलब है कि returnएक लाइन ब्रेक के साथ, जावास्क्रिप्ट दुभाषिया एक सम्मिलित करेगा;

(फिर से उद्धृत: यदि इन शब्दों में से किसी के बाद एक लाइन ब्रेक दिखाई देता है [जैसे कि return] ... जावास्क्रिप्ट हमेशा उस लाइन ब्रेक को अर्धविराम के रूप में व्याख्या करेगा)

और इस कारण से, का क्लासिक उदाहरण

return
{ 
  foo: 1
}

अपेक्षित रूप से काम नहीं करेगा, क्योंकि जावास्क्रिप्ट दुभाषिया इसे इस प्रकार मानेंगे:

return;   // returning nothing
{
  foo: 1
}

इसके तुरंत बाद कोई लाइन-ब्रेक नहीं होना चाहिए return:

return { 
  foo: 1
}

इसके लिए ठीक से काम करने के लिए। और ;यदि आप ;किसी कथन के बाद उपयोग करने के नियम का पालन करते हैं तो आप खुद को सम्मिलित कर सकते हैं :

return { 
  foo: 1
};

17

अर्धविराम सम्मिलन और var कथन के बारे में, var का उपयोग करते समय कॉमा को भूल जाने पर सावधान रहें, लेकिन कई लाइनों को फैलाते हुए। कल मेरे कोड में किसी ने यह पाया:

    var srcRecords = src.records
        srcIds = [];

यह भागा लेकिन इसका असर यह हुआ कि srcIds घोषणा / असाइनमेंट वैश्विक था क्योंकि पिछली लाइन पर var के साथ स्थानीय घोषणा अब लागू नहीं हुई क्योंकि उस कथन को स्वत: अर्ध-कॉलन सम्मिलन के कारण समाप्त माना गया था।


4
यह थोड़े बात है कि मैं jsLint का उपयोग क्यों करता हूं
Zach Lysobey

1
तुरंत प्रतिक्रिया के साथ अपने कोड संपादक में JsHint / लिंट अधिकार :)
dmi3y

5
@balupton जब अल्पविराम जो लाइन समाप्त हो जाता है वह भूल जाता है, एक अर्ध-बृहदान्त्र स्वचालित रूप से डाला जाता है। एक नियम के विपरीत यह एक "गोच" की तरह था।
डेक्‍सीजन

1
मुझे लगता है कि बालपटन सही है, अगर आप लिखते हैं तो यह एक अंतर है: var srcRecords = src.records srcIds = [];एक पंक्ति में और अल्पविराम को भूल जाओ या आप "रिटर्न ए और& बी" लिखो और कुछ भी मत भूलना ... लेकिन वापसी से पहले एक स्वचालित अर्धविराम सम्मिलित करने से पहले लाइन टूट जाएगी, जो ASI नियमों द्वारा परिभाषित किया गया है ...
सेबस्टियन

3
मैं टाइपिंग की स्पष्टता लगता है var( let, constएक दूसरे इसे टाइप करने के लिए ले जाता है के अंश outweighs प्रत्येक पंक्ति पर)।
स्क्वीडबी

5

जावास्क्रिप्ट के स्वचालित अर्धविराम सम्मिलन का सबसे अधिक प्रासंगिक विवरण क्राफ्टिंग इंटरप्रिटर्स के बारे में एक पुस्तक से आया है ।

जावास्क्रिप्ट का "स्वचालित अर्धविराम सम्मिलन" नियम विषम है। जहाँ अन्य भाषाएँ मानती हैं कि अधिकांश नई कहानियाँ सार्थक हैं और बहु-पंक्ति कथनों में केवल कुछ को अनदेखा किया जाना चाहिए, जेएस इसके विपरीत मानते हैं। यह आपकी सभी नई कहानियों को व्यर्थ व्हाट्सएप के रूप में मानता है जब तक कि यह एक पार्स त्रुटि का सामना न करे। यदि ऐसा होता है, तो यह वापस चला जाता है और पिछले न्यूलाइन को अर्धविराम में बदलने की कोशिश करता है ताकि कुछ व्याकरणिक रूप से मान्य हो सके।

आप इसे गंध का वर्णन करने के लिए आगे बढ़ते हैं

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


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.