बंद शैली में क्या अंतर है

जावास्क्रिप्ट में दो लोकप्रिय बंद शैलियों हैं। पहला मैं अज्ञात कन्स्ट्रक्टर को कॉल करता हूं:

new function() { 
  var code...
}

और इनलाइन निष्पादित फ़ंक्शन :

(function() {
  var code...
})();

क्या उन दोनों के बीच व्यवहार में मतभेद हैं? क्या दूसरे पर एक "बेहतर" है?

0
ro fr bn

6 उत्तर

हां, दोनों के बीच मतभेद हैं।

दोनों अज्ञात कार्य हैं और ठीक उसी तरह निष्पादित करते हैं। लेकिन, दोनों के बीच का अंतर यह है कि दूसरे मामले में चर के गुंजाइश गुमनाम कार्य तक ही सीमित है। वैश्विक दायरे में गलती से चर जोड़ने का कोई मौका नहीं है।

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

उदाहरण:

<html>
<body>
<script type="text/javascript">

new function() { 
a = "Hello";
alert(a + " Inside Function");
};

alert(a + " Outside Function");

(function() { 
var b = "World";
alert(b + " Inside Function");
})();

alert(b + " Outside Function");
</script>
</body>
</html>

उपरोक्त कोड में आउटपुट कुछ ऐसा है:

हैलो अंदरूनी समारोह
  बाहर समारोह के बाहर हैलो   विश्व अंदरूनी समारोह

... फिर, आपको एक त्रुटि मिलती है क्योंकि 'बी' को फ़ंक्शन के बाहर परिभाषित नहीं किया गया है!

इस प्रकार, मेरा मानना ​​है कि दूसरी विधि बेहतर है ... सुरक्षित!

0
जोड़ा
-1 यह "ए" को वैश्विक बनाने के पहले "var" को छोड़ने के कारण है और सवाल से असंबंधित है।
जोड़ा लेखक Tomas, स्रोत

दूसरा उदाहरण इसे बनाने के बाद फ़ंक्शन निष्पादित करेगा।

संपादित करें: यह वास्तव में सच नहीं है।

0
जोड़ा

खैर, मैंने इस तरह का एक पेज बनाया है:

<html>
<body>
<script type="text/javascript">
var a = new function() { 
  alert("method 1");

  return "test";
};

var b = (function() {
  alert("method 2");

  return "test";
})();

alert(a);  //a is a function
alert(b);  //b is a string containing "test"

</script>
</body>
</html>

आश्चर्यजनक रूप से पर्याप्त (मुझे वैसे भी) यह "विधि 1" और विधि 2 दोनों को सतर्क करता है। "मुझे" विधि 1 "को सतर्क करने की उम्मीद नहीं थी। अंतर यह था कि ए और बी के मूल्य क्या थे। यह कार्य ही था, जबकि बी स्ट्रिंग था कि समारोह वापस आ गया।

0
जोड़ा

वे दोनों कोड ब्लॉक निष्पादित करके बंद कर देते हैं। शैली के मामले में मैं कुछ कारणों से दूसरे को पसंद करता हूं:

यह पहली बार चमकते हुए स्पष्ट नहीं है कि कोड वास्तव में निष्पादित किया जाएगा; लाइन जैसा दिखता है यह एक नया फ़ंक्शन बना रहा है एक नया फ़ंक्शन है, इसे एक कन्स्ट्रक्टर के रूप में निष्पादित करने के बजाय, लेकिन यह वास्तव में नहीं हो रहा है। कोड से बचें जो ऐसा नहीं करता है जो ऐसा लगता है!

इसके अलावा (function() { ... }) (); अच्छा बुकेंड टोकन बनाएं ताकि आप तुरंत देख सकें कि आप प्रवेश बंद कर रहे हैं और छोड़ रहे हैं। यह अच्छा है क्योंकि यह प्रोग्रामर को स्कोप परिवर्तन में पढ़ने के लिए चेतावनी देता है, और विशेष रूप से उपयोगी होता है यदि आप फ़ाइल के कुछ पोस्टप्रोसेसिंग कर रहे हैं, उदाहरण के लिए खनन के लिए।

0
जोड़ा

@ लांस: पहला भी निष्पादित कर रहा है। एक नामित निर्माता के साथ इसकी तुलना करें:

function Blah() {
    alert('blah');
}
new Bla();

यह वास्तव में कोड निष्पादित भी कर रहा है। अज्ञात कन्स्ट्रक्टर के लिए भी यही है ...

लेकिन वह सवाल नहीं था ;-)

0
जोड़ा

दोनों मामले फ़ंक्शन निष्पादित करेंगे, केवल वास्तविक अंतर यह है कि अभिव्यक्ति का वापसी मूल्य क्या हो सकता है, और "यह" का मूल्य फ़ंक्शन के अंदर क्या होगा।

मूल रूप से व्यवहार

new expression

प्रभावी रूप से बराबर है

var tempObject = {};
var result = expression.call(tempObject);
if (result is not an object)
    result = tempObject;

हालांकि निश्चित रूप से tempObject और परिणाम क्षणिक मान हैं जिन्हें आप कभी नहीं देख सकते हैं (वे दुभाषिया में कार्यान्वयन विवरण हैं), और "ऑब्जेक्ट नहीं है" चेक करने के लिए कोई जेएस तंत्र नहीं है।

व्यापक रूप से "नया फ़ंक्शन() {..}" बोलना कन्स्ट्रक्टर के लिए इस ऑब्जेक्ट को बनाने की आवश्यकता के कारण धीमा हो जाएगा।

ऐसा कहा जाता है कि यह वास्तविक अंतर नहीं होना चाहिए क्योंकि ऑब्जेक्ट आवंटन धीमा नहीं है, और आपको हॉट कोड में ऐसे कोड का उपयोग नहीं करना चाहिए (फ़ंक्शन ऑब्जेक्ट और संबंधित बंद करने की लागत के कारण)।

Edit: one thing i realised that i missed from this is that the tempObject will get expressions prototype, eg. (before the expression.call) tempObject.__proto__ = expression.prototype

0
जोड़ा