2012-08-10 13 views
6

इन संरचनाओं के बीच अंतर, पेशेवर/विपक्ष (यदि कोई है) क्या है?जावास्क्रिप्ट बंद सिंटैक्स

new function(obj) { 
    console.log(obj); 
}(extObj); 

बनाम

(function(obj) { 
    console.log(obj); 
})(extObj); 
+0

क्या मैं जोड़ सकता हूं - क्या '(Funct' के बीच कोई अंतर है आयन (ओबीजे) {..}) (extObj); 'और' फ़ंक्शन (ओबीजे) {..}) (extObj); '? –

+2

@ मैट कोई नहीं है। – Christoph

उत्तर

4

आप एक तुरंत-लागू समारोह के साथ स्पष्ट रूप से निपटने पर देख रहे हैं, तो नहीं दोनों के बीच कोई वास्तविक अंतर है, सिवाय इसके कि पहले एक this वापस आ जाएगी फ़ंक्शन के अंदर, बाहरी दुनिया में, स्वचालित रूप से (new करता है), और डिफ़ॉल्ट रूप से यदि एक अलग वापसी मान निर्दिष्ट नहीं है (नियमित फ़ंक्शन undefined लौटाते हैं)।

शेष प्रमुख मतभेद वास्तव में कोई फर्क नहीं पड़ता है - प्रोटोटाइप श्रृंखला तक पहुंच व्यर्थ होने जा रही है, जिसमें this.constructor गुमनाम फ़ंक्शन पर वापस आने से आपको अज्ञात फ़ंक्शन को उपयोग के लिए कैशिंग करने की सुविधा मिल जाएगी बाद में (जैसे किसी ईवेंट श्रोता से इसे हटाने की तरह, यदि आप किसी भी तरह से संलग्न कार्य को चिपकाने में कामयाब रहे ... ... यह एक चाल है और खुद ही)।

लौटने वाले this ऑब्जेक्ट की एक कन्स्ट्रक्टर प्रॉपर्टी के रूप में लोगों को तत्काल-बुलाए गए फ़ंक्शन को कैश करने की अनुमति देना ऑब्जेक्ट सुरक्षा-जोखिम हो सकता है ... ... या यह वास्तव में उपयोगी हो सकता है ... ... बहुत विशिष्ट परिदृश्यों में ।

ऑनलाइन फ़ायरिंग कोड के हर दिन के उद्देश्य - कोई वास्तविक अंतर नहीं।

+0

मैं आपकी आखिरी वाक्य से असहमत हूं जैसे ही यह उस बिंदु पर आता है जहां आप परिवर्तनीय असाइनमेंट के साथ काम करते हैं। – Christoph

+0

@ क्रिस्टोफ कैसे? मेरा मतलब यह है कि वापसी का बयान पकड़ने के लिए वहां कोई चर नहीं है, तो फ़ंक्शन के अंदर क्या होता है, उसमें बहुत अंतर नहीं होने वाला है। नेमस्पेसिंग मॉड्यूल के मामले में या जो कुछ भी आप कर सकते हैं, वहां बड़ी विधियां हो सकती हैं। यदि आप वैश्विक क्षेत्र के बाहर तत्काल, प्रक्रियात्मक कोड को रेखांकित कर रहे हैं, जिसे बाद में उपयोग के लिए एक var में वापस नहीं किया जा रहा है, तो 'नया' या '(' या '! 'सभी एक ही चीज़ को प्राप्त करने जा रहे हैं, न्यूनतम (व्यावहारिक रूप से कोई नहीं) साइड इफेक्ट्स के साथ। – Norguard

+0

मैं आपके कथन से सहमत हूं हालांकि मुझे लगता है कि रिटर्न वैल्यू को किसी तरह से स्टोर करना काफी आम है। इसलिए मैं बस यह इंगित करना चाहता था कि उनके पास जो कुछ भी हो सकता है उसके बारे में उनका अलग व्यवहार प्रमुख प्रभाव – Christoph

9

