javascript - परिवर्धन असाइनमेंट+=अभिव्यक्ति में व्यवहार




language-lawyer compound-assignment (4)

हाल ही में मैं इस सवाल पर आया था: असाइनमेंट ऑपरेटर श्रृंखला समझ

इस प्रश्न का उत्तर देते समय मैंने अतिरिक्त असाइनमेंट ऑपरेटर += या किसी अन्य operator= (( &= , *= , /= , आदि) के व्यवहार की अपनी समझ पर संदेह करना शुरू कर दिया।

मेरा प्रश्न यह है कि परिवर्तनशील जगह पर अद्यतन किए गए भावों में परिवर्तनशील चर कब है, ताकि मूल्यांकन के दौरान अभिव्यक्ति में अन्य स्थानों पर इसका परिवर्तित मूल्य परिलक्षित हो, और इसके पीछे तर्क क्या है? कृपया निम्नलिखित दो अभिव्यक्तियों पर एक नज़र डालें:

अभिव्यक्ति १

a = 1
b = (a += (a += a))
//b = 3 is the result, but if a were updated in place then it should've been 4

अभिव्यक्ति २

a = 1
b = (a += a) + (a += a)
//b = 6 is the result, but if a is not updated in place then it should've been 4

पहली अभिव्यक्ति में, जब अंतरतम अभिव्यक्ति (a += a) का मूल्यांकन किया जाता है, तो ऐसा लगता है कि यह a मान अपडेट नहीं करता a , इस प्रकार परिणाम 4 बजाय 3 रूप में सामने आता है।

हालाँकि, दूसरी अभिव्यक्ति में, a का मान अद्यतन है और इसलिए परिणाम 6 है।

हमें कब यह मान लेना चाहिए कि अभिव्यक्ति में अन्य स्थानों पर a मूल्य परिलक्षित होगा और हमें कब नहीं करना चाहिए?


Answers

यह सिर्फ ऑप्स के ऑर्डर की विविधता का उपयोग करता है।

यदि आपको ops के आदेश की याद दिलाने की आवश्यकता है:

PEMDAS:

पी = कोष्ठक

= खर्च करने वाले

एमडी = गुणा / भाग

एएस = जोड़ / घटाव

बाकी दाएं से बाएं।

यह भिन्नता केवल बाएं से दाएं पढ़ी जाती है, लेकिन यदि आप देखते हैं कि एक कोष्ठक इसके अंदर सब कुछ करता है, और इसे एक स्थिर के साथ प्रतिस्थापित करता है तो आगे बढ़ें।

पहला पूर्व:

var b = (a+=(a+=a))

var b = (1+=(1+=1))

var b = (1+=2)

var b = 3

दूसरा पूर्व:

var b = (a+=a)+(a+=a)

var b = (1+=1)+(a+=a)

var b = 2 + (2+=2)

var b = 2 + 4

var b = 6

var a = 1
var b = (a += (a += a))
console.log(b);

a = 1
b = (a += a) + (a += a)
console.log(b);

a = 1
b = a += a += a;
console.log(b);

अंतिम एक b = a += a += a चूंकि कोई कोष्ठक नहीं है, यह स्वचालित रूप से b = 1 += 1 += 1 बन जाता है जो कि b = 3


निम्नलिखित नियम हैं जिनका ध्यान रखना आवश्यक है

  • संचालक वरीयता
  • परिवर्तनशील कार्य
  • अभिव्यक्ति का मूल्यांकन

    अभिव्यक्ति १

    a = 1
    b = (a += (a += a))
    
    b = (1 += (a += a))  // a = 1
    b = (1 += (1 += a))  // a = 1
    b = (1 += (1 += 1))  // a = 1
    b = (1 += (2))  // a = 2 (here assignment is -> a = 1 + 1)
    b = (3)  // a = 3 (here assignment is -> a = 1 + 2)

    अभिव्यक्ति २

    a = 1
    b = (a += a) + (a += a)
    
    b = (1 += a) + (a += a) // a = 1
    b = (1 += 1) + (a += a) // a = 1
    b = (2) + (a += a) // a = 2 (here assignment is -> a = 1 + 1)
    b = (2) + (2 += a) // a = 2 (here here a = 2)
    b = (2) + (2 += 2) // a = 2
    b = (2) + (4) // a = 4 (here assignment is -> a = 2 + 2)
    b = 6 // a = 4

    अभिव्यक्ति ३

    a = 1
    b = a += a += a += a += a
    
    b = 1 += 1 += 1 += 1 += 1 // a = 1
    b = 1 += 1 += 1 += 2 // a = 2 (here assignment is -> a = 1 + 1)
    b = 1 += 1 += 3 // a = 3 (here assignment is -> a = 1 + 2)
    b = 1 += 4 // a = 4 (here assignment is -> a = 1 + 3)
    b = 5 // a = 5 (here assignment is -> a = 1 + 4)

याद रखें कि a += x वास्तव में मतलब है a = a + x । समझने के लिए महत्वपूर्ण बिंदु यह है कि जोड़ का मूल्यांकन बाईं से दाईं ओर किया जाता है - अर्थात, a + x का मूल्यांकन a + x से पहले किया जाता है।

तो आइए जानें कि क्या b = (a += (a += a)) करता है। पहले हम नियम का उपयोग करते हैं a += x अर्थ a = a + x , और फिर हम सही क्रम में ध्यान से अभिव्यक्ति का मूल्यांकन करना शुरू करते हैं:

  • b = (a = a + (a = a + a)) क्योंकि a += x अर्थ है a = a + x
  • b = (a = 1 + (a = a + a)) क्योंकि वर्तमान में 1 । याद रखें कि हम सही अवधि (a = a + a) से पहले बाएं शब्द का मूल्यांकन करते हैं
  • b = (a = 1 + (a = 1 + a)) क्योंकि a अभी भी 1
  • b = (a = 1 + (a = 1 + 1)) क्योंकि a अभी भी 1
  • b = (a = 1 + (a = 2)) क्योंकि 1 + 1 2
  • b = (a = 1 + 2) क्योंकि a अब 2
  • b = (a = 3) क्योंकि 1 + 2 3
  • b = 3 क्योंकि a अब 3

यह हमें a = 3 और b = 3 साथ छोड़ देता है जैसा कि ऊपर तर्क दिया गया है।

आइए इसे अन्य अभिव्यक्ति के साथ देखें, b = (a += a) + (a += a) :

  • b = (a = a + a) + (a = a + a)
  • b = (a = 1 + 1) + (a = a + a) , याद रखें कि हम दाएं से पहले बाएं शब्द का मूल्यांकन करते हैं
  • b = (a = 2) + (a = a + a)
  • b = 2 + (a = a + a) and a is now 2. सही शब्द का मूल्यांकन शुरू करें
  • b = 2 + (a = 2 + 2)
  • b = 2 + (a = 4)
  • b = 2 + 4 और a अब 4
  • b = 6

यह हमें a = 4 और b = 6 साथ छोड़ देता है। इसे जावा / जावास्क्रिप्ट में प्रिंट करके और दोनों को सत्यापित किया जा सकता है (दोनों का व्यवहार समान है)।

इन भावों को पार्स ट्री के रूप में सोचने में भी मदद मिल सकती है। जब हम a + (b + c) का मूल्यांकन करते हैं, LHS का मूल्यांकन RHS (b + c) । यह पेड़ की संरचना में कूटबद्ध है:

   +
  / \
 a   +
    / \
   b   c

ध्यान दें कि हमारे पास अब कोई कोष्ठक नहीं है - संचालन का क्रम पेड़ की संरचना में कूटबद्ध है। जब हम पेड़ में नोड्स का मूल्यांकन करते हैं, तो हम नोड के बच्चों को एक निश्चित क्रम में संसाधित करते हैं (यानी, बाएं से दाएं + )। उदाहरण के लिए, जब हम रूट नोड + प्रक्रिया करते हैं, तो हम बाएं उपट्री का मूल्यांकन दायें सबट्री (b + c) से पहले करते हैं, भले ही सही उपरी कोष्ठक में संलग्न हो या नहीं (क्योंकि कोष्ठक में मौजूद नहीं हैं) पार्स ट्री)।

