javascript ब्राउज़र में एक ही वेब पेज के लिए कितने जावास्क्रिप्ट प्रोग्राम निष्पादित किए जाते हैं?




browser hoisting (4)

जावास्क्रिप्ट प्रोग्राम में बयान और कार्य घोषणाएं शामिल हैं। जब एक जावास्क्रिप्ट प्रोग्राम निष्पादित किया जाता है, तो ये दो चरण होते हैं:

  1. कोड फ़ंक्शन घोषणाओं और प्रत्येक func के लिए स्कैन किया गया है। घोषणा "निष्पादित" है (एक फ़ंक्शन ऑब्जेक्ट बनाकर) और उस फ़ंक्शन का नामित संदर्भ बनाया गया है (ताकि इस फ़ंक्शन को किसी कथन के भीतर से बुलाया जा सके)

  2. कथन क्रमशः निष्पादित (मूल्यांकन) निष्पादित होते हैं (जैसा कि वे कोड में दिखाई देते हैं)

इसके कारण, यह ठीक काम करता है :

<script>
    foo();
    function foo() {
        return;
    }
</script>

यद्यपि इसे "foo" फ़ंक्शन घोषित करने से पहले बुलाया जाता है, लेकिन यह कार्य करता है क्योंकि कथन से पहले फ़ंक्शन घोषणा का मूल्यांकन किया जाता है।

हालांकि, यह काम नहीं करता है :

<script>
    foo();
</script>
<script>
    function foo() {
        return;
    }
</script>

एक संदर्भ त्रुटि फेंक दी जाएगी ("foo परिभाषित नहीं है")। इससे निष्कर्ष निकाला जाता है कि वेब पेज के एचटीएमएल कोड के अंदर प्रत्येक एससीआरआईपीटी तत्व एक अलग जावास्क्रिप्ट प्रोग्राम का प्रतिनिधित्व करता है और हर बार जब एचटीएमएल पार्सर एससीआरआईपीटी तत्व से मुकाबला करता है, तो वह उस तत्व के अंदर प्रोग्राम निष्पादित करता है (और फिर प्रोग्राम को निष्पादित करने के बाद, पार्सर एचटीएमएल कोड पर चलता है जो एससीआरआईपीटी तत्व का पालन करता है)।

फिर फिर, यह काम करता है :

<script>
    function foo() {
        return;
    }
</script>
<script>
    foo();
</script>

मेरी समझ यह है कि वैश्विक वस्तु (जो वैश्विक निष्पादन संदर्भ में परिवर्तनीय वस्तु के रूप में कार्य करती है) हर समय मौजूद है (और बनी हुई है), इसलिए पहला जावास्क्रिप्ट प्रोग्राम फ़ंक्शन ऑब्जेक्ट बनाएगा और इसके लिए संदर्भ देगा, और उसके बाद दूसरा जावास्क्रिप्ट प्रोग्राम फ़ंक्शन को कॉल करने के लिए उस संदर्भ का उपयोग करेगा। इसलिए, सभी जावास्क्रिप्ट प्रोग्राम (एक ही वेब पेज के भीतर) एक ही वैश्विक वस्तु का उपयोग करते हैं, और एक जावास्क्रिप्ट प्रोग्राम द्वारा ग्लोबल ऑब्जेक्ट में किए गए सभी परिवर्तनों को बाद में चलने वाले सभी जावास्क्रिप्ट प्रोग्रामों द्वारा देखा जा सकता है।

अब, यह ध्यान दें ...

<script>
    // assuming that foo is not defined
    foo();
    alert(1);
</script>

उपर्युक्त मामले में, अलर्ट कॉल निष्पादित नहीं होगा , क्योंकि "foo ()" कथन एक संदर्भ त्रुटि (जो पूरे जावास्क्रिप्ट प्रोग्राम को तोड़ता है) फेंकता है और इसलिए, बाद के सभी कथन निष्पादित नहीं होते हैं।

हालांकि, इस मामले में ...

<script>
    // assuming that foo is not defined
    foo();
</script>
<script>
    alert(1);
</script>

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

अब, मेरे निष्कर्ष हैं:

  • वेब पेज के एचटीएमएल कोड के भीतर प्रत्येक एससीआरआईपीटी तत्व एक अलग जावास्क्रिप्ट प्रोग्राम का प्रतिनिधित्व करता है। ये प्रोग्राम तत्काल निष्पादित होते हैं क्योंकि HTML पार्सर उन्हें मुठभेड़ करता है।
  • एक ही वेब पेज के भीतर सभी जावास्क्रिप्ट प्रोग्राम एक ही वैश्विक वस्तु का उपयोग करते हैं। वह वैश्विक वस्तु हर समय मौजूद होती है (उस क्षण से जब वेब पेज को वेब पेज नष्ट कर दिया जाता है)। जावास्क्रिप्ट प्रोग्राम ग्लोबल ऑब्जेक्ट में हेरफेर कर सकते हैं, और एक जावास्क्रिप्ट प्रोग्राम द्वारा ग्लोबल ऑब्जेक्ट में किए गए सभी बदलावों को बाद के जावास्क्रिप्ट प्रोग्राम में देखा जा सकता है।
  • यदि एक जावास्क्रिप्ट प्रोग्राम टूट जाता है (एक त्रुटि फेंक कर), जो बाद के जावास्क्रिप्ट प्रोग्राम निष्पादित करने से नहीं रोकता है।

कृपया इस पोस्ट को जांचें और मुझे बताएं कि मुझे कुछ गड़बड़ है या नहीं।