पहला व्यक्ति आपके अज्ञात कन्स्ट्रक्टर फ़ंक्शन (= this) के नए निर्मित उदाहरण का संदर्भ देता है।

दूसरा व्यक्ति अज्ञात फ़ंक्शन का रिटर्न मान देता है। चूंकि आपके फ़ंक्शन में रिटर्न स्टेटमेंट नहीं है, इसलिए यह निश्चित रूप से अपरिभाषित रूप से वापस आ जाएगा।

निम्नलिखित का प्रयास करें: (। Btw, t1.constructor आप के साथ t1 बनाया मूल कार्य वापस आ जाएगी)

var t1 = new function(obj) { console.log(obj); }(extObj); 
var t2 = (function(obj) { console.log(obj); })(extObj); 

typeof t1 => "object" 
typeof t2 => "undefined" 

अंतर यदि आप एक वापसी कथन जोड़ने के लिए, अधिक स्पष्ट हो जाता है:

var t1 = new function(obj){ return(obj); }("foo"); 
var t2 = (function(obj){ return(obj); })("bar"); 

console.log(t1) => "object" 
console.log(t2) => "bar" 

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

var myNameSpace = (function(){ 
    /* do some private stuff here*/ 
    ... 
    /* expose parts of your anonymous function by returning them */ 
    return{ 
     functionX, 
     variable1, 
     variable2 
    } 
}(); 

मूल रूप से आप एक अभिव्यक्ति में समारोह घोषणा चालू करने के लिए एक मनमाना एकल ऑपरेटर का उपयोग कर सकते हैं, कि तुरंत शुरू हो जाती है। तो अगर आप भी लिख सकते हैं:

!function(){ /* code */ }(); 
~function(){ /* code */ }(); 
-function(){ /* code */ }(); 
+function(){ /* code */ }(); 

अपने कार्य की वापसी बयान के आधार पर, इन विभिन्न वापसी परिणाम प्राप्त होंगे। ! - रिटर्नव्यू +|- संख्या के रूप में मूल्यांकन करें (ऋणात्मक चिह्न लागू करें) ~ वापसी मूल्य पर bitwise not लागू करें।

1

एक और अंतर यह है कि पहला आविष्कार एक अतिरिक्त वस्तु बनाता है।यहाँ मैं नाम f और o डाल दिया है एक वस्तुओं को निरूपित करने के:

var o = new function f(obj) { 
    console.log(obj); 
}(extObj); 

दूसरे मामले में हम अभी भी एक समारोह वस्तु f बनाने, लेकिन हम एक o नहीं:

(function f(obj) { 
    console.log(obj); 
})(extObj); 

एक बंद अभी भी बनाया गया है लेकिन यह वास्तविक जावास्क्रिप्ट ऑब्जेक्ट से सस्ता है क्योंकि इसमें पूरे प्रोटोटाइप श्रृंखला या अन्य विशेषताओं (जैसे छिपे हुए वर्ग संदर्भ) नहीं हैं,

+0

जो पूरी तरह से सच नहीं है। आप दूसरे मामले में ऑब्जेक्ट बना सकते हैं, लेकिन चूंकि कोई रिटर्न वैल्यू नहीं है, इसलिए 'ओ' को उस फ़ंक्शन के निहित रिटर्न वैल्यू को असाइन किया गया है, जो अपरिभाषित है। – Christoph

+0

तो, 'ओ' अपरिभाषित होगा और कोई ऑब्जेक्ट नहीं बनाया जाएगा, है ना? –

+0

यदि आप 'var o = (function ...' लिखते हैं तो ओ "अनिर्धारित" के असाइन किए गए मान के साथ मौजूद है जो बहुत अधिक बेकार है क्योंकि आप इसे गैर-मौजूदा चर से अलग नहीं कर सकते हैं जो "अपरिभाषित" , लेकिन फिर भी 'ओ' मौजूद है। आपको इसके लिए 'window window.o' लिखना होगा। – Christoph

संबंधित मुद्दे