2012-06-05 24 views
11

जब मेरे पास कुछ कोड है तो मुझे एक बार में इसे एक से अधिक बार निष्पादित करने की आवश्यकता है, इसलिए मुझे खुद को दोहराना नहीं है। कभी-कभी पृष्ठ लोड पर इस कोड को निष्पादित करने की आवश्यकता होती है।जावास्क्रिप्ट में एक स्व निष्पादन समारोह कैसे कॉल करें?

function foo() { 
    alert('hello'); 
} 

foo(); 

मैं नहीं बल्कि यह इस तरह से करना होगा:: अभी मैं इसे इस तरह से करना

(function foo() { 
    alert('hello'); 
})(); 

समस्या है, यह केवल पृष्ठ लोड पर निष्पादित करेगा, लेकिन का उपयोग कर इसे बाद में कई बार फोन करने के लिए करता है, तो मैं कोशिश foo() यह काम नहीं करेगा।

मुझे लगता है कि यह एक दायरा मुद्दा है, लेकिन क्या बाद में बुलाए जाने पर स्वयं निष्पादन कार्यों को काम करने का कोई तरीका है?

+1

मुझे यकीन है कि अगर यह यह करने के लिए सबसे अच्छा तरीका है नहीं कर रहा हूँ। मुझे लगता है कि यह थोड़ी देर के बाद असली गन्दा हो जाएगा। – Hassan

+3

http://stackoverflow.com/questions/6211466/call-immediately-executing-function-from-outside का संभावित डुप्लिकेट। – apsillers

+0

http://stackoverflow.com/questions/6404196/can-i-name-a-javascript-function-and-execute-it-immediately (जो बेहतर उत्तर है, IMHO है, लेकिन प्रश्न का phrasing भी संभव है) के डुप्लिकेट एक सटीक मिलान से कम है।) – apsillers

उत्तर

29

अपने कार्य की वापसी मूल्य पर निर्भर नहीं करता है, तो आप ऐसा कर सकते हैं तो ...

var foo = (function bar() { 
    alert('hello'); 
    return bar; 
})(); // hello 

foo(); // hello 

यह नामित समारोह अभिव्यक्ति में स्थानीय संदर्भ bar का उपयोग करता बाहरी foo चर करने के लिए समारोह वापस जाने के लिए ।


या यहां तक ​​कि अगर यह होता है, आप वापसी मान सशर्त बना सकता है ...

var foo = (function bar() { 
    alert('hello'); 
    return foo ? "some other value" : bar; 
})(); // hello 

alert(foo()); // hello --- some other value 

या सिर्फ मैन्युअल बजाय लौटने की चर को असाइन ...

var foo; 
(function bar() { 
    alert('hello'); 
    foo = bar; 
})(); // hello 

foo(); // hello 

जैसा कि @RobG द्वारा नोट किया गया है, आईई के कुछ संस्करण पहचानकर्ता को संलग्न चरम दायरे में रिसाव करेंगे। वह पहचानकर्ता आपके द्वारा बनाए गए फ़ंक्शन के डुप्लिकेट का संदर्भ देगा। अपने एनएफई आईई-सुरक्षित (आर) बनाने के लिए, आप उस संदर्भ को रद्द कर सकते हैं।

bar = null; 

बस जागरूक रहें कि पहचानकर्ता अभी भी एक ही नाम के साथ पहचानकर्ता को छायांकन श्रृंखला पर छाया देगा। Nullifying उस में मदद नहीं करेगा, और स्थानीय चर हटाया नहीं जा सकता है, तो बुद्धिमानी से एनएफई नाम का चयन करें।

+0