साथ ही, मुझे ऐसे संसाधन नहीं मिले हैं जो इस पोस्ट में उल्लिखित व्यवहारों की व्याख्या करते हैं, और मुझे लगता है कि ब्राउज़र निर्माताओं ने कहीं ऐसे संसाधन प्रकाशित किए होंगे, इसलिए यदि आप उनके बारे में जानते हैं, तो कृपया उन्हें लिंक प्रदान करें।

अद्यतन करें!

ठीक है, मैं यहां अपने स्वयं के प्रश्न का उत्तर देने की कोशिश कर रहा हूं :) मुझे दिमित्री ए सोशिकोव से एक प्रतिक्रिया मिली (ई-मेल के माध्यम से) (वह http://www.dmitrysoshnikov.com/ पर जावास्क्रिप्ट के बारे में एक ब्लॉग चलाता है )।

इस मुद्दे पर उनका निर्णय यह है: प्रत्येक एससीआरआईपीटी ब्लॉक में वैश्विक कोड शामिल है। प्रत्येक एससीआरआईपीटी ब्लॉक को निष्पादित करना एक नया निष्पादन संदर्भ बनाता है। इसलिए, प्रत्येक एससीआरआईपीटी ब्लॉक का अपना निष्पादन संदर्भ होता है, लेकिन उन सभी निष्पादन संदर्भों में एक ही वैश्विक वस्तु साझा होती है।

एससीआरआईपीटी ब्लॉक को एक ही साझा राज्य के साथ अलग-अलग "उप-कार्यक्रम" के रूप में देखा जा सकता है।

इसके अलावा, ईसीएमएस्क्रिप्ट स्पेक (तीसरा संस्करण) कहता है (अध्याय 10): "वैश्विक कोड स्रोत टेक्स्ट है जिसे ईसीएमएस्क्रिप्ट प्रोग्राम के रूप में माना जाता है।"


फ़ंक्शन होस्टिंग - प्रक्रिया जो शेष function से पहले function स्टेटमेंट का मूल्यांकन करती है - ईसीएमएस्क्रिप्ट मानक आईआईआरसी का हिस्सा है (मुझे अभी कोई संदर्भ नहीं मिल रहा है, लेकिन मुझे इसका उल्लेख करने वाले ईएमसीएस्क्रिप्ट की चर्चाएं याद आती हैं)। script टैग का मूल्यांकन HTML मानक का हिस्सा है। यह निर्दिष्ट नहीं करता है कि वे इतने सारे शब्दों में "अलग कार्यक्रम" हैं, लेकिन यह कहता है कि दस्तावेज़ में दिखाई देने वाले क्रम में स्क्रिप्ट तत्वों का मूल्यांकन किया जाता है। यही कारण है कि बाद के स्क्रिप्ट टैग में फ़ंक्शंस नहीं फंस गए हैं: स्क्रिप्ट का अभी तक मूल्यांकन नहीं किया गया है। यह भी बताता है कि क्यों एक स्क्रिप्ट रोकना बाद की लिपियों को काट नहीं देता है: जब वर्तमान स्क्रिप्ट मूल्यांकन बंद कर देता है, तो अगला वाला शुरू होता है।


इसके बारे में सोचने का एक और तरीका छद्म स्थानीय बनाम वैश्विक क्षेत्र है। प्रत्येक एससीआरआईपीटी घोषणा में इसके मौजूदा तरीकों / कार्यों के साथ-साथ वर्तमान (पहले घोषित) वैश्विक दायरे तक पहुंच का स्थानीय दायरा भी है। जब भी एक एससीआरआईपीटी ब्लॉक में एक विधि / कार्य परिभाषित किया जाता है, तो इसे वैश्विक दायरे में जोड़ा जाता है और इसके बाद एससीआरआईपीटी ब्लॉक द्वारा सुलभ हो जाता है।

साथ ही, स्क्रिप्ट घोषणा / हैंडलिंग / संशोधन पर W3C से एक और संदर्भ यहां दिया गया है:

दस्तावेज़ के गतिशील संशोधन को निम्नानुसार मॉडलिंग किया जा सकता है:

  1. दस्तावेज लोड होने के बाद सभी एससीआरआईपीटी तत्वों का मूल्यांकन किया जाता है।
  2. एसजीएमएल सीडीएटीए उत्पन्न करने वाले एससीआरआईपीटी तत्व के भीतर सभी स्क्रिप्ट तैयार की जाती हैं। उनके संयुक्त जेनरेट किए गए टेक्स्ट को एससीआरआईपीटी तत्व के स्थान पर दस्तावेज़ में डाला गया है।
  3. जेनरेट की गई सीडीएटीए का फिर से मूल्यांकन किया जाता है।

This स्क्रिप्ट / फ़ंक्शन मूल्यांकन / घोषणा पर एक और अच्छा संसाधन है।


वे अलग कार्यक्रम हैं, लेकिन वे एक साझा वैश्विक वस्तु को संशोधित करते हैं।


दिमित्री सोशिकोव ने आपके प्रश्न का उत्तर दिया है। प्रत्येक <script> तत्व को एक प्रोग्राम के रूप में निष्पादित किया जाता है, जैसा कि ईसीएमएस्क्रिप्ट विनिर्देश द्वारा परिभाषित किया गया है। एक वैश्विक वस्तु है कि एक ही पृष्ठ के भीतर प्रत्येक कार्यक्रम का उपयोग करता है। और यह वास्तव में यह है।





hoisting