मेरे जावास्क्रिप्ट फ़ंक्शन नाम क्लैशिंग क्यों हैं?


97

मैंने निम्नलिखित स्क्रिप्ट को केवल यह देखने के लिए लिखा है कि जब एक चर और एक फ़ंक्शन होता है, जो इसे सौंपा गया होता है, तो उनके नाम क्लैश होते हैं:

var f = function() {
    console.log("Me original.");
}

function f() {
    console.log("Me duplicate.");
}

f();

मुझे जो आउटपुट मिल रहा है, वह है "मुझे मूल।" दूसरे फंक्शन को क्यों नहीं बुलाया गया?

इसके अलावा, अगर मैं अपने मूल असाइनमेंट को बदल देता हूं, तो मुझे var f = new function() {"ओ ओरिजिनल" मिल जाता है, इसके बाद टाइपर्रर कहा जाता है object is not a function। क्या कोई समझा सकता है?


26
@ Dean.DePue - जावास्क्रिप्ट के हिस्से पर कोई भ्रम नहीं है। उन्हें संभालने के नियम काफी स्पष्ट हैं (और बेंजामिन ने अपने जवाब में बताया)।
क्वेंटिन

4
जिज्ञासा, अभी भी एक भाषा के बारे में जानने का सबसे अच्छा तरीका है। :-D
सेरेब्रस

2
इसके अलावा, मैं कल्पना करता हूं कि यह किसी चीज़ के लिए बेहद असंभव है क्योंकि "जावास्क्रिप्ट" के रूप में "
फीलिंग

2
दूसरे उदाहरण में ध्वजारोहण का क्रम क्यों होना चाहिए?
सेरेब्रस

5
जावास्क्रिप्ट के ज्ञान में वृद्धि के लिए कदम: 1) 'उपयोग सख्त' 2) हमेशा या तो jslint या jshint का उपयोग करें 3) उन चीजों को देखें जो jslint या jshint शिकायत करते हैं 4 के बारे में) कुल्ला और दोहराएं
स्टीव-एर-रिनो

जवाबों:


170

जावास्क्रिप्ट में फ़ंक्शन घोषणाएँ फहराई जाती हैं (शीर्ष पर ले जाया जाता है)। आदेश देने के मामले में गलत होते हुए, आपके पास जो कोड है वह शब्दार्थ रूप से समान है क्योंकि फ़ंक्शन घोषणाओं को फहराया जाता है:

function f() {
    console.log("Me duplicate.");
}
var f = function() {
    console.log("Me original.");
}


f();

जो बदले में, फ़ंक्शन के नाम के अपवाद के साथ समान है:

var f = function() {
    console.log("Me duplicate.");
}
var f = function() {
    console.log("Me original.");
}


f();

बदले में, परिवर्तनशील उत्थापन के कारण समान है:

var f;
f = function() {
    console.log("Me duplicate.");
}
f = function() {
    console.log("Me original.");
}

f();

जो बताता है कि आपको क्या मिल रहा है, आप फ़ंक्शन को ओवरराइड कर रहे हैं। अधिक सामान्यतः, कई varघोषणाओं को जावास्क्रिप्ट में अनुमति दी जाती है - var x = 3; var x = 5पूरी तरह से कानूनी है। नए ECMAScript 6 मानक में, letबयानों ने इसे मना किया है।

यह लेख @kangax द्वारा जावास्क्रिप्ट में कार्यों को ध्वस्त करने में एक शानदार काम करता है


2
क्या तुम सच में सरल बना सकते हैं function f()करने के लिए var f = function()है कि ज्यादा? क्या उत्थापन और कार्य नाम वास्तव में एकमात्र अंतर हैं?
djechlin

6
@djechlin इस प्रश्न के संदर्भ में - हाँ। आमतौर पर, यह अधिक सूक्ष्म है - देखें stackoverflow.com/questions/336859/… । संकलक दृष्टिकोण से, वे भिन्न हैं - लेकिन प्रोग्रामर के दृष्टिकोण से - हम यह दावा करने के लिए पर्याप्त रूप से करीब हैं । इसलिए मैंने उस लंबे समय को जोड़ा "जबकि पार्सिंग ऑर्डर के मामले में गलत है, आपके पास जो कोड है वह शब्दार्थ रूप से" कहने के बजाय "जैसा है"। अच्छी बात।
बेंजामिन ग्रुएनबाम

1
@dotslash कृपया अपने मूल प्रश्न को संपादित न करें और इसे बदल दें, कि यहाँ बुरा माना जाता है - साथ ही, कई प्रश्नों को एक में मिलाना भी यहाँ बुरा माना जाता है। आप इसके बजाय एक नया प्रश्न पूछ सकते हैं या, यदि आपको लगता है कि यह बहुत छोटा है, तो टिप्पणियों में स्पष्टीकरण के लिए पूछें (यही वे वैसे भी हैं)। उपरोक्त कोड में, दोनों संस्करणों को fफहराया जाता है, और "Me Original"संस्करण को बाद में फहराया जाता है , वे प्रत्येक शीर्ष पर चले जाते हैं लेकिन उसी क्रम में। मैं बस इतना जोड़ना चाहूंगा कि, आपको कई कार्यों को एक ही तरह से नाम नहीं देना चाहिए :)
बेंजामिन ग्रुएनबाम

