2015-07-27 2 views
7

तो मैं इसयदि कोई स्थिति किसी स्थिति में परिभाषित की गई है तो क्या कोई फ़ंक्शन उड़ाया जाता है?

var x = 1; 
    if (function f(){}) { 
    x += typeof f; 
    } 
    x; 

यह "1undefined" outputs की तरह कुछ है लगता है। मैंने सोचा कि इसमें आउटपुट "1 फ़ंक्शन" होना चाहिए, क्योंकि फ़ंक्शन f() {} को उपरोक्त से ऊपर रखा जाना चाहिए था। यह स्पष्ट रूप से मामला नहीं है - क्यों? मैंने सोचा कि कार्य घोषणाएं और निकायों को हमेशा दायरे के शीर्ष पर फेंक दिया गया था?

+0

वास्तव में, यह है, देखें: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function – heartyporridge

+1

मुझे लगता है कि यह एक नामांकित फ़ंक्शन अभिव्यक्ति है, फ़ंक्शन घोषणा नहीं है। नाम का दायरा केवल कार्य के शरीर को परिभाषित किया जा रहा है, आसपास के कार्य नहीं। – Barmar

+0

यह 'var foo = function f() {};' जैसा है। – Barmar

उत्तर

4

जहां तक ​​मुझे पता है कि ES5 ब्लॉक के अंदर फ़ंक्शन घोषणाओं के व्यवहार को परिभाषित नहीं करता है।

Kangax का हवाला देते हुए:

FunctionDeclarations केवल कार्यक्रम या FunctionBody में प्रदर्शित करने की अनुमति है। Syntactically, वे ब्लॉक ({...}) - जैसे कि कथन के दौरान या नहीं, में दिखाई नहीं दे सकते हैं। ऐसा इसलिए है क्योंकि ब्लॉक में केवल वक्तव्य हो सकते हैं, स्रोत स्रोत नहीं, जो फ़ंक्शनक्लेक्शनेशन है। अगर हम उत्पादन नियमों को ध्यान से देखते हैं, तो हम देख सकते हैं कि ब्लॉक के भीतर अभिव्यक्ति की अनुमति केवल एकमात्र तरीका है जब यह अभिव्यक्ति स्टेटमेंट का हिस्सा है। हालांकि, अभिव्यक्ति स्टेटमेंट को "फ़ंक्शन" कीवर्ड से शुरू करने के लिए स्पष्ट रूप से परिभाषित नहीं किया गया है, और यही कारण है कि फ़ंक्शन डिस्क्लेरेशन सीधे स्टेटमेंट या ब्लॉक के भीतर दिखाई नहीं दे सकता है (ध्यान दें कि ब्लॉक केवल विवरणों की सूची है)।

क्योंकि इन प्रतिबंधों की

, समारोह सीधे एक ब्लॉक (जैसे पिछले उदाहरण के रूप में) में दिखाई देता है जब भी यह वास्तव में एक सिंटैक्स त्रुटि माना होना चाहिए, घोषणा या अभिव्यक्ति से काम नहीं। समस्या यह है कि मैंने लगभगपर लागू किए गए कार्यान्वयन में से कोई भी कड़ाई से प्रति नियम नहीं हैं (अपवाद हैं BESEN और DMDScript)। वे इसके बजाय मालिकाना तरीकों में व्याख्या करते हैं।

+3

क्या 'ब्लॉक' वास्तव में 'if()' भाग या '{body} 'भाग को इसके बाद संदर्भित करता है? – Barmar

+0

मुझे लगभग यकीन है कि 'अगर()' स्वयं को ब्लॉक भी माना जाता है ... लेकिन 100% नहीं :( –

+0

चूंकि आप '() 'के अंदर एक चर घोषित कर सकते हैं और इसके ब्लॉक के अंदर यह केवल वैध है। .. मुझे लगता है कि यह उसी तरह काम करता है –

5

फ़ंक्शन घोषणाएं फंसे हुए हैं। फंक्शन एक्सप्रेशन are not

यह एक नामित समारोह अभिव्यक्ति बनाता है:

if(function f(){}) 

यह जांच के अलावा कुछ भी नहीं करता है, तो समारोह अभिव्यक्ति truthy है देखने के लिए। (फ़ंक्शन अभिव्यक्ति हमेशा सत्य होती है।)

नामित समारोह भाव के बारे में, https://kangax.github.io/nfe/#named-expr देखें:

एक महत्वपूर्ण विस्तार याद रखना होगा कि इस नाम में ही उपलब्ध है है एक नव-निर्धारित फ़ंक्शन

इस के दायरे कोड के बाहर नई फ़ंक्शन अभिव्यक्ति का दायरा है, और इसलिए f अपरिभाषित है:

x += typeof f; 

के भीतर एक नामित समारोह अभिव्यक्ति, आप एक समस्या के बिना इसके नाम का उल्लेख कर सकते हैं:

(function f() { 
 
    alert(typeof f); //function 
 
})(); 
 

 
alert(typeof f);  //undefined

+1

के रूप में परिभाषित किया गया है, मुझे नहीं लगता 'toString' प्रासंगिक है। कार्य ऑब्जेक्ट प्रकार हैं और [बूलियन संदर्भों में 'सत्य' में परिवर्तित हो गए हैं (http://www.ecma-international.org/ecma-262/6। 0/# सेकंड-अगर-बयान)। – 1983

+0

@KingMob, उत्कृष्ट बिंदु, अद्यतन। –

0

समारोह घोषणाओं statements हैं। if-statement का सशर्त हिस्सा एक अभिव्यक्ति है, इसलिए आपके पास एक फ़ंक्शन अभिव्यक्ति है; यह एक समारोह घोषणा नहीं हो सकता है। और इसलिए यह फहराया नहीं गया है, क्योंकि केवल घोषणाएं हैं।

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

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