इसके कारण, जावा / जावास्क्रिप्ट हमेशा "सबसे नेस्टेड कोष्ठक" का मूल्यांकन नहीं करते हैं , पहले नियमों के विपरीत जो आपको अंकगणित के लिए पढ़ाया जा सकता है।

जावा भाषा विशिष्टता देखें:

15.7। मूल्यांकन आदेश

जावा प्रोग्रामिंग भाषा की गारंटी है कि ऑपरेटरों के ऑपरेंड का मूल्यांकन एक विशेष मूल्यांकन क्रम में किया जाता है , अर्थात् बाएं से दाएं।
...

15.7.1। पहले बाएं हाथ के संचालन का मूल्यांकन करें

बाइनरी ऑपरेटर के बाएं हाथ के ऑपरेंड का मूल्यांकन पूरी तरह से किया जाता है, इससे पहले कि दाएं हाथ के ऑपरेंड के किसी भी हिस्से का मूल्यांकन किया जाए।

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

आपके प्रश्न के समान और उदाहरण जेएलएस के लिंक किए गए भाग में पाए जा सकते हैं, जैसे:

उदाहरण 15.7.1-1। बाएं हाथ के संचालन का मूल्यांकन पहले किया गया है

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

class Test1 {
    public static void main(String[] args) {
        int i = 2;
        int j = (i=3) * i;
        System.out.println(j);
    }
}

यह कार्यक्रम उत्पादन का उत्पादन करता है:

9

यह 9 के बजाय 6 का उत्पादन करने के लिए * ऑपरेटर के मूल्यांकन के लिए अनुमति नहीं है।


और स्टीवन पेनी के जवाब का कॉफ़ीस्क्रिप्ट संस्करण, क्योंकि यह # 2 Google परिणाम है .... भले ही कॉफी सिर्फ वर्णों के साथ जावास्क्रिप्ट हटा दी गई हो ...;)

baz = "foo"
filter = new RegExp(baz + "d")
"food fight".match(filter)[0] // food

और मेरे विशेष मामले में

robot.name=hubot
filter = new RegExp(robot.name)
if msg.match.input.match(filter)
  console.log "True!"




javascript java language-lawyer compound-assignment