5
सख्त मोड में आप varएक ही स्कोप में दो बार एक ही नाम नहीं रख सकते ।
हॉफमैन

4
"यह स्पष्ट होना चाहिए" - शायद आप के लिए , लेकिन यह मेरे लिए एक बिंदु पर स्पष्ट नहीं था, और यह ओपी के लिए स्पष्ट नहीं था जब उसने यह पूछा, और नामकरण, और अधिक सामान्यतः कैसे लेक्सिकल वातावरण को प्रबंधित किया जाता है जावास्क्रिप्ट में एक था जब सबसे पहले मुझे जावास्क्रिप्ट सीखना है तो सबसे मुश्किल चीजों को समझना। जो लोग इसे नहीं समझते, उनका अपमान करना मुझे इतनी जल्दी नहीं होगी।
बेंजामिन ग्रुएनबाम

10

यदि ऐसा नहीं लगता है कि किसी ने आपके अनुवर्ती प्रश्न का उत्तर दिया है, तो मैं इसका उत्तर यहां दूंगा, हालांकि आपको आमतौर पर अनुवर्ती प्रश्नों को अलग-अलग प्रश्नों के रूप में पूछना चाहिए।

आपने पूछा कि यह क्यों:

var f = new function() {
    console.log("Me original.");
}

function f() {
    console.log("Me duplicate.");
}

f();

प्रिंट करता है "मुझे मूल।" और फिर एक त्रुटि।

यहाँ क्या हो रहा है कि newफ़ंक्शन का उपयोग एक कंस्ट्रक्टर के रूप में किया जाता है। तो यह निम्नलिखित के बराबर है:

function myConstructor() {
    console.log("Me original.");
}
var f = new myConstructor();

function f() {
    console.log("Me duplicate.");
}

f();

और उस समारोह के लिए धन्यवाद, जिसे बेंजामिन ने समझाया, उपरोक्त अनिवार्य रूप से इसके बराबर है:

var myConstructor = function() {
    console.log("Me original.");
};
var f = function() {
    console.log("Me duplicate.");
};

f = new myConstructor();

f();

यह अभिव्यक्ति:

var f = new function() {
    console.log("Me original.");
}

निर्माणकर्ता के fरूप में एक अनाम फ़ंक्शन का उपयोग करके एक नई वस्तु का निर्माण और उसे सौंपा जा सकता है । "मुझे मूल।" कंस्ट्रक्टर निष्पादित होने पर इसका प्रिंट आउट निकाल लिया जाता है। लेकिन जिस वस्तु का निर्माण किया जाता है वह स्वयं एक फ़ंक्शन नहीं है, इसलिए जब यह अंततः निष्पादित होता है:

f();

आपको कोई त्रुटि मिलती है, क्योंकि fकोई फ़ंक्शन नहीं है।


ओह अद्भुत! इसका जवाब देने के लिए परेशानी उठाने के लिए बहुत बहुत धन्यवाद! :) :)
akush981

2

मुझे माफ कर दो अगर यह एक बिंदु को जोड़ने के लिए गलत तरीका है। मैं यहाँ बहुत नहीं रहा, और रचनात्मक दिशा और / या आलोचना का स्वागत करूँगा।

बेंजामिन का जवाब ओपी के सवाल को बहुत ही शानदार तरीके से संबोधित करता है, लेकिन मैं एक ऐसा ट्विस्ट जोड़ना चाहूंगा जो हमें फहराने और उसकी विषमताओं का पूरा दौरा देगा।

यदि हम कॉल के साथ मूल कोड शुरू करते हैं f, जैसे:

f();

var f = function() {
   console.log("Me original.");
};

function f() {
   console.log("Me duplicate.");
}

f();

आउटपुट तब होगा:

Me duplicate.
Me original.

कारण यह है कि var और functionबयानों को थोड़े अलग तरीके से फहराया जाता है।

के लिए घोषणा वर्तमान क्षेत्र * के शीर्ष, लेकिन किसी भी करने के लिए ले जाया जाता है कामvar फहराया नहीं है। जहां तक ​​घोषित संस्करण का मूल्य है, यह तब तक अपरिभाषित है जब तक कि मूल असाइनमेंट लाइन नहीं पहुंच जाती।

के लिए functionबयान , दोनों घोषणा और परिभाषा फहराया जाता है। फंक्शन एक्सप्रेशंस , जैसा कि इसमें इस्तेमाल किया गया हैvar f = function() {... निर्माण , फहराया नहीं जाता है।

तो फहराने के बाद, निष्पादन इस तरह है जैसे कि कोड थे:

var f; // declares var f, but does not assign it.

// name and define function f, shadowing the variable
function f() { 
  console.log("Me duplicate.");
}

// call the currently defined function f
f(); 

// assigns the result of a function expression to the var f,
// which shadows the hoisted function definition once past this point lexically
f = function() { 
  console.log("Me original."); 
}

// calls the function referenced by the var f
f();

* सभी जावास्क्रिप्ट स्कोप लेक्सिकल, या फंक्शन, स्कोप है, लेकिन ऐसा लगता था कि यह उस समय f शब्द का उपयोग करने के लिए चीजों को भ्रमित करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.