नामांकित फ़ंक्शन एक्सप्रेशन ** ** बहुत उपयोगी होना चाहिए, लेकिन वे [आईई में टूटे हुए हैं] (http://kangax.github.com/nfe/#jscript-bugs) इसलिए सबसे अधिक अनुशंसा की जाती है। जैसे उपरोक्त 'टाइपोफ बार' में "फ़ंक्शन" दिखाया गया है, भले ही * IIFE से पहले * रखा गया हो। – RobG

+0

@RobG: सच है, लेकिन यह अक्सर एक निर्दोष मुद्दा है। तथ्य यह है कि 'बार' बाहर निकलता है और यहां तक ​​कि एक डुप्लिकेट फ़ंक्शन भी बनाता है, शायद यह केवल तभी मायने रखता है जब आप उस पहचानकर्ता को उस स्कोप श्रृंखला को आगे बढ़ाने के लिए संलग्न क्षेत्र में उपयोग कर रहे हैं। –

+0

यह कोई मुद्दा नहीं है, लेकिन आम तौर पर फ़ंक्शन एक्सप्रेशन का इरादा फ़ंक्शन को "निजी" रखना है। इसे वैश्विक कार्य बनने की अनुमति देने से अनजान परिणाम हो सकते हैं, खासकर बड़ी परियोजनाओं में। – RobG

4

बाहर से कॉल करने के लिए, फ़ंक्शन को बाहर से दिखाई देना होगा। आदर्श रूप में आप स्वयं को क्रियान्वित समारोह कुछ संदर्भ में पारित में इसकी सुई (इस मामले, this, वैश्विक संदर्भ संदर्भ देता है, जिसमें) होगा:

(function(context) { 
    var foo = function() { 
    alert('hello'); 
    }; 
    foo(); 
    context.foo = foo; 
})(this); 

... 

foo(); 

अधिक दिलचस्प पैटर्न here पाया जा सकता है। काम foo बनाने के लिए करता है

(window.foo = function() { 
    alert('hello'); 
})(); 

// at some later time 
foo(); 

कोष्ठकों के पहले सेट में अभिव्यक्ति, लेकिन यह भी:

+0

अच्छा लिंक, धन्यवाद। – TK123

+1

यह ' चूंकि यह वैश्विक कोड में वैश्विक वस्तु का संदर्भ देने की गारंटी देता है, इसलिए 'विंडो' को संदर्भित करने की गारंटी नहीं है, या यहां तक ​​कि परिभाषित भी किया जा सकता है। – RobG

+0

@RobG: हाँ, यह होगा :-) मैंने अभी एक उदाहरण प्रदान किया है और मैंने स्पष्ट रूप से उल्लेख किया है कि कुछ संदर्भ_ में पारित किया गया है। यह तय करने के लिए ओपी पर निर्भर है कि कौन सा संदर्भ उसके लिए सबसे अच्छा होगा। –

2

foo() एक वैश्विक समारोह, यानी, window की संपत्ति होने का इरादा है, तो आप ऐसा कर सकते हैं फ़ंक्शन होने का मूल्यांकन करता है ताकि आप इसे अंत में () के साथ तुरंत आवेदक कर सकें।

यह पैटर्न तब भी काम करता है जब फ़ंक्शन को मान वापस लौटाया जाता है।

+0

+1 कोई कारण यह स्थानीय लोगों के साथ भी नहीं किया जा सका। 'var foo; (foo = func ...})() ' –

+0

धन्यवाद @amnotiam। बेशक आप स्थानीय लोगों के बारे में सही हैं। किसी कारण से जब मैंने यह जवाब लिखा था, तो मैं इसे एक कथन के रूप में रखने और एक अलग कथन से बचने की कोशिश कर रहा था - मुझे अब भी याद नहीं है। – nnnnnn

0

दूसरा फ़ंक्शन foo फ़ंक्शन परिभाषा अभिव्यक्ति है।

एक समारोह परिभाषा अभिव्यक्ति में, आप केवल समारोह के भीतर ही नाम के साथ समारोह कॉल कर सकते हैं करने के लिए "जावास्क्रिप्ट निश्चित गाइड" के अनुसार:

समारोह परिभाषा भाव के लिए, नाम वैकल्पिक है: यदि वर्तमान , नाम फ़ंक्शन ऑब्जेक्ट को केवल फ़ंक्शन के शरीर के भीतर ही संदर्भित करता है

इसका उपयोग रिकर्सन फ़ंक्शन परिभाषा अभिव्यक्ति में किया जा सकता है।

उदाहरण के लिए:

var f = function factorial(n) { 
    if (n == 0 || n == 1) 
     return 1; 
    else 
     return n * factorial(n-1); 
} 
संबंधित मुद्दे